This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

UDP API problems ... what am I doing wrong ?

Hi

 I am having problems with the following code, where I try to communicate with a server over port 123

This line of code    iReadSocks = select(2, &socks, 0, 0, &timeout);   never returns a readsocket.

It is a mix of sample code from e.g. Basic wifi App.

Can You see what I have done wrong. It is the first time is use UDP. I have no trouble using TCP interaction with webservices.

I hope you can help.... I am kind of lost. The doxygen documentation doesn't help much here.

Kind regards Thomas

 

Here is the code :

 

//*****************************************************************************
//!   get time from timeserver
//*****************************************************************************
void getTimeFromServer()
{  
 
      unsigned char g_ThisMulticastAddress[4] = {224, 0, 0, 1};
      signed short sRxMsgLen;
      fd_set socks;
      struct timeval timeout;
      int iReadSocks;
      sockaddr  sntpSocketAddr;      
      socklen_t tRxPacketLength;
      socklen_t optlen;
      unsigned long uloptval;
      signed char cRetVal;
    
     
      // Timeout set for 1 ms
      timeout.tv_sec = 0;
      timeout.tv_usec = 5000;

      long udpSocket = 0xFFFFFFFF;
      unsigned int localport = 6800;
      unsigned int port = 123;
     
      unsigned char ntpData[48];
      int returnValue;
     
      ntpData[0] = 0x1B;    
      for (int i = 1; i < 48; i++)
      {
        ntpData[i] = 0;
      }      
     
      // setup my locals
      udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
      sntpSocketAddr.sa_family = AF_INET;
      sntpSocketAddr.sa_data[0] = (unsigned char) (localport >> 8);
      sntpSocketAddr.sa_data[1] = (unsigned char) localport;
      memcpy(&sntpSocketAddr.sa_data[2], g_ThisMulticastAddress, 4);
        
      if(udpSocket >= 0)     
      {
        if(bind(udpSocket, &sntpSocketAddr, sizeof(sockaddr)) == 0)
        {  
            memset(&sntpSocketAddr,0, sizeof(sntpSocketAddr));             
            sntpSocketAddr.sa_family = AF_INET;  
            sntpSocketAddr.sa_data[0] = (unsigned char) (port >> 8);
            sntpSocketAddr.sa_data[1] = (unsigned char) port;          
            sntpSocketAddr.sa_data[2] = 213;    // First octet of destination IP  
            sntpSocketAddr.sa_data[3] = 161;    // Second Octet of destination IP
            sntpSocketAddr.sa_data[4] = 194;    // Third Octet of destination IP
            sntpSocketAddr.sa_data[5] = 93;     // Fourth Octet of destination IP

            returnValue = sendto(udpSocket, ntpData, 48, 0, &sntpSocketAddr, sizeof(sockaddr));   
           
            // First use select to determine if there are any messages ready
            FD_ZERO(&socks);
            FD_SET(udpSocket, &socks);
            cRetVal = getsockopt(udpSocket, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &uloptval, &optlen);          
            iReadSocks = select(2, &socks, 0, 0, &timeout);
           
            if (iReadSocks > 0)
            {      
                if (FD_ISSET(0, &socks)) // Check if socket has data
                { 
                      sRxMsgLen = recvfrom(udpSocket, ntpData, 48, 0, &sntpSocketAddr, &tRxPacketLength);
                } 
            }
        }
    }
}

  • Dear Thomas,

    Basically, the code looks good.

    I have made a similar Multicast Demo myself and when looking at the code the only difference is that I have used two separate sockets for RX and TX. I also used select().

    So just as a work-around, you can use two separate sockets and test.

    In addition, please pay attention that the structure sntpSocketAddr is filled in the case of recvfrom() so you need to re-initialize it when using sendto() again. 

    Of course, there may still be a bug here when trying to use RX and TX on the same UDP socket when one side is a Multicast.

    Just for the test, can you switch places between RX and TX by trying to receive and only then transmit (and if it succeeds, try to receive again)?

    Thanks,

    Shlomi