Trying to receive incoming UDP packets, empty buffer - c++

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.

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).

Can not bind socket to address

I am trying to write some client code to send a UDP packet to another computer at a particular IP address. When the IP address was set to home it worked just fine. I could use wireshark to see the packets being sent. When I put the server's IP in I didn't see any packets. Upon further investigation I found I was getting an 10049 error when I tried to bind to the socket. I don't quite get why I can't bind to the IP of another computer on the network.
string m_port = "2033"; // port that the plugin is talking to
string m_hostIP = "192.168.2.27"; // IP address that the plugin is talking to
// start Windows Sockets
if ((error = WSAStartup(version, &data)) != NO_ERROR)
{
logError("Error: WSAStartup failed with error: ", error);
return;
}
// check if version 2.2 of Winsock is supported
if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2)
{
logError("Error: System could not support WinSock 2.2.", 0);
// clean up Winsock
if (WSACleanup() == SOCKET_ERROR)
{
logError("Error: Winsock cleanup error: ", WSAGetLastError());
}
return;
}
// create a datagram socket using IPv4 and UDP protocol
if ((m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
logError("Error: Socket creation failed with error: ", WSAGetLastError());
// clean up Winsock
if (WSACleanup() == SOCKET_ERROR)
{
logError("Error: Winsock cleanup error: ", WSAGetLastError());
}
return;
}
int iSetOption = 1;
if (setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&iSetOption, sizeof(iSetOption)) == SOCKET_ERROR)
{
logError("Error: Set Socket Options failed with error: ", WSAGetLastError());
// close the socket
if (closesocket(m_socket) == SOCKET_ERROR)
{
logError("Error: Unable to close socket: ", WSAGetLastError());
}
// clean up Winsock
if (WSACleanup() == SOCKET_ERROR)
{
logError("Error: Winsock cleanup error: ", WSAGetLastError());
}
m_socket = INVALID_SOCKET;
return;
}
struct sockaddr_in server_addr; // server address description struct
int server_addr_len = sizeof(server_addr); // size of server address struct
int bytesSent = 0;
memset((char *)&server_addr, 0, server_addr_len); // clear the address struct
server_addr.sin_family = AF_INET; // IPv4 address type
server_addr.sin_port = htons((unsigned short)stoul(m_port)); // port used by the simulator to send the data
server_addr.sin_addr.s_addr = inet_addr(m_hostIP.c_str()); // any server IP address will do
// bind the socket to the address struct
if (::bind(m_socket, (struct sockaddr *) &server_addr, server_addr_len) == SOCKET_ERROR)
{
logError("Error: unable to bind the socket: ", WSAGetLastError());
// close the socket
if (closesocket(m_socket) == SOCKET_ERROR)
{
logError("Error: Unable to close socket: ", WSAGetLastError());
}
// clean up Winsock
if (WSACleanup() == SOCKET_ERROR)
{
logError("Error: Winsock cleanup error: ", WSAGetLastError());
}
m_socket = INVALID_SOCKET;
return;
}
You bind socket to choose from which local endpoint (address+port) you send data.
Servers may have several network cards that connect you to internet or you may have several networks - by binding you choose from which network card (or whatever it actually is) you send your data.
Usually PCs have just a few workable address (local host and network addresses) but you can also specify the port. port can be used to filtrate unwanted packets which can be helpful when you want to create several sockets.
The other operation is called connect - choosing to which remote endpoint you send data. I don't remember exact details how it works on winsocket/udp. It might be unnecessary and you simply send the data instead and specify each time where you send it.

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?

Winsock UDP broadcast packets not sent

I'm encountering a strange issue using winsock when multiple network adapters are active but then one is disconnected.
This is the basic scenario:
Wifi and Ethernet are active and connected
Launch app, send UDP broadcast and receive response
Unplug Ethernet, restart app and try to send again - Nothing is sent (Wireshark shows nothing, seems Windows is dropping them before they get to NIC?)
Disable the disconnected Ethernet adapter and try again - sends fine over Wifi and gets response.
Now this is a very specific scenario but I believe it's happening in other cases, this is just the only way I know to reproduce it every time.
The following is a code snippet of the UDP send, for this example assume dstAddrStr is 192.168.1.255
struct sockaddr_in sa_remote;
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET) {
printf("Error creating socket: %ld\n", WSAGetLastError());
}
int enable = 1;
if ((setsockopt(sock,
SOL_SOCKET, SO_BROADCAST, (char*)&enable, sizeof(enable))) == -1) {
printf("Error enabling broadcasts: %ld\n", WSAGetLastError());
}
const MIB_IPADDRROW & row = iptbl->table[i];
uint32 ipAddr = ntohl(row.dwAddr);
uint32 netmask = ntohl(row.dwMask);
uint32 baddr = ipAddr & netmask;
if (row.dwBCastAddr) baddr |= ~netmask;
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
memset(&sa_remote, 0, sizeof(struct sockaddr_in));
sa_remote.sin_family = AF_INET;
sa_remote.sin_addr.s_addr = inet_addr(dstAddrStr);
sa_remote.sin_port = htons(_DST_PORT);
if (sendto(sock, dpString, strlen(dpString), 0, (struct sockaddr *)&sa_remote, sizeof(struct sockaddr_in)) < 0){
printf("UDP send error Error: %ld", WSAGetLastError());
break;
}

sendto and recvfrom in the same program?

this is my first time asking a question, and the first time I couldn't find an answer by just searching this site. so please go easy on me if I am doing it wrong.
Using Winsock. I need to send AND receive a packet of information to another computer running the same program. the type of connection should be UDP(non blocking I guess?)and using a data-coupled model.
do I need to be sending and receiving the information using different threads?
I know the data sends just fine but it is not being received at all.
I can easily have on program send and a completely different program recv but it seems the principles don't carry over to what I am trying to do.
should I use the same sockaddr_in struct for the recvfrom and sendto? or can they use the same one? how about slen? doesn't matter I have tried both and neither work.I have tried using one port to send and one to recieve, I have tried having one port to do both. nothing. I am relatively new to Winsock so sorry if I sound hopeless or missing something horribly obvious. At this point I just really need some help or at least a point in the right direction I don't care how many ports I just want to see the recv printf incoming with the right data.
winsock errors are
bind failed 10048 and recv failed 10022
I will also mention I looked into a concept called setsockopt suggested by MSDN but it just ended up furthering my confusion. am I missing something?
here are some relevant functions.
void UDPNetwork::initserver()
{
initRemote();
slen2= sizeof(si_other);
if ((_recvSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf("failed to create socket: %d", WSAGetLastError());
}
_recvSocket = (AF_INET, SOCK_DGRAM, 0);
memset((char *)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
if (bind(_recvSocket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d",
WSAGetLastError());
/* system("PAUSE");
exit(EXIT_FAILURE);*/
}
}
void UDPNetwork::initclient(){
slen = sizeof(si_other);
_sendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (_sendSocket == SOCKET_ERROR)
{
printf("failed to create socket... ");
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);
}
void UDPNetwork::send(float x, float y, float z)
{
sprintf(bufOut,"%f,%f,%f", x, y, z);
if (sendto(_sendSocket, bufOut, strlen(bufOut), 0, (struct sockaddr*) &si_other, slen) == SOCKET_ERROR)
{
printf("sento() failed with error code : d%", WSAGetLastError());
exit(EXIT_FAILURE);
}
//printf("Sent: %s\n", bufOut);
}
void UDPNetwork::recv(char *msg)
{
float ax = 0; float ay = 0; float az = 0;
memset(msg, '\0', BUFLEN);
recv_len = recvfrom(_recvSocket, msg, BUFLEN, 0, (struct sockaddr*) &si_other, &slen);
int nError = WSAGetLastError();
if (nError != WSAEWOULDBLOCK&&nError != 0);
{
printf("Recv failed with error code : %d",
WSAGetLastError());
//system("PAUSE");
//exit(EXIT_FAILURE);
}
recv = buf;
sscanf_s(msg, "'%f,%f,%f", &ax,&ay,&az);
printf("RECV: %f %f %f\n", ax, ay, az);
}
Most UDP receivers will send data back to the same IP:Port that the reeived data was sent from. So by creating two different sockets, you are using two different IP:Port pairs, which is likely why you are not receiving data. The data is likely being sent to a different IP:Port than the one you are reading on.
For UDP, you usually do not need to create separate send and receive sockets. You can create one UDP socket and use it for both sending and receiving, so the sending IP:Port matches the receiving IP:Port. The only time you should need to create separate sockets is if the receiver intentionally sends its data to a different IP:Port than what the sending socket is using.
after searching deep into the MSDN archives I found this helpful little page
https://msdn.microsoft.com/en-us/library/bb530747%28v=vs.85%29.aspx
hopefully this will add some insight to my problem. I will update on weather this resource ended up solving my problems