본문 바로가기

지식/Network

recv 함수

recv

 

recv 함수는 접속되어 있는 소켓으로부터 들어오는 데이터를 수신하는 함수입니다.

 

int recv (
        SOCKET   s,
        char FAR*   buf,
        int   len,
        int   flags
);

 

Parameters

s
[입력] 접속된 소켓을 명시하는 기술자(descriptor)입니다.

buf
[출력] 수신받은 데이터를 저장할 버퍼입니다.

len
[입력] 버퍼의 길이를 명시합니다.

flags
[입력]
recv 함수의 기본작업(수신받은 데이터를 큐에서 읽어내고 제거하는 작업)이 아닌 다른 작업을 하게 하기 위해 이 플래그를 설정합니다.

 

Remarks

recv 함수는 접속 지향형 소켓(connection-oriented socket)이나 비접속 지향형 소켓(connectionless socket)에서 수신되는 데이터를 읽기위해 사용됩니다. 접속지향형 프로토콜(connection-oriented protocol)을 사용 할 때, 소켓은 recv 함수를 호출하기 전에 미리 접속된 상태여야 합니다. 비접속 프로토콜(connectionless protocol)을 사용 할 경우, 소켓은 recv 함수를 호출하기 전에 미리 바인드 되어 있어야 합니다.

이 함수를 쓰기 전에, 소켓의 로컬 어드레스를 알아내야 하는데요. 서버 어플리케이션에서는 명시적인(explicit) bind 함수나 accept 또는 WSAAccept 함수를 사용해서 알아 냅니다. 이러한 명시적인(explicit) 바인딩을 클라이언트 어플리케이션에서 사용했을 때 좋지 않은 결과를 낼 수 있습니다. 클라이언트 어플리케이션을 위해, 소켓은 connect, WSAConnect, sendto, WSASendTo, 또는 WSAJoinLeaf 함수를 이용해서 묵시적으로 로컬 어드레스를 바인드 할 수 있습니다.

접속된 또는 접속되지 않은 소켓에 대해서 이 함수는 수신된 메시지가 허용된 곳으로 부터의 어드레스를 제한합니다. 이 함수는 명시된 원격지 주소로부터 메시지를 반환하기만 합니다. 다른 주소들로 부터의 메시지는 (살며시?) 버립니다. (해석이 넘 이상 합니다... 아래에 원문을 첨가 하도록 하겠습니다. 지성~)

<원문내용>
For connected or connectionless sockets, this function restricts the addresses from which received messages are accepted. The function only returns messages from the remote address specified in the connection. Messages from other addresses are (silently) discarded

접속 지향형 소켓(connection-oriented socket : ex:SOCK_STREAM)일 경우에, recv 함수는 이용 가능한 많은 정보를 반환 할 것입니다. 만약 아직 읽혀지지 않은 out-of-band 데이터가 남아있고, 소켓이 out-of-band 데이터의 인라인 수신을 할 수 있다면(이럴 경우 소켓옵션이 SO_OOBINLINE으로 설정되어 있어야 겠죠?), out-of-band 데이터는 읽여질 것입니다. 어플리케이션은 더 읽기위해 남아있는 out-of-band 데이터가 있는지 없는지 확인하기 위해 ioctlsocket 이나 WSAloctl의 SIOCATMARK 컴맨드를 사용 할 수 있습니다.

비접속 소켓(connectionless sockets : ex. SOCK_DGRAM 또는 다른 메시지 지향형 소켓(message-oriented sockets))일 경우 데이터는 connect 함수에 의해서 명시된 목적 어드레스로부터 날라온, 메시지 큐에 쌓여진 데이터그램중 첫 번째 데이터그램을 읽어냅니다.

데이터 그램이나 메시지가 지정된 버퍼 크기보다 더 클 경우에는 데이터그램의 첫 번째 부분부터 채워지고, recv 함수는 WSAEMSGSIZE 라는 에러코드를 발생시킵니다. UDP 와 같이 데이터의 신뢰성을 보장할 수 없는 프로토콜의 경우 초과된 데이터는 손실되게 됩니다. TCP와 같이 신뢰할 수 있는 프로토콜의 경우 데이터는 충분히 큰 버퍼를 가지고 recv 함수가 성공적으로 수행 될 때 까지 서비스 프로바이더에 의해서 남겨지게 됩니다.

만약 수신할 데이터가 없게되면, recv 함수는 수신할 데이터가 들어 올 때까지 블록킹 상태에 걸립니다.

소켓이 접속지향형(connected oriented) 이고 원격지 지점에서 접속이 셧다운(우아한(gracefully) 종료) 되어 버리고, 현재 그 원격지에서 보낸 데이터를 수신되고 있는 상태라면, recv 함수는 데이터를 하나도 받지 못한 상태에서 동작을 완료합니다. 접속이 리셋 되어 버린 경우엔 WSAECONNRESET 이라는 에러코드를 발생하며 함수의 수행은 실패 하게 됩니다.

flag 매개변수는 소켓에 대해 명시된 옵션 이상의 함수동작에 영향을 미치기 위해서 사용될 수 있습니다. 함수의 의미체계는 소켓옵션 그리고, flag 매개변수에 의해서 결정되어 집니다. flag 매개변수를 이용한 방법의 경우 아래의 값을 OR 비트연산을 취해서 구성되어 집니다. 즉, 쉽게 말해서 recv 함수가 기본적으로 수행하는 수신된 데이터를 일고 수신큐에서 제거하는 일 이외의 원하는 다른 처리를 할 수 있도록 하는 플래그 라는 의미입니다.

 

Value Meaning
MSG_PEEK

MSG_PEEK 플래그는 수신큐에 있는 데이터를 읽기만 하는 작업을 하게

합니다. 데이터는 단지 읽어서 특정한 버퍼로 복사가 가능하지만,

수신 큐에 있는 데이터를 제거하지는 않습니다.

MSG_OOB MSG_OOB 플래그는 out-of-band 데이터의 처리에 사용됩니다.

 

Return Values

에러가 발생하지 않으면, recv 함수는 읽혀진 데이터의 바이트 수를 반환 합니다. 만약 접속이 종료(우아한종료) 되었다면, 0을 반환 하게 됩니다. 에러가 발생한 경우 SOCK_ERROR 값이 반환 되며, WSAGetLastError 함수를 이용해 특정한 에러 코드를 얻을 수 있습니다.

 

Error Codes

WSANOTINITIALISED

이 함수를 사용하기 전에 성공적인 WSAStartup

함수의 호출이 없었습니다.

WSAENETDOWN 네트웍 서브 시스템에 에러가 발생했습니다.
WSAEFAULT buf 매개변수가 제대로 된 형태가 아닙니다.
WSAENOTCONN 소켓이 접속된 상태가 아닙니다.
WSAEINTR

블록킹 호출이 WSACancelBlockingCall 함수에서

취소되었습니다.

WSAEINPROGRESS

블럭킹 윈속 v1.1 이 현재 진행 중이거나, 서비스

프로바이더가 콜백 함수를 여전히 처리하고 있습니다.

WSAENETRESET 연산이 진행되고 있는 도중 접속이 끊겨버렸습니다.
WSAENOTSOCK 기술자(descriptor)가 소켓이 아닙니다.
WSAEOPNOTSUPP

MSG_OOB 가 명시되었지만, 소켓은 SOCK_STREAM 과

같은 형태의 스트림 형태가 아닙니다.

WSAESHUTDOWN 소켓이 셧다운 되었습니다.
WSAEWOULDBLOCK

소켓이 넌블록킹(비동기)로 마킹되어 있고, 수신 연산이

블록킹 상태입니다.

WSAEMSGSIZE

수신된 메시지가 지정된 버퍼에 저장하기에 너무 커서

손실 되었습니다.

WSAEINVAL

소켓이 bind 함수에 의해서 바인드 되지 않았거나, 알 수

없는 플래그가 사용되었거나, SO_OOBINLINE 옵션을

가능하게 한 상태 에서 MSG_OOB 플래그가 소켓에 대해서

명시되었습니다. 또는 len 매개변수가 0 이거나 0보다 작습니다.

WSAECONNABORTED

가상 연결 회로망이 타임아웃이나 다른 실패 때문에 끊어져

버렸습니다.

WSAETIMEDOUT

접속이 네트웍 실패나 상대방 시스템의 응답 실패로 인하여

드랍 되어 버렸습니다.

WSAECONNRESET

가상 회로망이 원격지에서 "hard"나 "abortive" 종료를 수행해서

리셋되었습니다.

 

QuickInfo

Windows NT : 사용가능
Windows : 사용가능
Windows CE : 버젼 1.0 그리고 그이후의 버젼에서 사용가능
Header :
          Win16/32 : winsock.h
          Win32-II : winsock2.h
Import Library :
          Win16 : winsock.lib
          Win32 : wsock32.lib
          Win32-II : ws2_32.lib

See Also

overview, recvfrom, select, send, socket, WSAAsyncSelect, WSARecvEx