0

I fallen into problem during development of my client application.

I want to use non-blocking UDP sockets in my application to communicate with a server. I am using winsock2 library on Windows.

But... For some reason I have strange behavior of select() function under some conditions:

  1. Socket don't have bound address and port (it is client-side socket, so it don't need it).
  2. Before select() I send data to my local address and some port with sendto call.
    • For example: 192.168.1.2

Under these conditions select() instantly (without even waiting for timeout) returns 1. Like I have some packet ready to receive. But if call recvFrom then it will sure return -1.


  1. If I send my packets from client to any other address (which is not my address on LAN) then select() works as intended.
  2. Also select() works as intented if don't send any packets to any address before calling select().

Socket initialization method:

bool CUdpSocket::initialize()
{
  _handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  ... error processing code, returns false if error...
}

Method which uses select(). This method works fine for server socket (with bound address and port).

bool CUdpSocket::waitData(s32 timeout_ms)
{
    fd_set readset;
    int result;
    struct timeval tv;

    // Initialize the set.
    FD_ZERO(&readset);
    FD_SET(_handle, &readset);

    // Initialize time out struct.
    tv.tv_sec = 0;
    tv.tv_usec = timeout_ms * 1000;

    result = select(_handle + 1, &readset, NULL, NULL, &tv);

    // Timeout with no data.
    if (result == 0) {
        return false; // Get out of here!
    }

    // Error.
    if (result < 0) {
        // TODO: Maybe throw exception or do something.
        return false;
    } else if (!FD_ISSET(_handle, &readset)) {
        return false; // No data!
    }

    // There is some data!
    return true;
}
  • Seen this? https://stackoverflow.com/questions/13547721/udp-socket-set-timeout, http://danzig.jct.ac.il/tcp-ip-lab/inet-dgram/timeout/ –  Jun 30 '18 at 16:06
  • `recvfrom()` will return -1 with what error? – user207421 Jun 30 '18 at 16:34
  • @EJP Hmmm... Forgot to check that. WSAGetLastError after ``recvFrom`` call returns code 10054 (WSAECONNRESET). – zcaliptium Jun 30 '18 at 16:42
  • Google is your friend: Google "WSAECONNRESET UDP" - top hit: https://stackoverflow.com/questions/30749423/is-winsock-error-10054-wsaeconnreset-normal-with-udp-to-from-localhost, as per comment by @ChrisDodd below. I hope you learned something about digging into your own problems from this. – Paul Sanders Jul 03 '18 at 05:33

1 Answers1

0

If you send a packet from an unbound UDP socket, the OS will pick an usused port for you and bind the socket to that port -- the UDP protocol requires that the sending port have an address to send from.

So if the packet you're sending results in a response, then it makes perfect sense for the select to return 1 -- that's the response to the packet you sent.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • As I wrote. Problem is... I am constantly getting returm `1` even if server application is not started (there is no response). And the ``select()`` returns `1` instantly. Without waiting when timeout expire. This happen only if address where I send request address is my LAN address. – zcaliptium Jun 30 '18 at 16:53
  • If the server is not running, you may be getting an ICMP error response from the the OS. In which case, that may show up as an error on the receiving socket. – Chris Dodd Jun 30 '18 at 17:47