recvfrom 함수(winsock.h)

recvfrom 함수는 데이터그램을 수신하고 원본 주소를 저장합니다.

구문

int recvfrom(
  [in]                SOCKET   s,
  [out]               char     *buf,
  [in]                int      len,
  [in]                int      flags,
  [out]               sockaddr *from,
  [in, out, optional] int      *fromlen
);

매개 변수

[in] s

바인딩된 소켓을 식별하는 설명자입니다.

[out] buf

들어오는 데이터에 대한 버퍼입니다.

[in] len

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

[in] flags

연결된 소켓에 대해 지정된 옵션 외에 함수 호출의 동작을 수정하는 옵션 집합입니다. 자세한 내용은 아래 설명을 참조하세요.

[out] from

반환 시 원본 주소를 보유할 sockaddr 구조체의 버퍼에 대한 선택적 포인터입니다.

[in, out, optional] fromlen

from 매개 변수가 가리키는 버퍼의 크기(바이트)에 대한 선택적 포인터입니다.

반환 값

오류가 발생하지 않으면 recvfrom 은 받은 바이트 수를 반환합니다. 연결이 정상적으로 닫힌 경우 반환 값은 0입니다. 그렇지 않으면 SOCKET_ERROR 값이 반환되고 WSAGetLastError를 호출하여 특정 오류 코드를 검색할 수 있습니다.

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

설명

recvfrom 함수는 연결된 소켓과 연결되지 않은 소켓 모두에서 들어오는 데이터를 읽고 데이터가 전송된 주소를 캡처합니다. 이 함수는 일반적으로 연결 없는 소켓과 함께 사용됩니다. 소켓의 로컬 주소를 알고 있어야 합니다. 서버 애플리케이션의 경우 일반적으로 바인딩을 통해 명시적으로 수행됩니다. 클라이언트 애플리케이션에는 명시적 바인딩이 권장되지 않습니다. 이 함수를 사용하는 클라이언트 애플리케이션의 경우 소켓은 sendto, WSASendTo 또는 WSAJoinLeaf를 통해 로컬 주소에 암시적으로 바인딩될 수 있습니다.

SOCK_STREAM 형식의 소켓과 같은 스트림 지향 소켓의 경우 recvfrom 호출은 지정된 버퍼 크기까지 현재 사용 가능한 만큼의 정보를 반환합니다. 소켓이 OOB 데이터(소켓 옵션 SO_OOBINLINE)의 인라인 수신을 위해 구성되어 있고 OOB 데이터가 아직 읽지 않은 경우 OOB 데이터만 반환됩니다. 애플리케이션은 ioctlsocket 또는 WSAIoctlSIOCATMARK 명령을 사용하여 더 많은 OOB 데이터를 읽을 수 있는지 여부를 확인할 수 있습니다. fromfromlen 매개 변수는 연결 지향 소켓에 대해 무시됩니다.

메시지 지향 소켓의 경우 데이터가 첫 번째 큐에 포함된 메시지에서 지정된 버퍼 크기까지 추출됩니다. 데이터그램 또는 메시지가 지정된 버퍼보다 크면 버퍼가 데이터그램의 첫 번째 부분으로 채워지고 recvfrom에서WSAEMSGSIZE 오류를 생성합니다. 신뢰할 수 없는 프로토콜(예: UDP)의 경우 초과 데이터가 손실됩니다. 수신된 패킷에 데이터가 없는 경우(비어 있는) UDP의 경우 recvfrom 함수 함수의 반환 값은 0입니다.

from 매개 변수가 0이 아니고 소켓이 연결 지향적이지 않은 경우(예: SOCK_DGRAM 입력) 데이터를 보낸 피어의 네트워크 주소가 해당 sockaddr 구조에 복사됩니다. fromlen이 가리키는 값은 이 구조체의 크기로 초기화되고 반환 시 sockaddr 구조에 저장된 주소의 실제 크기를 나타내도록 수정됩니다.

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

소켓이 연결 지향이고 원격 쪽에서 정상적으로 연결을 종료한 경우 recvfrom 호출은 수신된 바이트 0으로 즉시 완료됩니다. 연결이 다시 설정된 경우 recvfrom실패하고 WSAECONNRESET 오류가 발생합니다.

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

의미
MSG_PEEK 들어오는 데이터를 피킹합니다. 데이터는 버퍼에 복사되지만 입력 큐에서 제거되지 않습니다.
MSG_OOB OOB(대역 외) 데이터를 처리합니다.
 
참고recvfrom과 같은 차단 Winsock 호출을 실행할 때 Winsock은 호출이 완료되기 전에 네트워크 이벤트를 기다려야 할 수 있습니다. Winsock은 이 상황에서 경고 가능한 대기를 수행하며, 동일한 스레드에서 예약된 APC(비동기 프로시저 호출)에 의해 중단될 수 있습니다. 동일한 스레드에서 지속적인 차단 Winsock 호출을 중단한 APC 내에서 또 다른 차단 Winsock 호출을 실행하면 정의되지 않은 동작이 발생하며 Winsock 클라이언트에서 시도해서는 안 됩니다.
 

예제 코드

다음 예제에서는 recvfrom 함수를 사용하는 방법을 보여 줍니다.
#ifndef UNICODE
#define UNICODE
#endif

#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")

int main()
{

    int iResult = 0;

    WSADATA wsaData;

    SOCKET RecvSocket;
    struct sockaddr_in RecvAddr;

    unsigned short Port = 27015;

    char RecvBuf[1024];
    int BufLen = 1024;

    struct sockaddr_in SenderAddr;
    int SenderAddrSize = sizeof (SenderAddr);

    //-----------------------------------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error %d\n", iResult);
        return 1;
    }
    //-----------------------------------------------
    // Create a receiver socket to receive datagrams
    RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (RecvSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error %d\n", WSAGetLastError());
        return 1;
    }
    //-----------------------------------------------
    // Bind the socket to any address and the specified port.
    RecvAddr.sin_family = AF_INET;
    RecvAddr.sin_port = htons(Port);
    RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
    if (iResult != 0) {
        wprintf(L"bind failed with error %d\n", WSAGetLastError());
        return 1;
    }
    //-----------------------------------------------
    // Call the recvfrom function to receive datagrams
    // on the bound socket.
    wprintf(L"Receiving datagrams...\n");
    iResult = recvfrom(RecvSocket,
                       RecvBuf, BufLen, 0, (SOCKADDR *) & SenderAddr, &SenderAddrSize);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
    }
 
    //-----------------------------------------------
    // Close the socket when finished receiving datagrams
    wprintf(L"Finished receiving. Closing socket.\n");
    iResult = closesocket(RecvSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
        return 1;
    }

    //-----------------------------------------------
    // Clean up and exit.
    wprintf(L"Exiting.\n");
    WSACleanup();
    return 0;
}


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

WSAEventSelect

Winsock 함수

Winsock 참조

Recv

send

sockaddr

socket