recv 함수(winsock.h)

recv 함수는 연결된 소켓 또는 바인딩된 연결 없는 소켓에서 데이터를 수신합니다.

구문

int recv(
  [in]  SOCKET s,
  [out] char   *buf,
  [in]  int    len,
  [in]  int    flags
);

매개 변수

[in] s

연결된 소켓을 식별하는 설명자입니다.

[out] buf

들어오는 데이터를 수신할 버퍼에 대한 포인터입니다.

[in] len

buf 매개 변수가 가리키는 버퍼의 길이(바이트)입니다.

[in] flags

이 함수의 동작에 영향을 주는 플래그 집합입니다. 아래 설명 부분을 참조하세요. 이 매개 변수의 가능한 값에 대한 자세한 내용은 설명 섹션을 참조하세요.

반환 값

오류가 발생하지 않으면 recv 는 수신된 바이트 수를 반환하고 buf 매개 변수가 가리키는 버퍼에는 수신된 이 데이터가 포함됩니다. 연결이 정상적으로 닫힌 경우 반환 값은 0입니다.

그렇지 않으면 SOCKET_ERROR 값이 반환되고 WSAGetLastError를 호출하여 특정 오류 코드를 검색할 수 있습니다.

오류 코드 의미
WSANOTINITIALISED
이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다.
WSAENETDOWN
네트워크 하위 시스템이 실패했습니다.
WSAEFAULT
buf 매개 변수가 사용자 주소 공간의 유효한 부분에 완전히 포함되지는 않습니다.
WSAENOTCONN
소켓이 연결되지 않았습니다.
WSAEINTR
(차단) 호출이 WSACancelBlockingCall을 통해 취소되었습니다.
WSAEINPROGRESS
차단 Windows Sockets 1.1 호출이 진행 중이거나 서비스 공급자가 여전히 콜백 함수를 처리하고 있습니다.
WSAENETRESET
연결 지향 소켓의 경우 이 오류는 작업이 진행되는 동안 오류를 감지한 연결 유지 작업으로 인해 연결이 끊어졌는지 나타냅니다. 데이터그램 소켓의 경우 이 오류는 TTL(Time to Live)이 만료되었음을 나타냅니다.
WSAENOTSOCK
설명자가 소켓이 아닙니다.
WSAEOPNOTSUPP
MSG_OOB 지정되었지만 소켓이 SOCK_STREAM 형식과 같은 스트림 스타일이 아니거나, OOB 데이터가 이 소켓과 연결된 통신 도메인에서 지원되지 않거나, 소켓이 단방향이며 보내기 작업만 지원합니다.
WSAESHUTDOWN
소켓이 종료되었습니다. SD_RECEIVE 또는 SD_BOTH 설정된 방법을 사용하여 종료가 호출된 후에는 소켓에서 수신할 수 없습니다.
WSAEWOULDBLOCK
소켓이 차단되지 않는 것으로 표시되고 수신 작업이 차단됩니다.
WSAEMSGSIZE
메시지가 너무 커서 지정된 버퍼에 맞지 않아 잘렸습니다.
WSAEINVAL
소켓이 바인딩된 상태로 바인딩되지 않았거나 알 수 없는 플래그가 지정되었거나 SO_OOBINLINE 사용하도록 설정된 소켓에 대해 MSG_OOB 지정되었거나(바이트 스트림 소켓에만 해당) len 이 0 또는 음수였습니다.
WSAECONNABORTED
가상 회로가 시간 초과 또는 기타 오류로 인해 종료되었습니다. 더 이상 소켓을 사용할 수 없으므로 응용 프로그램이 소켓을 닫아야 합니다.
WSAETIMEDOUT
네트워크 오류로 인해 또는 피어 시스템이 응답하지 않기 때문에 연결이 삭제되었습니다.
WSAECONNRESET
가상 회로가 하드 또는 중단한 닫기를 실행하는 원격 쪽에서 재설정되었습니다. 더 이상 소켓을 사용할 수 없으므로 응용 프로그램이 소켓을 닫아야 합니다. UDP-datagram 소켓에서 이 오류는 이전 보내기 작업으로 인해 ICMP "포트 연결할 수 없음" 메시지가 발생했음을 나타냅니다.

설명

recv 함수는 연결 지향 소켓 또는 연결 없는 소켓에서 들어오는 데이터를 읽는 데 사용됩니다. 연결 지향 프로토콜을 사용하는 경우 recv를 호출하기 전에 소켓을 연결해야 합니다. 연결 없는 프로토콜을 사용하는 경우 recv를 호출하기 전에 소켓을 바인딩해야 합니다.

소켓의 로컬 주소를 알고 있어야 합니다. 서버 애플리케이션의 경우 명시적 바인딩 함수 또는 암시적 accept 또는 WSAAccept 함수를 사용합니다. 명시적 바인딩은 클라이언트 애플리케이션에 권장되지 않습니다. 클라이언트 애플리케이션의 경우 connect, WSAConnect, sendto, WSASendTo 또는 WSAJoinLeaf를 사용하여 소켓을 로컬 주소에 암시적으로 바인딩할 수 있습니다.

연결된 소켓 또는 연결 없는 소켓의 경우 recv 함수는 수신된 메시지가 허용되는 주소를 제한합니다. 함수는 연결에 지정된 원격 주소의 메시지만 반환합니다. 다른 주소의 메시지는 (자동으로) 삭제됩니다.

연결 지향 소켓(예: SOCK_STREAM 형식)의 경우 recv 를 호출하면 지정된 버퍼 크기까지 현재 사용 가능한 만큼의 데이터가 반환됩니다. 소켓이 OOB 데이터(소켓 옵션 SO_OOBINLINE)의 인라인 수신을 위해 구성되었으며 OOB 데이터가 아직 읽지 않은 경우 OOB 데이터만 반환됩니다. 애플리케이션은 ioctlsocket 또는 WSAIoctlSIOCATMARK 명령을 사용하여 더 많은 OOB 데이터를 읽을 수 있는지 여부를 확인할 수 있습니다.

연결 없는 소켓(SOCK_DGRAM 또는 기타 메시지 지향 소켓 유형)의 경우 연결 함수에서 지정한 대상 주소에서 큐에 추가된 첫 번째 데이터그램(메시지)에서 데이터가 추출됩니다.

데이터그램 또는 메시지가 지정된 버퍼보다 큰 경우 버퍼는 데이터그램의 첫 번째 부분으로 채워지고 recvWSAEMSGSIZE 오류를 생성합니다. 신뢰할 수 없는 프로토콜(예: UDP)의 경우 초과 데이터가 손실됩니다. 신뢰할 수 있는 프로토콜의 경우 충분한 버퍼가 있는 recv 를 호출하여 데이터를 성공적으로 읽을 때까지 서비스 공급자가 데이터를 보존합니다.

소켓에서 들어오는 데이터를 사용할 수 없는 경우 recv 호출은 소켓이 차단되지 않는 한 MSG_PARTIAL 플래그가 설정되지 않은 WSARecv 에 정의된 차단 규칙에 따라 데이터가 도착할 때까지 차단하고 기다립니다. 이 경우 오류 코드가 WSAEWOULDBLOCK으로 설정된 SOCKET_ERROR 값이 반환됩니다. select, WSAAsyncSelect 또는 WSAEventSelect 함수를 사용하여 더 많은 데이터가 도착하는 시기를 확인할 수 있습니다.

소켓이 연결 지향적이며 원격 쪽에서 정상적으로 연결을 종료하고 모든 데이터를 받은 경우 0바이트가 수신된 즉시 recv 가 완료됩니다. 연결이 다시 설정되면 WSAECONNRESET 오류와 함께 recv가 실패합니다.

flags 매개 변수를 사용하여 연결된 소켓에 대해 지정된 옵션 외에 함수 호출의 동작에 영향을 줄 수 있습니다. 이 함수의 의미 체계는 소켓 옵션 및 flags 매개 변수에 의해 결정됩니다. flags 매개 변수의 가능한 값은 다음 값과 함께 비트 OR 연산자를 사용하여 생성됩니다.

의미
MSG_PEEK 들어오는 데이터를 피킹합니다. 데이터는 버퍼에 복사되지만 입력 큐에서 제거되지는 않습니다.
MSG_OOB OOB(대역 외) 데이터를 처리합니다.
MSG_WAITALL 수신 요청은 다음 이벤트 중 하나가 발생하는 경우에만 완료됩니다.
  • 호출자가 제공하는 버퍼가 완전히 가득 찼습니다.
  • 연결이 닫혔습니다.
  • 요청이 취소되었거나 오류가 발생했습니다.
기본 전송이 MSG_WAITALL 지원하지 않거나 소켓이 비차단 모드인 경우 WSAEOPNOTSUPP로 이 호출이 실패합니다. 또한 MSG_WAITALL MSG_OOB, MSG_PEEK 또는 MSG_PARTIAL 함께 지정되면 WSAEOPNOTSUPP에서 이 호출이 실패합니다. 이 플래그는 데이터그램 소켓 또는 메시지 지향 소켓에서 지원되지 않습니다.
 
참고recv와 같은 차단 Winsock 호출을 실행할 때 Winsock은 호출이 완료되기 전에 네트워크 이벤트를 기다려야 할 수 있습니다. Winsock은 이 상황에서 경고 가능한 대기를 수행합니다. 이 대기는 동일한 스레드에서 예약된 APC(비동기 프로시저 호출)에 의해 중단될 수 있습니다. 동일한 스레드에서 지속적인 차단 Winsock 호출을 중단한 APC 내에서 다른 차단 Winsock 호출을 실행하면 정의되지 않은 동작이 발생하며 Winsock 클라이언트에서 시도해서는 안 됩니다.
 

예제 코드

다음 코드 예제에서는 recv 함수의 사용을 보여 있습니다.
#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"

int __cdecl main() {

    //----------------------
    // Declare and initialize variables.
    WSADATA wsaData;
    int iResult;

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService; 

    char *sendbuf = "this is a test";
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
  
    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
      printf("WSAStartup failed: %d\n", iResult);
      return 1;
    }

    //----------------------
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return 1;
    }

    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port of the server to be connected to.
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    clientService.sin_port = htons( 27015 );

    //----------------------
    // Connect to server.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    if ( iResult == SOCKET_ERROR) {
        closesocket (ConnectSocket);
        printf("Unable to connect to server: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf("send failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed: %d\n", WSAGetLastError());

    } while( iResult > 0 );

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}


예제 코드

자세한 내용과 recv 함수의 또 다른 예제는 시작 With Winsock을 참조하세요.

Windows Phone 8: 이 함수는 Windows Phone 8 이상에서 Windows Phone 스토어 앱에서 지원됩니다.

Windows 8.1Windows Server 2012 R2: 이 함수는 Windows 8.1, Windows Server 2012 R2 이상의 Windows 스토어 앱에서 지원됩니다.

요구 사항

   
지원되는 최소 클라이언트 Windows 8.1, Windows Vista [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows Server 2003 [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 winsock.h(Winsock2.h 포함)
라이브러리 Ws2_32.lib
DLL Ws2_32.dll

추가 정보

WSAAsyncSelect

WSARecv

WSARecvEx

Winsock 함수

Winsock 참조

recvfrom

선택

send

socket