---
title: "[W5300] recv함수의 반환값이 어떻게 되나요?"
url: "https://maker.wiznet.io/forum/12310"
markdown_url: "https://maker.wiznet.io/forum/12310/md"
type: "Forum topic"
category: "Ethernet Chips"
author: "Seongwook Yoon"
created: "2017-05-31T00:54:44+09:00"
last_activity: "2017-06-09T13:31:32+09:00"
language: "ko"
views: 3564
replies: 5
source: "WIZnet Makers forum (https://maker.wiznet.io/forum/)"
---

# [W5300] recv함수의 반환값이 어떻게 되나요?

## Question

Asked by Seongwook Yoon on 2017-05-31 in Ethernet Chips.

W5300제품을 사용중에 의문사항이 들어 질문 드립니다.
socket.c 파일의 uint32 recv(SOCKET s, uint8 * buf, uint32 len)함수의 반환값이 어떻게 되는지요?

예를들어
getSn_RX_RSR(s)의 반환값이 38일때
recv(s, rx_buff, len)를 호출하면 36을 반환합니다.

getSn_RX_RSR(s)한 값과 recv()했을때 반환하는 값이 같을것이라 기대했는데
실제로 recv한 값이 2바이트 작습니다.

예상되는 바로는
getSn_RX_RSR(s)한 값에는 ‘/r’ '/n’이 포함 된 길이고
recv는 ‘/r’ '/n’이 빠진 길이라고 생각하는데 맞는건지 궁금합니다.

## Replies

### Reply 1 by Kei, 2017-05-31

참조하신 socket.c 파일은,
아래 Github의 ioLibrary를 참조하신 것인가요?

[github.com](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/socket.c)

#### [Wiznet/ioLibrary_Driver/blob/master/Ethernet/socket.c](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/socket.c)

```
//*****************************************************************************
//
//! \file socket.c
//! \brief SOCKET APIs Implements file.
//! \details SOCKET APIs like as Berkeley Socket APIs. 
//! \version 1.0.3
//! \date 2013/10/21
//! \par  Revision history
//!       <2015/02/05> Notice
//!        The version history is not updated after this point.
//!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
//!        >> https://github.com/Wiznet/ioLibrary_Driver
//!       <2014/05/01> V1.0.3. Refer to M20140501
//!         1. Implicit type casting -> Explicit type casting.
//!         2. replace 0x01 with PACK_REMAINED in recvfrom()
//!         3. Validation a destination ip in connect() & sendto(): 
//!            It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
//!            Copy 4 byte addr value into temporary uint32 variable and then compares it.
//!       <2013/12/20> V1.0.2 Refer to M20131220
//!                    Remove Warning.
```

This file has been truncated. [show original](https://github.com/Wiznet/ioLibrary_Driver/blob/master/Ethernet/socket.c)

recv() 함수의 리턴값은 파라미터로 받은 len의 값입니다.
(len이 RX레지스터의 최대 크기를 넘어간다면, 최대 크기만큼으로 변경됩니다)
추가로, W5300의 경우, 아래 코드로 인해 len값이 변경될 수 있습니다.

```
if(len > sock_remained_size[sn]) len = sock_remained_size[sn];
```

참조하시는 드라이버가 어떤 것인지 언급해주시면,
보다 정확한 답변이 가능하겠습니다.

### Reply 2 by Seongwook Yoon, 2017-05-31

인수인계 받은거라 정확히 어떤 라이브러리를 사용했는지 알 수 없으나 아래 정보로 확인이 가능하실까요…?

socket.c 파일 상단 주석 내용과 recv함수를 첨부하겠습니다.

socket.c 파일 상단 주석은 다음과 같습니다.

```
/**
 * \file    socket.c
 *   Implemetation of WIZnet SOCKET API fucntions
 *
 * This file implements the WIZnet SOCKET API functions that is used in your internat application program.
 * 
 * Revision History :
 * ----------  -------  -----------  ----------------------------
 * Date        Version  Author       Description
 * ----------  -------  -----------  ----------------------------
 * 24/03/2008  1.0.0    MidnightCow  Release with W5300 launching
 * ----------  -------  -----------  ----------------------------
 * 15/05/2008  1.1.0    MidnightCow  Refer to M_15052008.
 *                                   Modify the warning code block in recv(). 
 * ----------  -------  -----------  ---------------------------- 
 * 04/07/2008  1.1.1    MidnightCow  Refer to M_04072008.
 *                                   Modify the warning code block in recv(). 
 * ----------  -------  -----------  ---------------------------- 
 * 08/08/2008  1.2.0    MidnightCow  Refer to M_08082008.
 *                                   Modify close(). 
 * ----------  -------  -----------  ---------------------------- 
 * 11/25/2008  1.2.1    Bongjun      Refer to M_11252008.
 *                                   Modify close().
 * ----------  -------  -----------  ----------------------------  
 * 15/03/2012  1.2.2    Dongeun      Modify a ARP error.
 *                                   Modify connect() & sendto()
 * ----------  -------  -----------  ----------------------------  
 * 12/07/2012  1.2.3    Dongeun      Modify a ARP error.
 *                                   Modify connect() & sendto()
 * ----------  -------  -----------  ---------------------------- 
 * 16/05/2013  1.2.4    Dongeun      Fixed bug. ( when data received, 1byte data is crashed ) 
 *
 * ----------  -------  -----------  ---------------------------- 
 * 28/07/2014  1.2.5    Eunkyoung    Modify a ARP error.
 *                                   Modify connect() & sendto()
 * ----------  -------  -----------  ---------------------------- 
 */
```

또한, 사용한 recv함수는 다음과 같이 정의 되 있습니다.

```
uint32   recv(SOCKET s, uint8 * buf, uint32 len)
{
   uint16 pack_size=0;
   uint16 mr = getMR();							// added 20130516 Fixed bug. (when data received, 1byte data is crashed)
   
   #ifdef __DEF_IINCHIP_DBG__
      printf("%d : recv()\r\n",s);
   #endif
   
   if(IINCHIP_READ(Sn_MR(s)) & Sn_MR_ALIGN) 
   {
      wiz_read_buf(s, buf, (uint32)len);
      setSn_CR(s,Sn_CR_RECV);
      return len;
   }
   

   wiz_read_buf(s,(uint8*)&pack_size,2);        // extract the PACKET-INFO(DATA packet length)
   
   //if( (*(vint16*)MR) & MR_FS )				// Modified 20130516 Fixed bug. (when data received, 1byte data is crashed)
   if( mr & MR_FS )
      pack_size = ((((pack_size << 8 ) & 0xFF00)) | ((pack_size >> 8)& 0x00FF));
   
   #ifdef __DEF_IINCHIP_DBG__   
      printf("%d:pack_size=%d\r\n",s,pack_size);
   #endif

   wiz_read_buf(s, buf, (uint32)pack_size);     // copy data   
   
   setSn_CR(s,Sn_CR_RECV);                      // recv
   
   /*
   * \warning  send a packet for updating window size. This code block must be only used when W5300 do only receiving data.
   */
   // ------------------------
   // WARNING CODE BLOCK START 
   
   // M_15052008 : Replace Sn_CR_SEND with Sn_CR_SEND_KEEP.
   //if(!(getSn_IR(s) & Sn_IR_SENDOK))
   //{
   //   setSn_TX_WRSR(s,0);                    // size = 0
   //   setSn_CR(s,Sn_CR_SEND);                // send
   //   while(!(getSn_IR(s) & Sn_IR_SENDOK));  // wait SEND command completion
   //   setSn_IR(s,Sn_IR_SENDOK);              // clear Sn_IR_SENDOK bit
   //}
   
   // M_04072008 : Replace Sn_CR_SEND_KEP with Sn_CR_SEND.
   //if(getSn_RX_RSR(s) == 0)                     // send the window-update packet when the window size is full
   //{
   //   uint8 keep_time = 0;
   //   if((keep_time=getSn_KPALVTR(s)) != 0x00) setSn_KPALVTR(s,0x00); // disables the auto-keep-alive-process
   //   setSn_CR(s,Sn_CR_SEND_KEEP);              // send a keep-alive packet by command
   //   setSn_KPALVTR(s,keep_time);               // restore the previous keep-alive-timer value
   //}
   #if 0
   if(getSn_RX_RSR(s) == 0)                     // check if the window size is full or not
   { /* Sn_RX_RSR can be compared with another value instead of n0o,
      according to the host performance of receiving data */
      setSn_TX_WRSR(s,1);                       // size : 1 byte dummy size
      IINCHIP_WRITE(Sn_TX_FIFOR(s),0x0000);     // write dummy data into tx memory
      setSn_CR(s,Sn_CR_SEND);                   // send                         
      while(!(getSn_IR(s) & Sn_IR_SENDOK));     // wait SEND command completion 
      setSn_IR(s,Sn_IR_SENDOK);                 // clear Sn_IR_SENDOK bit       
   }    
   #endif                                                                        
   // WARNING CODE BLOCK END
   // ----------------------
   
   return (uint32)pack_size;
}
```

### Reply 3 by irina, 2017-05-31

안녕하세요.

Seongwook_Yoon:

> socket.c 파일의 uint32 recv(SOCKET s, uint8 * buf, uint32 len)함수의 반환값이 어떻게 되는지요?
>
> 예를들어
> getSn_RX_RSR(s)의 반환값이 38일때
> recv(s, rx_buff, len)를 호출하면 36을 반환합니다.
>
> getSn_RX_RSR(s)한 값과 recv()했을때 반환하는 값이 같을것이라 기대했는데
> 실제로 recv한 값이 2바이트 작습니다.

언급하신 부분의 경우, 정상적인 상황입니다.
W5300 칩의 데이터 수신 시, 수신된 TCP 데이터는 다음과 같이 구성되어 있습니다.

1. Sn_MR(ALIGN) = ‘0’ 일 경우

- **2-bytes Packet-info(payload length) + Payload (data)**

1. Sn_MR(ALIGN) = ‘1’ 일 경우

- **Payload only**

따라서, getSn_RX_RSR(s) 함수가 리턴하는 hardware rx socket buffer에 수신된 데이터의 길이와 recv() 함수를 통해 수신된 실제 데이터의 길이는 packet-info header의 유무에 따라 차이가 있을 수 있으며 recv() 함수의 리턴 값을 수신 데이터 길이로 보시면 됩니다.

다음 W5300 제품 페이지 링크 내 Datasheet p.97의 **TCP 데이터 수신 프로세스**에 관한 내용을 참고 부탁 드립니다.

<http://www.wiznet.io/ko/product-item/w5300/>

### Reply 4 by Seongwook Yoon, 2017-06-01 (in reply to reply 3)

감사합니다.
덕분에 잘 이해됐습니다 ^^
혹시 getSn_RX_RSR(s)의 반환값과 recv(s, rx_buff, len)의 반환값이 2의 배수 바이트 만큼 차이가 나는게 아니라 3바이트가 차이나는 경우는 어떻게 이해하면 될지요~??

만약 4바이트 차이가 난다면 2개의 패킷을 수신 한 경우로 PACKT-INFO가 2Byte * 2개 패킷 해서 4바이트 차이가 날 수있을 것 같은데, 3바이트 차이가 나는 경우가 발생하고 있습니다.
이럴 경우에는 어떤 문제를 의심해봐야 할까요~??

### Reply 5 by irina, 2017-06-02

Seongwook_Yoon:

> getSn_RX_RSR(s)의 반환값과 recv(s, rx_buff, len)의 반환값이 2의 배수 바이트 만큼 차이가 나는게 아니라 3바이트가 차이나는 경우는 어떻게 이해하면 될지요~??

먼저 실제 송/수신한 데이터에 오차가 있는지, 있다면 데이터의 어떤 부분에 누락이 있는지 확인 하는 것이 우선 일 것 같습니다.

그리고 드라이버 단의 처리를 점검해보면 좋을 것 같습니다.

비교 해 보시고, 송수신 데이터를 함께 답글에 보여주시면 원인 파악에 도움이 될 듯 싶네요.

---

Source: https://maker.wiznet.io/forum/12310
