0

I started to lock into socket programming an got into a little trouble: I created the small program below which sends a message via udp an receives one if possible in a loop. I want to try that with multiple sockets later on, so I use select().

When I use my 127.0.0.1, select() gives a timeout in the first loop (after send()) but after that it always returns 1 indicating that the socket is readable without receiving a message:

//C++
WSADATA wsa;
SOCKADDR_IN RemoteAddr;
SOCKADDR_IN OwnAddr;
SOCKET UDP_Socket1;
fd_set m_Fds;
struct timeval m_Timeout;
int iRemoteAddrLenght = sizeof(SOCKADDR_IN);
int i = 0;

//--Init
WSAStartup (MAKEWORD (2,2), &wsa);
UDP_Socket1 = socket(AF_INET, SOCK_DGRAM, 0);
m_Timeout.tv_sec = 2;
m_Timeout.tv_usec = 0;

RemoteAddr.sin_family = AF_INET;
RemoteAddr.sin_port = htons (2002);
RemoteAddr.sin_addr.s_addr = inet_addr("127.0.0.1");   

OwnAddr.sin_family = AF_INET;
OwnAddr.sin_port = htons (2003);
OwnAddr.sin_addr.s_addr = htonl(INADDR_ANY);

bind(UDP_Socket1, (SOCKADDR*) &OwnAddr, sizeof(OwnAddr));

for(;;)
{
    //..//
    //--send
    sendto(UDP_Socket1, sSend.c_str(), strlen(sSend.c_str()), 0 ,  (SOCKADDR*)&RemoteAddr, sizeof(RemoteAddr));

    //--select & recv
    FD_ZERO(&m_Fds);
    FD_SET(UDP_Socket1,&m_Fds);
    i = select(sizeof(m_Fds)*8, &m_Fds, NULL, NULL, &m_Timeout);
    if(i > 0)
    {
        recvfrom(UDP_Socket1, m_szBuff, 256, 0, (SOCKADDR*) &RemoteAddr, &m_iRemoteAddrLenght);
    } //if
    else if(i < 1)        // "0" in 1st loop, then "1" =(
    {
        cout << "Udp Timeout" << endl;    
    } //else if
} //for

send returns 56 (bytes send) with WSAGetLastError: 0

recvfrom returns -1 with WSAGetLastError: 10054

I'd appreciate your help about why select() returns 1 when it should timeout

moon
  • 1
  • Where you create the socket, you must tell it that you want a UDP one: the third parameter must be IPPROTO_UDP – Loghorn Mar 21 '13 at 21:51
  • `UDP_Socket1 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);` is still the same – moon Mar 21 '13 at 21:56
  • if `recvfrom` returns -1 and `WSAGetLastError` return 10054 (`WSAECONNRESET`), according to MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/ms740120.aspx) it means that the send actually failed (ICMP Port Unreachable). Try to check for errors in the select by passing another fd_set as fourth parameter. – Loghorn Mar 21 '13 at 22:21
  • ´i = select(sizeof(m_Fds)*8, NULL, NULL, &m_Fds, &m_Timeout);´ returns "0"; when I add a second fd_set with my socket and pass it to select like this: ´int i = select(1,&m_Fds, NULL, &m_Fds2, &m_Timeout);´ it still returns "1" and would you be so kind and explain why recvfrom() cares about sendto()? I thought Udp is all about just firing a message and not caring about it later on...? thanks in advance – moon Mar 21 '13 at 22:39
  • sry, took too long to edit: `i = select(sizeof(m_Fds)*8, NULL, NULL, &m_Fds, &m_Timeout);` returns "0"; when I add a second fd_set with my socket and pass it to select like this: `int i = select(1,&m_Fds, NULL, &m_Fds2, &m_Timeout);` it still returns "1". ... and would you be so kind and explain why recvfrom() cares about sendto()? I thought Udp is all about just firing a message and not caring about it later on...? thanks in advance – moon Mar 21 '13 at 22:45
  • Sorry, I mean something like: `select(0, &m_Fds, NULL, &m_Err, &m_Timeout)` then you can check if the socket is ready for receive or in error. Also, are you sure that you want to send the packet to localhost? – Loghorn Mar 21 '13 at 22:45
  • Honestly, I don't know why recvfrom returns error if sendto failed, I've simply read it on the documentation. Here you can find something related: http://stackoverflow.com/questions/2372371/error-receiving-in-udp-connection-refused – Loghorn Mar 21 '13 at 22:49
  • `select(0, &m_Fds, NULL, &m_Err, &m_Timeout)` returns the "1"/0 with `FD_ZERO(&m_Err);` executed first (with a "beep" over my speakers..?) and without that: "-1" / 10055. (m_Error only declared, not filled with the socket, I hope that's what you meant) By using localhost I could try my programs and send and recv without using another machine (which I dont have =) – moon Mar 21 '13 at 23:33
  • you should fill m_Error too. However, do you have something listening on port 2002 on your machine? – Loghorn Mar 21 '13 at 23:41
  • I treated my `&m_Fds2`exactly like `&m_Fds` so I guess that's covered. And I changed the part about the ports and enter various port no whenever I compile the project. – moon Mar 21 '13 at 23:55

1 Answers1

0

You can ignore these kinds of errors for UDP. Some operating systems report them, some don't. They're basically meaningless.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278