WIZnet Developer Forum

UDP sendto 에서 상대 IP가

UDP는 send to를 사용할때요…

dest IP가 정상적인 상태일때는 상관이 없습니다.
dest IP가 통신을 안하고 있을때 (전원이 꺼져있을경우)

sendto 에서 시간이 걸린다는겁니다.
TCP도 아니고
UDP에서 TimeOut으로 처리가 된다는것이
이상합니다.

PC에선 전혀 문제가 없는 부분인데…
장비에서 문제가 발생하네요.

W5300에서 Sn_IR_SENDOK 가 보낸것을 확인하느것이 아니라. 상대가 받은 것을 확인하는것이라
생각이 드네요.

TCP처럼 UDP에서도 timeout을 설정해서 처리해야 하는것인지
아니면 아래 소스가 잘못된 것인지 부탁드립니다.

uint32   sendto(SOCKET s, uint8 * buf, uint32 len, uint8 * addr, uint16 port)
{
   uint8 status=0;
   uint8 isr=0;
   uint32 ret=0;
   
   #ifdef __DEF_IINCHIP_DBG__
      printf("%d : sendto():%d.%d.%d.%d(%d), len=%d\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
   #endif
      
   if
   (
      ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
      ((port == 0x00)) ||(len == 0)
   ) 
   {
      #ifdef __DEF_IINCHIP_DBG__
         printf("%d : Fail[%d.%d.%d.%d, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
      #endif
      return 0;
   }
   
   
   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
   else ret = len;
   
   // set destination IP address
   IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
   IINCHIP_WRITE(Sn_DIPR1(s),addr[1]);
   IINCHIP_WRITE(Sn_DIPR2(s),addr[2]);
   IINCHIP_WRITE(Sn_DIPR3(s),addr[3]);
   // set destination port number
   IINCHIP_WRITE(Sn_DPORTR0(s),((uint8)(port >> 8)));
   IINCHIP_WRITE(Sn_DPORTR1(s),((uint8)(port & 0xff)));

   wiz_write_buf(s, buf, ret+(ret & 0x01));                               // copy data
   // send
   setSn_TX_WRSR(s,ret);
   setSn_CR(s, Sn_CR_SEND);
   
   while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK))            // wait SEND command completion
   {
      status = getSn_SSR(s);                                // warning ---------------------------------------
      if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT)) // Sn_IR_TIMEOUT causes the decrement of Sn_TX_FSR
      {                                                     // -----------------------------------------------
         #ifdef __DEF_IINCHIP_DBG__
            printf("%d: send fail.status=0x%02x,isr=%02x\r\n",s,status,isr);
         #endif
         setSn_IR(s,Sn_IR_TIMEOUT);
         return 0;
      }
   }
   setSn_IR(s, Sn_IR_SENDOK); // Clear Sn_IR_SENDOK
   
   #ifdef __DEF_IINCHIP_DBG__           
      printf("%d : send()end\r\n",s);
   #endif       
   
   return ret;   
}

좋은 답변 또는 의견 부탁드립니다.

안녕하세요

UDP의 경우 상대방의 응답을 확인하지 않습니다.

다만 나타나는 증상을 보니

UDP send전에 ARP하는 과정에서 상대방의 응답이 없기 때문에 ARP Timeout이 발생하는 것 같습니다.

만약 ARP과정을 생략하고 UDP전송을 원하시면

SEND_MAC 이라는 커맨드가 있습니다.

이를 활용하셔서 UDP를 전송하시면 됩니다.

SEND_MAC을 사용하실 경우 상대방의 MAC주소는 미리 Sn_DHAR Register에 저장해주셔야 합니다.

해당 W5300 Datasheet는 다음 링크를 확인하세요

http://www.wiznet.io/product-item/w5300/

감사합니다.

lawrence

한국어 포럼으로 이동하였습니다.

답변 감사합니다.

MAC을 알아서 처리하는 방법은 아닌것 같고요.

결국은 Timeout으로 처리하든
해야 겠네요…

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.