Sending Ethernet (UDP) Frames to other PCs - c++

I am trying to send UDP frames from my laptop to another PC as a client-server application using C++. I am monitoring the ethernet port using WireShark and I do not see any information being sent from my laptop. Can someone help regarding this? Am I missing an important step?
/*
Simple udp client
*/
#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define SERVER "10.222.14.229"
#define BUFLEN 512
#define PORT 8888
int main(void)
{
struct sockaddr_in si_other;
int s, slen = sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN];
char message1[] = "Hello";
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
printf("socket() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
while (1)
{
if (sendto(s, message1, strlen(message1), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
memset(buf, '\0', BUFLEN);
puts(buf);
}
closesocket(s);
WSACleanup();
return 0;
}

There's nothing wrong with that code - it runs fine here (apart from the busy loop). Either:
the packets aren't going out on the wire, perhaps because there is no route to 10.222.14.229 (try pinging it), or
WireShark isn't functioning properly (can it see other traffic from your laptop? - it might have a filter set or something)
If you suspect WireShark, you could always try Microsoft Network Monitor.

The solution to this thread:
WireShark was missing the Pincap library when it was installed on Windows 10.
Installing the Pincap library solved the problem.

Related

Waiting on sockets using the function WaitForMultipleObjects (msdn)

I am trying to implement a unit test to see if using the function "WaitForMultipleObjects" works properly with socket. To do so I implemented a simple UDP server-client protocol. The server bind his socket and wait to receive data from receiver using the function "WaitForMultipleObjects". Once the server receives data from the client, it displays it then waits 5 seconds. The problem here that if the client try to send 2 messages during this five seconds, the first one is displayed while the second one will block the function "WaitForMultipleObjects" forever. I know that I can use the "Select" function to do that since the socket is the only object I am waiting for, but it's just a unit test. In my real project I need to wait on a socket and another object's type which is a windows event (which is of type HANDLE) at the same time. And that's why i am trying to use "WaitForMultipleObjects" on sockets.
Here's the server code:
/*
Simple UDP Server
*/
#include<winsock2.h>
#include<windows.h>
#include <ws2tcpip.h>
#include<stdio.h>
#include<iostream>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define BUFLEN 512 //Max length of buffer
#define PORT 8888 //The port on which to listen for incoming data
int main()
{
SOCKET s;
struct sockaddr_in server, si_other;
int slen , recv_len;
char buf[BUFLEN];
WSADATA wsa;
HANDLE SEvent;
slen = sizeof(si_other) ;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( PORT );
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
SEvent = WSACreateEvent();
WSAEventSelect( s, SEvent, FD_READ);
//keep listening for data
while(1)
{
printf("Waiting for data...");
fflush(stdout);
//clear the buffer by filling null, it might have previously received data
memset(buf,'\0', BUFLEN);
INT r = WaitForMultipleObjectsEx(1,&SEvent,FALSE,INFINITE,TRUE);
if( r == WAIT_OBJECT_0)
{
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//print details of the client/peer and the data received
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
printf("Data: %s\n" , buf);
//now reply the client with the same data
if (sendto(s, buf, recv_len, 0, (struct sockaddr*) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
ResetEvent(SEvent);
Sleep(5000);
}
else
{
std::cerr<<"WaitForMultipleObject() Error ( "<<GetLastError()<<" )"<<std::endl;
exit(0);
}
}
closesocket(s);
WSACleanup();
return 0;
}
Here's the client code:
/*
Simple udp client
*/
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define SERVER "127.0.0.1" //ip address of udp server
#define BUFLEN 512 //Max length of buffer
#define PORT 8888 //The port on which to listen for incoming data
int main(void)
{
struct sockaddr_in si_other;
int s, slen=sizeof(si_other);
char buf[BUFLEN];
char message[BUFLEN];
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
printf("socket() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//setup address structure
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
//start communication
while(1)
{
printf("Enter message : ");
gets(message);
//send the message
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
//receive a reply and print it
//clear the buffer by filling null, it might have previously received data
/*memset(buf,'\0', BUFLEN);
//try to receive some data, this is a blocking call
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts(buf);*/
}
closesocket(s);
WSACleanup();
return 0;
}
Note: I didn't write all the code. I used a code that was already written (from the internet) but made some changes.
Does anyone know how to fix this problem? (using "WaitForMultipleObjects" on socket properly)
The problem here that if the client try to send 2 messages during this five seconds, the first one is displayed while the second one will clock the function "WaitForMultipleObjects" forever.
Your server code has a race condition.
Your should call WSAResetEvent/ResetEvent before calling recvfrom, not afterwards. Otherwise, there is a possiblity that new data will arrive between the call to recvfrom and WSAResetEvent, setting the event object to signalled. In that case, WSAResetEvent will set the event back to non-signalled, causing you to lose the notification of new data being available.
Also, according to the documentation of WSAEventSelect, after reading data from a socket, if more data is available to be read, the event will automatically be set to signalled again, in order to indicate that more data is available. If you call WSAResetEvent afterwards, then you will set the event back to non-signalled, causing you to lose the notification of new data being available. This is probably the reason for the behavior you describe in the question.
You should rather call WSAResetEvent/ResetEvent immediately after WSAWaitForMultipleEvents/WaitForMultipleObjectsEx. See the documentation for the function WSAWaitForMultipleEvents for a code example (that example uses overlapped I/O instead of WSAEventSelect, though).

C++ Winsock2 Client not connecting to server through remote IP

I'm trying to learn the basics of network programming by using Winsock2 API. I've had success connecting through LAN IP addresses, but I've been struggling for over a day now trying to get the client to connect to my server through its public IP.
I have already set up port forwarding on my router and have even used Wireshark to watch for client connection requests. I'm seeing the requests in Wireshark, but it never connects to the server and eventually, I get a timeout error.
I'm at a loss, I appreciate anyone who can point me in the right direction!
This is the client implementation:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_PORT //MY PORT
#define DEFAULT_BUFLEN 512
#define SERVER_IPV4 //"MY PUBLIC IP STRING"
int main(int argc, char **argv)
{
//wsaData to hold Winsock dll information
WSADATA wsaData;
WORD wVersionRequired = MAKEWORD(2, 2);
//Attempts to load winsock dll matching required version and fills WSADATA object
int wsaInit = WSAStartup(wVersionRequired, &wsaData);
if(wsaInit != 0)
{
printf("WSAStartup failed with error code: %d\n", wsaInit);
}
//If dll fails to load correct version free winsock dll resources
if(wsaData.wHighVersion != wVersionRequired)
{
printf("No usable version of Winsock.dll found\n");
WSACleanup();
return 1;
}
else
{
printf("Winsock dll 2.2 loaded correctly\n");
}
/**********************Socket Code Here**********************/
SOCKADDR_IN SockAddrIP4;
SockAddrIP4.sin_family = AF_INET;
SockAddrIP4.sin_addr.s_addr = inet_addr(SERVER_IPV4);
SockAddrIP4.sin_port = htons(DEFAULT_PORT);
/**************Create Socket****************/
//INVALID_SOCKET used like NULL
SOCKET ConnectSocket = INVALID_SOCKET;
// TODO(baruch): Only supporting IP_V4
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ConnectSocket == INVALID_SOCKET)
{
printf("socket() error: %ld\n", WSAGetLastError());
//clean up address info after getaddrinfo function when socket fails
WSACleanup();
return 1;
}
/*****************Connect to socket**************/
int connectResult = connect(ConnectSocket, (SOCKADDR*)&SockAddrIP4, sizeof(SOCKADDR_IN));
if(connectResult == SOCKET_ERROR)
{
printf("Connect failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
else
{
printf("Connected with server: %s\n", SERVER_IPV4);
}
if(ConnectSocket == INVALID_SOCKET)
{
printf("Unable to connect with server\n");
WSACleanup();
return 1;
}
/*************END of Socket CODE CLEANUP********/
// TODO(baruch): close socket
WSACleanup();
}
And this is the server:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
// TODO(baruch): Only supporting ascii consider Unicode later
#undef UNICODE
#define DEFAULT_PORT //My Port
#define DEFAULT_BUFLEN 512
int main(int argc, char **argv)
{
//wsaData to hold Winsock dll information
WSADATA wsaData;
WORD wVersionRequired = MAKEWORD(2, 2);
int wsaInit = WSAStartup(wVersionRequired, &wsaData);
if(wsaInit != 0)
{
printf("WSAStartup failed with error code: %d\n", wsaInit);
}
//If dll fails to load correct version free winsock dll resources
if(wsaData.wHighVersion != wVersionRequired)
{
printf("No usable version of Winsock.dll found\n");
WSACleanup();
return 1;
}
else
{
printf("Winsock dll 2.2 loaded correctly\n");
}
/**********************Socket Code Here**********************/
/**************Create Socket****************/
SOCKADDR_IN SockAddrIP4;
SockAddrIP4.sin_family = AF_INET;
SockAddrIP4.sin_addr.s_addr = INADDR_ANY;
SockAddrIP4.sin_port = htons(DEFAULT_PORT);
//INVALID_SOCKET used like NULL
SOCKET ListenSocket = INVALID_SOCKET;
// TODO(baruch): Only supporting IP_V4
// Socket for server to listen on for client connections
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ListenSocket == INVALID_SOCKET)
{
printf("socket() error: %ld\n", WSAGetLastError());
//clean up address info after getaddrinfo function when socket fails
WSACleanup();
return 1;
}
/**************Bind Socket******************/
int bindResult = bind(ListenSocket, (SOCKADDR*)&SockAddrIP4, sizeof(SOCKADDR_IN));
if(bindResult == SOCKET_ERROR)
{
printf("failed to bind with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
/************Listen for Connections**********/
int listenResult = listen(ListenSocket, SOMAXCONN);
if(listenResult == SOCKET_ERROR)
{
printf("Listen failed, error: %d\n", WSAGetLastError() );
WSACleanup();
return 1;
}
else
{
printf("Now listening for client connections...\n");
}
/************Accept and Handle CLient Connections***********/
// TODO(baruch): For testing, only allowing a single client. Eventually need to create a loop to handle all client connections.
SOCKET ClientSocket;
SOCKADDR_IN connectedAddress;
int addressLength = sizeof(connectedAddress);
ClientSocket = accept(ListenSocket, (SOCKADDR *) &connectedAddress, &addressLength);
if(ClientSocket == SOCKET_ERROR)
{
printf("Accept failed, error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
{
//inet_ntoa converts ip address to binary format.
char *clientIp = inet_ntoa(connectedAddress.sin_addr);
// TODO(baruch): Make sure this string correctly prints address
printf("Client connection from: %s accepted\n", clientIp);
}
/**********Handle inbound and outbound data**********/
char inBuf[DEFAULT_BUFLEN];
int dataBufLen = DEFAULT_BUFLEN;
int inDataResult, outDataResult;
do
{
inDataResult = recv(ClientSocket, inBuf, dataBufLen, 0);
if(inDataResult > 0)
{
printf("Number of bytes received: %d", inDataResult);
//Confirm to client message received
char confirmReceipt[] = "\nMessage received!\n";
outDataResult =
send(ClientSocket, confirmReceipt, sizeof(confirmReceipt), 0);
if(outDataResult == SOCKET_ERROR)
{
printf("Confirmation message failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
else
{
printf("Confirmation message sent\n");
}
}
else if(inDataResult == 0)
{
printf("Connection closing\n");
}
else
{
printf("Data receipt failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
} while(inDataResult > 0);
//Shutdown sending portion of socket, can still receive data
int shutDownResult = shutdown(ClientSocket, SD_SEND);
if(shutDownResult == SOCKET_ERROR)
{
printf("Shutdown failure, error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
/*************End Socket Code Clean up Winsock dll**********/
closesocket(ClientSocket);
WSACleanup();
}
If you can connect via the local LAN IP Address, but not via the public IP address, it's likely one of these issues.
Did you enable your program to pass through the Windows Firewall? Completely turn off the Windows Firewall (temporarily) just to make sure.
If both your client and server are behind the same NAT, your NAT may not allow for client connections to connect via the public IP address. This is called NAT hairpinning. Not all NATs support this. Validate that you can connect to your server's IP address via a client outside the network of your server.
When in doubt, use a simple program like netcat to test socket connectivity between PCs. Easy test is to just run nc in listen mode on your port and then to use another instance of nc to connect to it. Do an Internet search for "Netcat for Windows". If you can connect to your port via netcat, but not through your client/server code, then the issue with with your code. If you can't connect to your port via netcat, then it's a firewall or network configuration error.
Thanks to Selbie I was able to go through a process of elimination and determine there is something wrong with my service. I contacted my ISP, and they had to change the service type and give me a real public IP. By default, they use carrier-grade NAT which means that residential sites are assigned a private IP that is translated to a public IP by a "middlebox network address translator" somewhere in the ISP's network.
Thank you!

Trying to receive incoming UDP packets, empty buffer

I'm trying to read these incoming UDP packets using Wireshark:
I'm using the next code:
struct sockaddr_in si_other;
struct sockaddr_in remaddr; /* remote address */
int slen = sizeof(remaddr);
int s, recvlen;
char buf[BUFLEN];
char message[BUFLEN];
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == SOCKET_ERROR) //IPPROTO_UDP
{
printf("socket() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
//setup address structure
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER);
if (bind(s, (struct sockaddr *)&si_other, sizeof(si_other)) < 0) {
perror("bind failed");
return 0;
}
u_long nMode = 1; // 1: NON-BLOCKING
if (ioctlsocket(s, FIONBIO, &nMode) == SOCKET_ERROR)
{
closesocket(s);
WSACleanup();
return 0;
}
//start communication
while (1)
{
printf("waiting on port %d\n", PORT);
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Done");
puts(buf);
}
The address I'm binding is 192.168.1.1 and the port 1234.
And the given output by WSAGetLastError is an empty buffer error: 10035
I tried to disconnect firewall, antivirus...and I'm running the program as a administrator, and it didn't help.
Why is the buffer empty? I'm clearly seeing that there are packets coming, what could be blocking the incoming data to the socket?
the given output by WSAGetLastError() is an empty buffer error: 10035
No it isn't. 10035 is WSAEWOULDBLOCK. That means the operation would block in blocking mode, i.e. that no data was present to be received at the moment you called recvfrom().
The address I'm binding is 192.168.1.1
The IP 192.168.1.1 is shown as a gateway
These two statements are mutually inconsistent. If it's a gateway it's an external IP address, and if it's an external IP address you can't bind to it.
I tried INADDR_ANY and it didn't help
Not surprising. If you're not 192.168.1.1 you can't receive its messages. Unclear why you would think otherwise.
As #EJP mentioned 10035 is WSAEWOULDBLOCK, i.e., no data is ready. The cause of this is that the receiver is 192.168.1.1 which is your gateway's IP address, thus not a local IP. In this case you cannot receive the packets in a normal manner.
You can receive these packets, even though they are not meant for you, by using an UDP sniffer, e.g., using libpcap.
Thanks for the answers, they pointed me to the right direction. I 've got now the program working and I'm able to receive the incoming UDP packets.
The solution was to "sniff" these UDP packets, winsock allows that using the WSAIoctl function after bind, in my case adding the next code to the above program (after the bind function):
if (WSAIoctl(s, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD)&si_other, 0, 0) == SOCKET_ERROR)
{
printf("WSAIoctl() failed.\n");
return 1;
}
I hope could help somebody else with similar issue.

How to run a live server win winsock?

So I want to run a live server on my pc to connect and get info from someone else. I thought I can let the other person connect to my ip address on a port that is not used. So for example if my hypothetical ip address is 214.231.34.12 and port 50000 and I open te connection and give this information to someone, they can connect to it and send me information through TCP.
I thought I could use this code:
// TCPClient.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
/*
Live Server on port 50000
*/
#include<io.h>
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
struct sockaddr_in server, client;
int c;
char *message;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_addr.s_addr = inet_addr("214.231.34.12");
server.sin_family = AF_INET;
server.sin_port = htons(50000);
//Bind
if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
//Listen to incoming connections
listen(s, 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(s, (struct sockaddr *)&client, &c)) != INVALID_SOCKET)
{
puts("Connection accepted");
//Reply to the client
message = "Hello Client , I have received your connection. But I have to go now, bye\n";
send(new_socket, message, strlen(message), 0);
}
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d", WSAGetLastError());
return 1;
}
closesocket(s);
WSACleanup();
return 0;
}
But it is failing at binding the connection. This whole TCP and winsocket stuff is totally new to me and I do not understand how I should approach this differently. I know this code is not receiving any information yet, it is just the connection that I try to get working at the moment. Is this not the right way to set this up?
The bind() fails with windows socket error 10049
There are plenty of obstacles for establish a TCP connection over internet:
internet itself: bad/unstable connection, dynamic ips, etc
ISP: maybe your ISP blocks some ports or ips
router: router firewall, NAT traversal problems, upnp, etc
OS: windows firewall, antivirus, port blocked/in use
YOUR APP: maybe a code mistake
Is a complete new world link to pcs over internet, the concept is the same, but implement it......
So it might be an answer, but maybe I have to use another port as datenwolf suggested.
I found that it is not possible to bind to my ISP's ipaddress. So I have forward the port I want to use and then connect to the ipaddress of my computer, as mentioned here:
connecting to an IP address instead of localhost?
I tried that, so I changed the ipaddress in code to:
//Prepare the sockaddr_in structure
server.sin_addr.s_addr = inet_addr("192.168.178.93");
server.sin_family = AF_INET;
server.sin_port = htons(50000);
And then when I connect to 214.231.34.12 and port 50000 with telnet, the connection works! I just wonder if this is a valid result?

c++ WINSOCK recvfrom no get data from network

i have problem because my server dont get UDP data. Ports on router are forwarded, data income to local-server network (it is visible on sniffer (3) ) but server dont receive it.
Server and server network screen
You can see 1 and 2 TCP packets correct income to server on connected sockets. But my client then send UDP data to server and data enter to local-server network (see that sniffer detect it on 3) but server dont take it.
Here is code of client:
struct sockaddr_in si_other;
int s, slen = sizeof(si_other);
char buf[10];
char message[10];
WSADATA wsa;
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//create socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
{
printf("socket() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
//setup address structure
memset((char *)&si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(14996);
si_other.sin_addr.S_un.S_addr = inet_addr(server ip);
memcpy(message, "cokolwiek", 8);
//send the message
if (sendto(s, message, strlen(message), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR)
{
printf("sendto() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
But its not problem with client. Here is server code but i think it is also correct:
SOCKET s;
struct sockaddr_in server, si_other;
int slen, recv_len;
char buf[10];
WSADATA wsa;
slen = sizeof(si_other);
//Initialise winsock
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
printf("Initialised.\n");
//Create a socket
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(14996);
//Bind
if (::bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
//blocking on it, waiting for data
if ((recv_len = recvfrom(s, buf, 10, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR)
{
printf("recvfrom() failed with error code : %d", WSAGetLastError());
exit(EXIT_FAILURE);
}
//print details of the client/peer and the data received
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
printf("Data: %s\n", buf);
Some description that may help - main server loop is select() and when client ask for order, server send order back to client and starts proceeding command.
server:
while (1) {
select()
if (socket is in FD_SET)
get data, send it back and handleCommand()
}
handleCommand() {
tcp data exchange
wait for udp packet - it fail
}
client:
sendCommand()
//another receiving commands thread
while (recv) {
handle command
tcp data exchange
send udp data
}
Pls dont give me answears to do it in another wait. I need to punch hole for NAT Traversal. What problem is that? Another listener grabbing my data? But netstat -nop UDP -a didn't give information that something other is listening, and bind socket didn't failed. Also another important information That code work on the begining of program, i mean server receive data but later not.
Okey, so as ElderBug said
Are you sure you setup the UDP server socket before you send the data ? It's not clear in your question
Yep, it was my fault. The miniseconds decided that sending data on one machine was executed before setting up listener on server. Thank you for answer.
But i dont exactly understand the problem. Shouldn't that data income to receive buffer and wait for "grabbing" it by recvfrom function?