title: recvfrom() hangs when I try to get time from NTP server
body: <p>I'm currently figuring out why my recvfrom() doesn't return anything.
  I've suspected whether socket or NTP Ip address is wrong, but both seems right so far.</p>
  <p>The following is the code:</p>
  <pre><code>    int sntp_client(ST_VOID)
  
  {
      struct sockaddr_in saddr, myaddr;
      struct timeval tv, tp;
      int sntp_fd=-1;
      int len;
      unsigned int pkt_len;
      fd_set readfds;
      ST_CHAR hostname[16];
  
      sprintf(&amp;hostname[0], &quot;%d.%d.%d.%d&quot;, SNTP_IP.m_dsIPAddr.m_u8IP[0], SNTP_IP.m_dsIPAddr.m_u8IP[1]
                                  , SNTP_IP.m_dsIPAddr.m_u8IP[2], SNTP_IP.m_dsIPAddr.m_u8IP[3]);
  
      // sntp ip 가 0.0.0.0 즉, 설정되지 않으면 시각동기를 하지 않는다.
      if(!strcmp(hostname, &quot;0.0.0.0&quot;))
      {
          printf(&quot;host ip error - 0.0.0.0\n&quot;);
          return -1;
      }
    
      // sntp 서버 ip 가져오기
      if((len = strlen(hostname)) &lt;= 0)
      {
          printf(&quot;sntp : get host name error\n&quot;);
          return -1;
      }
  
    
      // socket 생성
      bzero((char *)&amp;saddr, sizeof(saddr)); 
      saddr.sin_family = AF_INET;
      saddr.sin_port   = htons(SNTP_SPORT);
      saddr.sin_addr.s_addr = inet_addr(hostname);
  
      if((sntp_fd = socket(AF_INET, SOCK_DGRAM, 0)) &lt; 0)
      {
          printf(&quot;sntp make socket error\n&quot;);
          return(sntp_fd);
      }
    
      bzero((char *)&amp;myaddr, sizeof(myaddr)); 
      myaddr.sin_family = AF_INET;
      myaddr.sin_port = htons(3030); 
      myaddr.sin_addr.s_addr = INADDR_ANY;
    
      if(bind(sntp_fd, (struct sockaddr *)&amp;myaddr, sizeof(myaddr)) &lt; 0) 
      {
          printf(&quot;sntp bind socket error\n&quot;);
          
          close(sntp_fd);
          return -1;
      }
  
      /* Fill in the request packet */
      bzero((char *)&amp;pkt, sizeof pkt);
  
  
      // 서우현 박사에 의하면 client에서 txtime을 0으로 셋팅하면 sntp 규격에 어긋나므로 
      // IED의 현재 시간을 넣는다. 
      gettimeofday(&amp;tp, NULL);
  
      pkt.txtime[0] = tp.tv_sec + JAN_1970;
      pkt.txtime[1] = tp.tv_usec * 4295;          
  
      
      pkt.livnmode = 0x1b;        /* version 1, mode 3 (client) */
  
   
      // send request packet to server
      if((len=sendto(sntp_fd, (char *)&amp;pkt, sizeof(pkt), 0, 
                      (struct sockaddr *)&amp;saddr, sizeof(saddr))) != sizeof(pkt))
      {
          printf(&quot;sntp service sendto() error\n&quot;);
          
          close(sntp_fd);
          return -1; 
      }
    
      //read reply packet from server
      pkt_len = sizeof(pkt);
  
  
      // montavistadpsms FD_ZERO가 꼭 있어야 한다. 
      FD_ZERO(&amp;readfds);
      FD_SET(sntp_fd, &amp;readfds);  // FD_SET 메크로 사용
      tv.tv_sec = 1;
      tv.tv_usec = 0;
  
      // select는 이벤트가 발생하기 전까지 block(대기)
      if(select(sntp_fd+1, &amp;readfds, NULL, NULL, &amp;tv)) 
      {
          if((len = recvfrom(sntp_fd, (char *)&amp;pkt, sizeof(pkt), 0,
                                  (struct sockaddr *)&amp;saddr, &amp;pkt_len)) != sizeof(pkt))
          {
              printf(&quot;sntp service recvfrom error\n&quot;);
              
              close(sntp_fd);
              return -1; 
          }
      }
      else
      {
          //perror(&quot;ntp : select timeout\n&quot;);
          close(sntp_fd);
          return -1; 
      }
  
  
      // diebu add - 2019.12.31.
      // livnmode는 leap indicator(2bit) + version number(3bit) + mode (3bit) 이다. 
      // 여기서 leap indicator가 synchronize에 관련된다.
      // 정상 : 0x8A, ClockFailure : 0x4A, ClockNotSynchronize : 0x2A
      if((pkt.livnmode &amp; 0xC0) == 0x00)
      {
          SntpTimeQuality = SNTP_TIME_GOOD;
      }
      else
      {
          // diebu modified - 2020.05.15. : SNTP_CLOCK_NOT_SYNCHRONIZED -&gt; SNTP_CLOCK_FAILURE
          // 시각동기는 됬지만, synch가 맞지 않음 - clock not synchronized 
          // GPS등과 연결이 안된 시간을 의미..
          SntpTimeQuality = SNTP_CLOCK_FAILURE;
      }
      
  
      // STB는 UTC 시간 그대로 받는다.
      tv.tv_sec = ntohl(pkt.txtime[0]) - JAN_1970;
      tv.tv_usec = ntohl(pkt.txtime[1]/4295);         //  --&gt; usec을 만들기 위해 
      
      settimeofday(&amp;tv, NULL);
      
      if(sntp_fd &gt; 0)
          close(sntp_fd);
  
      return SD_TRUE;
  }
  </code></pre>
  <p>As you can see in the code, I'm skipping the part by calling select() function.
  However, I'd like to get the NTP time to synchronize.</p>
  <p>I'm using the following pkt struct</p>
  <pre><code>struct 
  {
      unsigned char livnmode, stratum, poll, prec;
      unsigned long delay, disp, refid;
      unsigned long reftime[2], origtime[2], rcvtime[2], txtime[2];
  }pkt;
  </code></pre>
  <p>And I'm using '203.248.240.140' as the NTP server.</p>
  <p>It'd be great if any network guru can help me out!!</p>