Below you can see my code that implements a pretty basic UDP sender in C++ with Winsock. The thing is that no matter how many times I run the code, the socket (the listenSocket) gets bound to a different UDP port. Is there any specific reason for this? Am I doing some mistake in my code?
thanks
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
using namespace std;
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKADDR_IN myAddress;
SOCKADDR_IN targetAddress;
int myPort = 60888;
const char *myIP = "192.168.0.1";
int remotePort = 2048;
const char *remoteIP = "192.168.0.2";
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET SendSocket = INVALID_SOCKET;
SOCKET acceptSocket;
char cBuffer[1024] = "Test Buffer";
int nBytesSent = 0;
int nBufSize = strlen(cBuffer);
int iResult;
// Initialize Winsock
if( WSAStartup( MAKEWORD(2, 2), &wsaData ) != NO_ERROR )
{
cerr<<"Socket Initialization: Error with WSAStartup\n";
system("pause");
WSACleanup();
exit(10);
}
ListenSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ListenSocket == INVALID_SOCKET or SendSocket == INVALID_SOCKET)
{
cerr<<"Socket Initialization: Error creating socket"<<endl;
system("pause");
WSACleanup();
exit(11);
}
//bind
myAddress.sin_family = AF_INET;
myAddress.sin_addr.s_addr = inet_addr(myIP);
myAddress.sin_port = htons(myPort);
targetAddress.sin_family = AF_INET;
targetAddress.sin_addr.s_addr = inet_addr(remoteIP);
targetAddress.sin_port = htons(remotePort);
if(bind(ListenSocket, (SOCKADDR*) &myAddress, sizeof(myAddress)) == SOCKET_ERROR)
{
cerr<<"ServerSocket: Failed to connect\n";
system("pause");
WSACleanup();
exit(14);
}
else
printf("Server: bind() is OK.\n");
nBytesSent = sendto(SendSocket, cBuffer, nBufSize, 0,
(SOCKADDR *) &targetAddress,
sizeof(SOCKADDR_IN));
printf("Everything is ok\n");
system("PAUSE");
closesocket(ListenSocket);
closesocket(SendSocket);
return EXIT_SUCCESS;
}
EDIT: Maybe I was not so clear. What I do with this code is to send some data to a remote PC. But what is required is that the UDP segments should appear to be originated from a specific port. How can this be done? Is it wrong what I'm doing here? Now that I'm thinking of it, I guess it is wrong indeed. The SendSocket and ListenSocket don't have any connection, correct? So, how can I make it that the UDP segments appear to originate from a specific UDP port? Thanks!
You are not calling bind() on SendSocket before sending data with it, so WinSock is free to bind that socket to whatever random local IP/Port it needs to. If you have to send data with a specific source IP/Port every time, you have to bind() to that IP/Port first. If that local IP/Port is the same pair you are binding ListenSocket to, then you don't need to use two separate sockets to begin with. You can send data with the same socket that is listening for incoming data.
Related
Code:
//server.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <WinSock2.h>
#include <Windows.h>
#define SCK_VERSION 0x0202
int main()
{
//declare sockets first
SOCKET ConSock; // used for connection, hence the name
SOCKET ListenSock; // used for listening from the server
SOCKADDR_IN address; //socket address
int addrsize = sizeof(address);
long ok;
char MESSAGE[200];
char reply[200];
WSADATA WSD;
WORD DllVersion;
DllVersion = MAKEWORD(2,1);
ok = WSAStartup(DllVersion, &WSD);
//start creating our sockets
ConSock = socket(AF_INET, SOCK_STREAM, NULL);
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_family = AF_INET;
address.sin_port = htons(10103);
ListenSock = socket(AF_INET, SOCK_STREAM, NULL);
bind(ListenSock, (SOCKADDR*)&address, sizeof(address));
listen(ListenSock, SOMAXCONN);
printf("Server waiting for connections\n\n");
for(;;){
if (ConSock = accept(ListenSock, (SOCKADDR*)&address, &addrsize))
{
ok = recv(ConSock, MESSAGE, sizeof(MESSAGE),NULL);
printf("\nClient says:\t %s", MESSAGE);
printf("\nEnter reply:\t");
gets(reply);
ok = send(ConSock,reply,200,NULL);
}
}
}
//client.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <WinSock2.h>
#include <Windows.h>
#define SCK_VERSION 0x0202
int main()
{
SOCKET sock;
SOCKADDR_IN address;
long ok;
char MESSAGE[200];
char reply[200];
WSADATA WSD;
WORD DllVersion;
DllVersion = MAKEWORD(2,1);
ok = WSAStartup(DllVersion, &WSD);
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_family = AF_INET;
address.sin_port = htons(10103);
for(;;)
{
sock = socket(AF_INET,SOCK_STREAM,NULL);
connect(sock, (SOCKADDR*)&address, sizeof(address));
printf("\nEnter Message:\t");
gets(MESSAGE);
ok = send(sock,MESSAGE,200,NULL);
ok = recv(sock,reply,sizeof(reply),NULL);
printf("\nServer says:\t %s",reply);
}
}
//makefile
server:
g++ server.c -o server
client:
g++ client.c -o client
clean:
rm server
rm client
all: server client
This runs with -lwsock32 and it does a good job, but I need to adjust it now to comunicate some data from a file, the data is mostly values of voltages, currents, active reactive power, etc.
I have been trying for quite some time and I cannot seem to adjust it.
If you can rewrite it in terms of the client communicating the values(that are stored in a file) to the server, that will be great. Any help is greatly appreciated, as I am not being succesful currently.
I have a client/server LWIP program, I want to use multicast features so I used IGMP library did the following setting like this:
Setting .IOC
Enable LWIP_IGMP
Enable LWIP_MULTICAST_TX_OPTION
Enable LWIP_IP4
in ethernet.c
netif->flags |= NETIF_FLAG_IGMP
in stm32f7xx_hal_eth.c (ETH_MACDMAConfig)
macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_ENABLE;
macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_NONE;
and i implemented code like this :
void UDP_Multicast_init(void *arg)
{
struct ip4_addr ipgroup, localIP;
struct udp_pcb *upcb;
char msg[] = "hello";
struct pbuf* p;
p = pbuf_alloc(PBUF_TRANSPORT,sizeof(msg),PBUF_RAM);
memcpy (p->payload, msg, sizeof(msg));
IP4_ADDR(&ipgroup, 224, 224, 0, 1); //Multicast IP address.
IP4_ADDR(&localIP, 192, 168, 1, 99); //Interface IP address
#if LWIP_IGMP
igmp_joingroup((ip4_addr_t *)(&localIP),(ip4_addr_t *)(&ipgroup));
#endif
upcb = ( struct udp_pcb*) udp_new();
MulticastStart(); //binding connection to the port 10
udp_recv(upcb, UDP_callback, NULL);
udp_sendto(upcb,p,&ipgroup,10);
}
void UDP_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port)
{
printf("test");
}
and I try to see in wireshark, iplocal successfully joins into the multicast address, and sends a data to the multicast address.
enter image description here
but the callback function cannot be executed.
is there something missing??
thanks for the response.
I'm trying to make a simple mesh connection using 6LoWPAN with Contiki.
For simplicity I'm making this in Cooja, so the hardware is not a constrain in this problem i think.
My objective is to have one root (UDP Server) and many motes (UDP Client). With the examples provided by Contiki, I'm able to do start the communication with the Motes and talk to the Server, but is it possible to do it the other way around?
I want the Root to start send the message to any client, and if it's neccesary, to hop the message via another clients in the network.
Do you have any idea if this is possible to do? Or any track for achieve this?
Update: What I've tried so far:
What i've tried so far, in the server device, create two process, one for initiating the root, and the other one for sendig the packet periodically:
#include "contiki.h"
#include <stdlib.h>
#include "net/routing/routing.h"
#include "random.h"
#include "net/netstack.h"
#include "net/ipv6/simple-udp.h"
#include "sys/log.h"
#define LOG_MODULE "App"
#define LOG_LEVEL LOG_LEVEL_DBG
#define UDP_CLIENT_PORT 8765
#define UDP_SERVER_PORT 5678
#define SEND_INTERVAL (5 * CLOCK_SECOND)
static struct simple_udp_connection udp_conn;
static struct etimer periodic_timer;
PROCESS(udp_server_process, "UDP server");
PROCESS(send_msg_process, "UDP server");
AUTOSTART_PROCESSES(&udp_server_process, &send_msg_process);
static void
udp_rx_callback(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
LOG_INFO("Received response '%.*s' from ", datalen, (char *) data);
LOG_INFO_6ADDR(sender_addr);
LOG_INFO_("\n");
}
PROCESS_THREAD(udp_server_process, ev, data)
{
PROCESS_BEGIN();
/* Initialize DAG root */
NETSTACK_ROUTING.root_start();
/* Initialize UDP connection */
simple_udp_register(&udp_conn, UDP_SERVER_PORT, NULL,
UDP_CLIENT_PORT, udp_rx_callback);
PROCESS_END();
}
PROCESS_THREAD(send_msg_process, ev, data)
{
static unsigned count;
static char str[32];
uip_ipaddr_t dest_ipaddr;
LOG_INFO("%u", count);
PROCESS_BEGIN();
while(1) {
etimer_set(&periodic_timer, CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
uip_ip6addr(&dest_ipaddr,0xfe80,0,0,0,0x207,0x7,0x7,0x7);
LOG_INFO("Sending request %u to ", count);
LOG_INFO_6ADDR(&dest_ipaddr);
LOG_INFO_("\n");
snprintf(str, sizeof(str), "hello %d", count);
simple_udp_sendto(&udp_conn, str, strlen(str), &dest_ipaddr);
count++;
}
PROCESS_END();
}
In the cliend side, the code is based simply on listening to the UDP socket, and make a response in the case that it receives a packet.
#include "contiki.h"
#include "net/routing/routing.h"
#include "random.h"
#include "net/netstack.h"
#include "net/ipv6/simple-udp.h"
#include "sys/log.h"
#define LOG_MODULE "App"
#define LOG_LEVEL LOG_LEVEL_DBG
#define WITH_SERVER_REPLY 1
#define UDP_CLIENT_PORT 8765
#define UDP_SERVER_PORT 5678
#define SEND_INTERVAL (5 * CLOCK_SECOND)
static struct simple_udp_connection udp_conn;
/*---------------------------------------------------------------------------*/
PROCESS(udp_client_process, "UDP client");
AUTOSTART_PROCESSES(&udp_client_process);
/*---------------------------------------------------------------------------*/
static void
udp_rx_callback(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
LOG_INFO("Received request '%.*s' from ", datalen, (char *) data);
LOG_INFO_6ADDR(sender_addr);
LOG_INFO("Sending response.\n");
simple_udp_sendto(&udp_conn, data, datalen, sender_addr);
LOG_INFO_("\n");
}
PROCESS_THREAD(udp_client_process, ev, data)
{
PROCESS_BEGIN();
simple_udp_register(&udp_conn, UDP_CLIENT_PORT, NULL,
UDP_SERVER_PORT, udp_rx_callback);
PROCESS_END();
}
As you can see, the code for the server sends periodically a packet to the ipv6 direction: 0xfe80:0:0:0:0x207:0x7:0x7:0x7, which is the ip that will be assigned to a mote in cooja when it is the number 7 in the simulation.
The results I've obtained is that, when the root (A) and the client (B) are in direct connection, they talk to each other perfectly, but when I separate them and try to make the connection from the root (A) to the client (B) via another client (C), the message won't get from A to B.
Yes, it is possible. The RPL routing protocol allows to send packets in both directions from and to the root. Simply use the node's IP address as the destination.
One issue is that a node typically has two IPv6 addresses:
Addresses starting with 0xfe80 are link local.
Addresses starting with the network prefix - defined in the OS config as UIP_DS6_DEFAULT_PREFIX, equal to 0xfd00 by default. This address is only present after the node has joined the RPL network.
Packets to link-local addresses must be single-hop, they are not forwarded by nodes. In order to utilize the multi-hop mesh forwarding properly, use the other address as the destination.
I am kinda new to the lwip stack. I'm trying to send some data over UDP protocol from my development board to my pc. And using ethernet cable between the two of them.
I gave an ip address to my server(source-board), which is 192.168.1.75:88. And the ip address of my computer is 192.168.1.2:90. When I set this configuration and run the program, I can sniff nothing with wireshark, I mean there is no udp package exchange at all. But when I change all destination adress to 255.255.255.255 or 0.0.0.0, I can sniff some packages.
Why can't I send udp packages to the ip address that I want?
Main.c
int main(void)
{
#define dst_port 88
#define src_port 90
#ifdef SERIAL_DEBUG
DebugComPort_Init();
#endif
LCD_LED_Init();
ETH_BSP_Config();
LwIP_Init();
IP4_ADDR(&dstaddr, 0, 0, 0, 0);
IP4_ADDR(&srcaddr, 192, 168, 1, 75);
pcb = udp_new();
udp_bind(pcb, &dstaddr, src_port);
udp_recv(pcb, RecvUTPCallBack, NULL);
udp_connect(pcb, &dstaddr, dst_port);
#ifdef USE_DHCP
/* Start DHCPClient */
xTaskCreate(LwIP_DHCP_task, "DHCPClient", configMINIMAL_STACK_SIZE * 2, NULL,DHCP_TASK_PRIO, NULL);
#endif
/* Start toogleLed4 task : Toggle LED4 every 250ms */
xTaskCreate(ToggleLed4, "LED4", configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL);
xTaskCreate(SendUDP, "UDP", configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL);
/* Start scheduler */
vTaskStartScheduler();
for( ;; );
}
SendUDP Task
void SendUDP(void * pvParameters)
{
while(1)
{
pcb = udp_new();
udp_bind(pcb, &dstaddr, src_port);
udp_recv(pcb, RecvUTPCallBack, NULL);
udp_connect(pcb, &dstaddr, dst_port);
pb = pbuf_alloc(PBUF_TRANSPORT, sizeof((str)), PBUF_REF);
pb->payload = str;
pb->len = pb->tot_len = sizeof((str));
udp_sendto(pcb, pb, &dstaddr, dst_port);
udp_disconnect(pcb);
udp_remove(pcb);
pbuf_free(pb);
vTaskDelay(1000);
}
}
I figured this out about a week ago, but I couldn't post the answer to here.
First of all, there is an ip defining in main.h, like
/*Static IP ADDRESS*/
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 15
and this configurations being use in netconf.h
IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
that's why server's ip adress is always 192.168.1.15.
And the second, I just started to use netconn API instead of raw API, this is way much easier than raw API. And this is my new SendwithUDP function, which is working perfect.
void SendwithUDP(uint16_t *veri, uint8_t length)
{
while(1)
{
if(((EventFlags.udp) && (1<<0)) == (1<<0))
{
STM_EVAL_LEDToggle(LED3);
sendconn = netconn_new( NETCONN_UDP );
netconn_bind(sendconn, IP_ADDR_ANY, src_port );
netconn_connect(sendconn, &clientAddr, 150);
sendbuf = netbuf_new();
data =netbuf_alloc(sendbuf, 2*length);
memcpy(data, veri, 2*length);
netconn_send(sendconn, sendbuf);
netbuf_free(sendbuf);
netbuf_delete(sendbuf);
netconn_disconnect(sendconn);
netconn_delete(sendconn);
vTaskDelay(10);
}
}
}
It seems, I found a bug in Windows...
Ok, let not be such pathetic one. I'm trying to do generic sendto() operation for UDP and occasionaly found that WinXP (32 bit, SP3, checked on real and virtual machines) returns "-1" bytes sent with WSAGetLastError() as error 10014 (aka WSAEFAULT). Occurs only on IPv4 addresses (same code with IPv6 destination works perfectly). Major condition to reproduce is usage of "const struct sockaddr_in" declared at global scope. Here is the plain C code for VS2010 (also I've tried with Eclipse+MinGW, got same results):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <winsock2.h>
#include <stdint.h>
#pragma comment(lib, "Ws2_32.lib")
#define INADDR_UPNP_V4 0xEFFFFFFA
#define htons(x) ((((uint16_t)(x) & 0xFF00) >> 8) | (((uint16_t)(x) & 0x00FF) << 8))
#define htonl(x) ((((uint32_t)(x) & 0xFF000000) >> 24) | (((uint32_t)(x) & 0x00FF0000) >> 8) | (((uint32_t)(x) & 0x0000FF00) << 8) | (((uint32_t)(x) & 0x000000FF) << 24))
// Magic "const" qualifier, causes run-time error
const struct sockaddr_in addr_global = {
AF_INET,
htons(1900),
{
htonl(INADDR_UPNP_V4)
},
{0},
};
int main(int argc, char** argv)
{
#define CR_LF "\r\n"
// these two lines to un-buffer console window output at Win32, see URL below for details
// http://wiki.eclipse.org/CDT/User/FAQ#Eclipse_console_does_not_show_output_on_Windows
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
printf("Started\n");
const struct sockaddr_in addr_local = {
AF_INET,
htons(1900),
{
htonl(INADDR_UPNP_V4)
},
{0},
};
const char *MSEARCH_REQUEST_V4 = "M-SEARCH * HTTP/1.1"CR_LF
"Host:239.255.255.250:1900"CR_LF
"MAN:\"ssdp:discover\""CR_LF
"ST:ssdp:all"CR_LF
"MX:3"CR_LF
CR_LF;
const int MSEARCH_LEN = strlen(MSEARCH_REQUEST_V4);
WSADATA wsaData;
int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
int af = AF_INET;
int sock_id = socket(af, SOCK_DGRAM, IPPROTO_UDP);
if (-1 == sock_id) {
printf("%s: socket() failed with error %i/%i\n", __FUNCTION__,
errno, WSAGetLastError());
return 1;
}
int data_sent = 0;
printf("1st sendto()\n");
data_sent = sendto(sock_id, MSEARCH_REQUEST_V4,
MSEARCH_LEN, 0,
(const struct sockaddr * const)&addr_local,
sizeof(struct sockaddr_in));
if (data_sent < 0) {
printf("%s: sendto(local) failed with error %i/%i\n", __FUNCTION__,
errno, WSAGetLastError());
}
printf("2nd sendto(), will fail on WinXP SP3 (32 bit)\n");
data_sent = sendto(sock_id, MSEARCH_REQUEST_V4,
MSEARCH_LEN, 0,
(const struct sockaddr * const)&addr_global,
sizeof(struct sockaddr_in));
if (data_sent < 0) {
printf("%s: sendto(global) failed with error %i/%i\n", __FUNCTION__,
errno, WSAGetLastError());
}
closesocket(sock_id);
res = WSACleanup();
printf("Finished\n");
return 0;
}
So, if you run this code at Win7, for example, it will be absolutely OK. But WinXP fails on addr_global usage if it equipped with "const" qualifier (see "Magic" comment above). Also, "Output" window says:
First-chance exception at 0x71a912f4 in SendtoBugXP.exe: 0xC0000005:
Access violation writing location 0x00415744.
With help of "Autos" window, it's easy to figure out that 0x00415744 location is address of addr_global.sin_zero field. It seems, WinXP to write zeros there and violates memory access flags. Or this is just silly me, trying to go wrong door?
Appreciate your comments a lot. Thanks in advance.
Yeah you found a bug. sendto() has that argument declared const, but wrote to it anyway. Good luck getting it fixed though. Hint: it might be in your antivirus or firewall.
To summarize results from other forums: yes, this is Windows bug, existing up to WinXP in "desktop" and Win2003 at "server" segments.
WinSock code does attempt to force-fill "sin_zero" field with zeros. And "const" global scope causes memory access violation. Stack trace is about like that:
Thread [1] 0 (Suspended : Signal : SIGSEGV:Segmentation fault)
WSHTCPIP!WSHGetSockaddrType() at 0x71a912f4
0x71a52f9f
WSAConnect() at 0x71ab2fd7
main() at tests_main.c:77 0x401584
The same behavior observed on bind() by other people.