0
votes

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

}
2
What is this line of code supposed to do: _recvSocket = (AF_INET, SOCK_DGRAM, 0);? - πάντα ῥεῖ
The errors are WSAEADDRINUSE and WSAEINVAL. Reading about them together with a bind and recv function reference might be a good start. - Some programmer dude
yes this is where MSDN told me to look into setsockopt but I have no idea why or what I am supposed to do with it. there are about 50 different socket options. I can't seem to find a good reference on how to use it even on MSDN.(as in an example). is setsockopt really the only way to achieve a data coupled model? - Mac
@Mac The bind(_recvSocket) error might well be caused from that code line I have pointed out. It's nothing more than an obfuscated way to write _recvSocket = 0;. - πάντα ῥεῖ
Also, the recvfrom call may modify the address length argument, you should really set it prior to each call. - Some programmer dude

2 Answers

1
votes

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.

0
votes

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