Recvfrom function not receiving data - c++

This is my first time posting so hopefully I'm doing it right. I've been browsing the site trying to find an answer to this problem, but I'm at a loss.
I developed some UDP code in C++ in Linux on a Raspberry Pi, that's supposed to receive from something on Windows. If it matters, I'm using Remote Desktop to access the Pi from the same computer the code is on. Due to other problems, I can't simply put this code on the Pi.
I can create a socket, bind() it, and do everything up to the point where the recvfrom() function is supposed to grab the data. At this point, it simply stops working. There's no error, it just won't display anything below it, even an if statement for if recvfrom is -1.
I've tried making it blocking and non-blocking, changing the variable names, and plopping this part of the code down in its own separate file to debug, but it still won't receive anything. I know the server code works fine.
This isn't my first time working with UDP, but I'm also not super experienced, and I don't know what could be causing this issue. There's another UDP function in the code that works.
Why aren't I receiving data, and how can I fix it?
int PORT = 20016;
struct sockaddr_in serverAddress;
memset((char *) &serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(PORT);
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
int packetSize = 36;
char packetData[packetSize];
struct sockaddr_in clientAddress;
socklen_t caddr_length= sizeof clientAddress;
handle = socket( AF_INET, SOCK_DGRAM, 0 );
if(handle < 0)
{
perror("socket\n");
exit;
}
if ( bind( handle, (struct sockaddr*)&serverAddress, sizeof(serverAddress) ) < 0 )
{
perror("bind failure\n");
exit;
}
while ( 1 )
{
cout << "receiving data..." << endl;
int received_bytes = recvfrom(handle, packetData, sizeof(packetData),0, (struct sockaddr*)&clientAddress, &caddr_length);
if ( received_bytes == -1)
{
cout << "Data not received: " << strerror(errno) << endl;
}
else
{
cout << "Data incoming:" << endl;
int *dataPacket=(int *)packetData;
a = dataPacket[0];
b = dataPacket[1];
c = dataPacket[2];
d = dataPacket[3];
e = dataPacket[4];
f = dataPacket[5];
g = dataPacket[6];
h = dataPacket[7];
i = dataPacket[8];
}
}
return 0;
}

Related

Recvfrom working locally, but don't receive anything on random ports between executions

I'm working on a multithreaded UDP listener and I'm stuck in a problem that definitely surpasses me.
So, I'm required to receive huge amounts of UDP packets in several ports. Locally, the best solution for me was to call non blocking recvfrom in as much threads as ports I'm listening (select and poll were too slow for my requirements). I'm using a thread pool manager, it simply calls on threads and queues tasks. Here's the code:
void receiveFromSocket(void * arguments){
sockaddr_in client; // Local
socklen_t clientSize = sizeof(client);
memset(&client, 0, sizeof(client));
struct arg_struct_listenPort *args2 = (struct arg_struct_listenPort *)arguments;
int fd = args2->arg_fd;
int port = args2->arg_port;
for(;;) {
char buf[158];
memset(buf,0,158*sizeof(char));
int n = recvfrom(fd, (char * ) buf, 158, MSG_DONTWAIT, ( struct sockaddr *) &client, &clientSize);
if(n == -1){
//cerr << "Error while receiving from client: " << errno << endl;
continue;
}
if(n != 158){
cerr << "Discarded message since it's not 158 bytes." << endl;
continue;
}
struct arg_struct args;
args.arg_port = port;
memcpy(args.buf,buf,158);
thpool_add_work(globals.thpool, socketThread, (void*)(&args));
}
}
/// Runs the Socket listener
int network_accept_any()
{
vector<int>::iterator i;
for(i = globals.fds.begin(); i != globals.fds.end(); i++){
int port = distance(globals.fds.begin(),i);
struct arg_struct_listenPort args;
args.arg_fd = *i;
args.arg_port = globals.cmnSystemCatalogs[port].diag_port;
thpool_add_work(globals.thpool, receiveFromSocket, (void*)(&args));
}
cout << "Listening threads created..." << endl;
return 0;
}
This works perfectly fine locally. But when I compile it on a production environment, some ports listen the packets and other's simply don't! And the working ports change in each execution. I can , confirm that it is not a firewall problem. I also can clearly see the packets through Wireshark. I can receive packets on those ports through netcat. Netstat shows all ports open.
My local environment is an Ubuntu 18.04 VM, and the production environment is a Debian 9.8.
Here's how I call the sockets:
int lSocket(int port) {
//Crear Socket
int listening = socket(AF_INET, SOCK_DGRAM, 0);
if (listening == -1) {
cerr << "No se puede crear el socket";
exit(EXIT_FAILURE);
}
//Enlazar socket a un IP / puerto
struct sockaddr_in hint;
memset(&hint, 0, sizeof(hint));
hint.sin_family = AF_INET; //IPv4
hint.sin_port = htons(port); //Port
hint.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(listening, (struct sockaddr*)&hint, sizeof(hint)) == -1) { //Enlaza las opciones definidas al socket
cerr << "No se puede enlazar IP/puerto" << endl;
exit(EXIT_FAILURE);
}
return listening;
}
Any advise is greatly appreciated!
EDIT:
As suggested, I tried switching to blocking I/O, but the main issue remains. Still not receiving at all the opened ports.
What an amazing welcome!
#molbdnilo was absolutely right:
You're using pointers to objects whose lifetime has ended (&args).
This has undefined behaviour - it might appear to work, but it's a bug
that needs a-fixin'.
Here's the fixed code. Gotta be careful when feeding arguments to threads!
void receiveFromSocket(void * arguments){
sockaddr_in client; // Local
socklen_t clientSize = sizeof(client);
memset(&client, 0, sizeof(client));
struct arg_struct_listenPort *args2 = (struct arg_struct_listenPort *)arguments;
int fd = args2->arg_fd;
int port = args2->arg_port;
for(;;) {
char buf[158];
memset(buf,0,158*sizeof(char));
int n = recvfrom(fd, (char * ) buf, 158, MSG_WAITALL, ( struct sockaddr *) &client, &clientSize);
if(n == -1){
cerr << "Error while receiving from client: " << errno << endl;
continue;
}
if(n != 158){
cerr << "Discarded message since it's not 158 bytes." << endl;
continue;
}
arg_struct *args = new arg_struct;
args->arg_port = port;
memcpy(args->buf,buf,158);
thpool_add_work(globals.thpool, socketThread, (void*)(args));
}
}
/// Runs the Socket listener
int network_accept_any()
{
vector<int>::iterator i;
for(i = globals.fds.begin(); i != globals.fds.end(); i++){
int port = distance(globals.fds.begin(),i);
arg_struct_listenPort *args = new arg_struct_listenPort;
args->arg_fd = *i;
args->arg_port = globals.cmnSystemCatalogs[port].diag_port;
thpool_add_work(globals.thpool, receiveFromSocket, (void*)(args));
}
cout << "Listening threads created..." << endl;
return 0;
}
Also, I'll keep an eye on #John Bollinger 's and #Superlokkus comments.
Thank you all!

WinSock2 client/server communication: send & receive strings

I am having a bit of difficulty trying to code this as I do not know a lot. I have a setup for two PCs that can communicate between each other. It works and all, but it only can send single characters to each other. One PC acts like a server if the command is executed with no IP address argument, and the other, given a server IP address, acts like a client to connect to the server.
The code is all here:
// Quick and dirty - error checks omitted for brevity.
#include <iostream>
#include <string>
#include <conio.h>
#include <WinSock2.h>
#include <ws2tcpip.h>
using namespace std;
void chat (int socket_d)
{
while (true)
{
if (_kbhit ())
{
char ch;
ch = _getche();
int n;
n = send (socket_d, &ch, 1, 0);
if (ch == '\r')
{
cout << "\n";
}
}
int n;
int count = 0;
char byte; // Read one byte at a time - is this efficient?
n = recv (socket_d, &byte, 1, 0);
if (n <= 0)
{
if (WSAGetLastError() != WSAEWOULDBLOCK) // A real problem - not just avoiding blocking.
{
cout << "Terminated " << WSAGetLastError() << "\n";
return;
}
}
else
{
cout << (char)byte;
if ((char) byte == '\r')
cout << "\n";
}
}
}
int main (int argc, char * argv [])
{
// Messy process with windows networking - "start" the networking API.
WSADATA wsaData;
int result = WSAStartup (MAKEWORD (2, 2), &wsaData);
unsigned short port = 25565;
// If argument is IP address - be a client and connect to it. Otherwise
// be a server.
if (argc > 1)
{
int socket_d;
socket_d = socket (AF_INET, SOCK_STREAM, 0);
// be a client.
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr (argv[1]); // Parse the string and create the 32 bit address.
server_addr.sin_port = htons (port); // Watch out for the endian conversion!
connect (socket_d, (sockaddr *) &server_addr, sizeof (server_addr));
u_long iMode=1;
ioctlsocket (socket_d, FIONBIO, &iMode); // put the socket into non-blocking mode.
chat (socket_d);
closesocket (socket_d);
}
else
{
// be a server
int listen_socket_d;
int connection_socket_d;
listen_socket_d = socket (AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; // A placeholder that will be replaced with my own address.
server_addr.sin_port = htons (port); // Watch out for the endian conversion!
bind (listen_socket_d, (struct sockaddr *) &server_addr, sizeof (server_addr));
int backlog = 5;
listen (listen_socket_d, backlog);
// take only the first connection.
struct sockaddr_storage their_addr;
int their_addr_size = sizeof(their_addr);
connection_socket_d = accept (listen_socket_d, (struct sockaddr *) &their_addr, &their_addr_size);
u_long iMode=1;
ioctlsocket (connection_socket_d, FIONBIO, &iMode); // put the socket into non-blocking mode.
chat (connection_socket_d);
closesocket (connection_socket_d);
}
return 0;
}
What I am trying to achieve is to be able to send strings instead of single characters. The way I would like this to work is by increasing the byte size it sends instead of single byte currently. The way I am assuming it could work, let's say a total size of 64 bytes is sent and received at a time.
It's not really clear from this where your problem area is actually.
My solution is below. The basic idea is to allocate send and receive buffers of equal size, append characters to the send buffer on keyboard input, and transfer the buffer when it is full or the user hits the return key.
The non-blocking send function might not send the whole buffer at once (see the docs). I decided to go ahead and block here until the entire buffer was sent so I didn't have to track separate input and transmit buffers. You could improve on this, I'm sure.
The receive part just echoes whatever bytes have been received. In general, there's no way to know whether the other user was "done" sending data, so we just print what we received after the first call to recv.
I always memset the buffers to all zeros after each send and receive to prevent weird behavior from missing null terminators. It would be more optimized to simply append a null character to the end of the current string, but I get paranoid sometimes.
Here's my code:
#define BUFFER_SIZE 64
void chat (int socket_d)
{
char sendBuffer[BUFFER_SIZE] = { 0 };
char receiveBuffer[BUFFER_SIZE] = { 0 };
int bufferPosition = 0;
int charsSent = 0;
int charsReceived = 0;
while (true)
{
if (_kbhit ())
{
sendBuffer[bufferPosition++] = _getche();
if (sendBuffer[bufferPosition - 1] == '\r' || bufferPosition == BUFFER_SIZE - 1)
{
// This defeats the purpose of a non-blocking socket, I know.
// You can do better by keeping separate buffers for sending and
// collecting input.
while (charsSent < bufferPosition)
{
charsSent += send(
socket_d,
&sendBuffer[charsSent], // Treats the address of a character as a string.
bufferPosition - charsSent, // Only send the part that hasn't been sent yet.
0);
}
memset(sendBuffer, 0, bufferPosition); // Paranoid.
bufferPosition = charsSent = 0;
cout << "\n";
}
}
charsReceived = recv (socket_d, receiveBuffer, BUFFER_SIZE, 0);
if (charsReceived <= 0)
{
if (WSAGetLastError() != WSAEWOULDBLOCK) // A real problem - not just avoiding blocking.
{
cout << "Terminated " << WSAGetLastError() << "\n";
return;
}
}
else
{
cout << receiveBuffer;
if (receiveBuffer[charsReceived - 1] == '\r')
cout << "\n";
memset(receiveBuffer, 0, charsReceived); // Super paranoid.
}
}
}
Now, I wouldn't really consider this "good" until it supports UTF-8, or at least wchar_t. ASCII lacks a lot of characters that people expect to be able to use in a real chat application.
PS - According to Visual Studio 2013, the inet_addr function is deprecated. I used inet_ptons instead. Here's the documentation on the Winsock implementation for it.

connection error: Invalid argument at sockets

I have this code
Server:
//"sock" has already been created with no problem and binding as well
void Connection::bind_connection(int port){
cout << "Port " << port << endl;
server.sin_family = AF_INET ;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(port);
/* Bind socket to address */
struct sockaddr *serverptr = ( struct sockaddr *) &server;
if ( bind ( sock , serverptr , sizeof(server) ) < 0) {
perror("Binding error"); exit(BE);
}
cout << "Server binding completed!" << endl;
}
struct sockaddr_in client ;
socklen_t clientlen ;
struct sockaddr * clientptr =( struct sockaddr *) &client ;
if ( listen (sock , MAX_CONNECTIONS) < 0) {perror("listening error"); exit(LE);}
cout << "Listening for connections to port " << port << endl;
while (1) {
/* accept connection */
if (( newsock = accept ( sock , clientptr , &clientlen ) ) < 0) {
perror("Accepting error"); cout << "Errno = " << errno << endl; exit(AE);
}
//Code
....
}
and
Client:
//struct sockaddr_in server; <--- declared as data member of class "Connection"
//"sock" has already been created with no problem
void Connection::do_connect(){
struct sockaddr *serverptr = ( struct sockaddr *) &server;
if ( connect ( sock , serverptr , sizeof (server) ) < 0)
perror("client connect"); exit(CE);
cout << "Client connecting to the server" << endl;
}
and I get the above message. Most of the code is copied from the lesson slides but modified for my needs. Googling the problem it seems that I give wrong size at the syscall(s). Any idea where exactly the problem is? Thanks in advance.
Those lines always exit:
if ( connect ( sock , serverptr , sizeof (server) ) < 0)
perror("client connect"); exit(CE);
You might start to think about using a different indention scheme. Typically one that does not use more then one statement per line.
For the above code a tool like indent would have formatted it like this:
if (connect (sock, serverptr, sizeof (server)) < 0)
perror("client connect");
exit(CE);
This format makes the programming bug obvious.
You didn't initialize clientlen.
socklen_t clientlen = sizeof(client);
You can catch similar problems in future by running your code through valgrind.
As already indicated, you do not seem to be initializing your variables properly. You do not show how you initialize your sockaddr_in structures, which is likely the culprit. A relatively easy way to specify the address for bind() or connect() is to use getaddrinfo()/freeaddrinfo(). From the documentation:
Synopsis
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
void freeaddrinfo(struct addrinfo *res);
Description
Given node and service, which identify an Internet host and a service, getaddrinfo() returns one or more addrinfo structures, each of which contains an Internet address that can be specified in a call to bind(2) or connect(2). ...
The freeaddrinfo()function frees the memory that was allocated for the dynamically allocated linked list res.
As a simple example, here is a function that can connect to a server specified by a string that has the format <servername>:<port>:
int connect_tcp (std::string hostspec) {
struct addrinfo hints = { .ai_flags = AI_NUMERICSERV };
struct addrinfo *res = 0;
std::istringstream ss(hostspec);
std::string node, service;
int sock = -1;
std::getline(ss, node, ':');
std::getline(ss, service, ':');
getaddrinfo(node.c_str(), service.c_str(), &hints, &res);
for (struct addrinfo *rp = res; rp != 0; rp = rp->ai_next) {
if (rp->ai_socktype != SOCK_STREAM) continue;
int sock = socket(rp->ai_family, SOCK_STREAM, 0);
if (sock == -1) continue;
if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
break;
close(sock);
sock = -1;
}
freeaddrinfo(res);
if (sock == -1) errno = EHOSTDOWN;
return sock;
}

C++ Winsock2 sending integers with byte order

I have been looking for a way to have an integer sent over a Windows Socket using Winsock2. I have looked at most, if not all, of the questions people have asked on stackoverflow already.
This is what I have for the client, that sends the integer:
struct struct_var
{
int Packet;
int Number;
};
struct_var *arraystruct;
arraystruct = (struct_var *) malloc(sizeof(struct_var));
(*arraystruct).Packet = 100;
(*arraystruct).Number = 150;
int bytes = send(client,(char*)arraystruct,sizeof(*arraystruct),0);`
I have also tried to send using:
int int_data = 4;
int bytes = send(server, (char*) &int_data, sizeof(int), 0);`
This was recommended on another stackoverflow question
This is the receiving side, which was also recommended:
int int_data;
int bytes = recv(server, (char*) &int_data, sizeof(int), 0);
cout << int_data;`
When I run these the output I get from command line is: -858993460
Does anyone know why this is happening?
I would also like it to have the correct byte order as this will be sent over multiple kinds of computers.
Thanks in advance who can help me out
Full Server Code:
int main() {
WSADATA wsaData;
WORD version;
int error;
version = MAKEWORD(2, 0);
error = WSAStartup(version, &wsaData);
if ( error != 0 )
{
return FALSE;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup();
return FALSE;
}
SOCKET server;
server = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(5555);
if (bind( server, (SOCKADDR*)&sin, sizeof(sin) ) == SOCKET_ERROR ){
DWORD ec=WSAGetLastError();
cerr << hex << "bind ERROR" << ec << endl;
return FALSE;
}
if ( listen( server, SOMAXCONN ) == SOCKET_ERROR ) {
DWORD ec=WSAGetLastError();
cerr << hex << "listen ERROR" << ec << endl;
return FALSE;
}
SOCKET client;
int length;
while(1) {
if ( listen( server, SOMAXCONN ) == SOCKET_ERROR ) {
DWORD ec=WSAGetLastError();
cerr << hex << "listen ERROR" << ec << endl;
return FALSE;
}
length = sizeof sin;
client = accept( server, (SOCKADDR*)&sin, &length );
cout << "Client connected" << endl;
cout << "Sending Instructions..." << endl;
int int_data;
int bytes;
bytes = recv(client, (char*) &int_data, sizeof(int), 0);
cout << int_data << endl;
}
}
}
Full Client Code:
int main() {
WSADATA wsaData;
WORD version;
int error;
version = MAKEWORD(2, 0);
error = WSAStartup(version, &wsaData);
if ( error != 0 )
{
return FALSE;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup();
return FALSE;
}
SOCKET client;
client = socket( AF_INET, SOCK_STREAM, 0 );
sockaddr_in sin;
memset( &sin, 0, sizeof sin );
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_port = htons(5555);
if ( connect(client, (SOCKADDR*)(&sin), sizeof sin ) == SOCKET_ERROR ){
return FALSE;
}
int int_data = 4;
int bytes = send(client, (char*) &int_data, sizeof(int), 0);
}
Here's the problem:
int bytes = recv(server, (char*) &int_data, sizeof(int), 0);
Should be:
int bytes = recv(client, (char*) &int_data, sizeof(int), MSG_WAITALL);
A few other nitpicky things, that aren't causing your problem, but you should know:
Don't bind your server socket to 10.0.0.5. Bind to 0 (INADDR_ANY). That way, your code still works when you run it on machine who's IP addrss is 10.0.0.6.
Use htonl(), htons(), ntohs(), and ntohl() for interoperating with big-endian boxes.
Always check the return values from socket calls. If recv returns 0 or -1, it means the remote side has disconnected. (0 technically means the client has stopped sending, but unless you are doing shutdown half-close stuff, it means he disconnected).
TCP sockets are not message oriented, they are stream oriented. That is, just because you tell recv() to get N bytes, doesn't mean it will return N bytes. IP fragmentation, TCP segmentations, and other factors can make recv() return partial data. Use the MSG_WAITALL flag as appropriate.
You're making this almost impossible on yourself. Instead of starting with code, start with a protocol specification. You can look at the specifications of existing protocols that use TCP, such as HTTP, IMAP, and so on, to see what a protocol specification should include.
The protocol specification should explain everything that is sent or received at the byte level. It should explain how connections are established and torn down. It should explain how dead connections are detected from either end. If the protocol has application-layer messages, it should explain how they are delimited and how the receiver finds the ends of messages. It should specify who transmits when.
Then, debugging is easy. Follow this flowchart:
1) Does the server follow the specification? If not, the server is broken.
2) Does the client follow the specification? If not, the client is broken.
3) If it still doesn't work, the specification is broken.
This makes it possible to ensure that the server and client work together. And when they don't, it makes it possible to know which side needs to be fixed.
It only take an hour or two to sketch out a protocol specification, and I promise you the time saved will be more than worth it. All it takes is one time you change the wrong end when something doesn't work (and then find lots of things are newly-broken because you fixed one of the places that was right) to pay for the time taken. Plus, as a bonus, it is then possible to make other implementations.
I was stuck at this problem as well and I noticed that my client wasn't even connecting.
Try to save the value returned by connect() and recv() making sure its > -1 or print out some error.

Problem with simple UDP client/server application

Ok. So I have a simple client program sending images over UDP to a specified IP address. At the specified IP a server program is listening and should receive the images.
When I try both programs on localhost (i.e. they are both running at 127.0.0.1) it works and the server receives the images. When I try to put the client and the server programs on different PCs in the same network it does not work.
147.232.24.163 is the server IP, 147.232.24.150 is the client IP.
Here is my client program:
// Initialize UDP.
struct sockaddr_in server;
int n_sent;
int socketId = socket(AF_INET, SOCK_DGRAM, 0);
if (socketId < 0)
{
cout << "Problem creating socket." << endl;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("147.232.24.163");
// Establish the server port number - we must use network byte order!
server.sin_port = htons(42001);
for ( int iter = 0; iter < 60; iter++ )
{
// load image into jpegBuf
n_sent = sendto(socketId, reinterpret_cast<char*> (&jpegBuf[0]), jpegBuf.size(), 0, (struct sockaddr*) &server, sizeof(server));
if (n_sent < 0) {
cout << "Problem sending data." << endl;
}
}
close(socketId);
Here is my server program:
int main()
{
int bufferSize = 1024000;
int iSockFd = -1;
int iLength = 0;
struct sockaddr_in servAddr, cliAddr;
char buff[bufferSize];
iSockFd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
memset(&servAddr, 0, sizeof(servAddr));
memset(&cliAddr, 0, sizeof(cliAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("147.232.24.163");
servAddr.sin_port = htons(42001);
int cliAddrLen = sizeof(struct sockaddr_in);
int bindRet = bind(iSockFd, (struct sockaddr*)&servAddr, sizeof(servAddr));
cout << "Bind returned " << bindRet << endl;
int i = 0;
while (true)
{
int iRcvdBytes=recvfrom(iSockFd, buff, bufferSize, 0,
(struct sockaddr*)&cliAddr, (socklen_t*)&cliAddrLen);
if (0 == i % 5)
{
cout << "Received " << iRcvdBytes << " bytes from the client" << endl;
}
i++;
}
close(iSockFd);
return 0;
}
Any ideas why it does not work? I don't get any error messages.
This is not a solution but your code should be checking iRcvdbytes for error in the same way as the send code checks the result of sendto.
A return of 0 means the socket was closed gracefully (if connection-oriented - that should not apply here), SOCKET_ERROR means an error (in WinSock2 at least).
The socket on the send side needs to be created with IPPROTO_UDP, not 0. This could definitely be causing your failure.