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를 호출하여 특정 오류 코드를 검색할 수 있습니다.
오류 코드 | 의미 |
---|---|
이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다. | |
네트워크 하위 시스템이 실패했습니다. | |
buf 또는 매개 변수에서 가리키는 버퍼가 사용자 주소 공간에 없거나 fromlen 매개 변수가 너무 작아 피어 주소의 원본 주소를 수용할 수 없습니다. | |
WSACancelBlockingCall을 통해 (차단) 호출이 취소되었습니다. | |
차단 Windows 소켓 1.1 호출이 진행 중이거나 서비스 공급자가 여전히 콜백 함수를 처리하고 있습니다. | |
소켓이 바인딩되지 않았거나 알 수 없는 플래그가 지정되었거나 SO_OOBINLINE 사용하도록 설정된 소켓에 대해 MSG_OOB 지정되었거나(바이트 스트림 스타일 소켓에만 해당) len 이 0 또는 음수였습니다. | |
소켓이 연결되어 있습니다. 이 함수는 소켓이 연결 지향인지 연결이 없는지 여부에 관계없이 연결된 소켓에서 허용되지 않습니다. | |
데이터그램 소켓의 경우 이 오류는 TTL(Time to Live)이 만료되었음을 나타냅니다. | |
s 매개 변수 의 설명자는 소켓이 아닙니다. | |
MSG_OOB 지정되었지만 소켓은 SOCK_STREAM 형식과 같은 스트림 스타일이 아니거나, OOB 데이터가 이 소켓과 연결된 통신 도메인에서 지원되지 않거나, 소켓이 단방향이며 보내기 작업만 지원합니다. | |
소켓이 종료되었습니다. SD_RECEIVE 또는 SD_BOTH 설정하는 방법을 사용하여 종료가 호출된 후에는 소켓에서 다시 탐색할 수 없습니다. | |
소켓이 차단 해제로 표시되고 recvfrom 작업이 차단됩니다. | |
메시지가 너무 커서 buf 매개 변수가 가리키는 버퍼에 맞지 않고 잘렸습니다. | |
네트워크 오류 또는 다른 쪽 끝의 시스템이 예고 없이 중단되었기 때문에 연결이 끊어졌습니다. | |
가상 회로가 하드 또는 중단한 닫기를 실행하는 원격 쪽에서 재설정되었습니다. 애플리케이션은 소켓을 닫아야 합니다. 더 이상 사용할 수 없습니다. UDP-datagram 소켓에서 이 오류는 이전 보내기 작업으로 인해 ICMP 포트 연결할 수 없음 메시지가 발생했음을 나타냅니다. |
설명
recvfrom 함수는 연결된 소켓과 연결되지 않은 소켓 모두에서 들어오는 데이터를 읽고 데이터가 전송된 주소를 캡처합니다. 이 함수는 일반적으로 연결 없는 소켓과 함께 사용됩니다. 소켓의 로컬 주소를 알고 있어야 합니다. 서버 애플리케이션의 경우 일반적으로 바인딩을 통해 명시적으로 수행됩니다. 클라이언트 애플리케이션에는 명시적 바인딩이 권장되지 않습니다. 이 함수를 사용하는 클라이언트 애플리케이션의 경우 소켓은 sendto, WSASendTo 또는 WSAJoinLeaf를 통해 로컬 주소에 암시적으로 바인딩될 수 있습니다.
SOCK_STREAM 형식의 소켓과 같은 스트림 지향 소켓의 경우 recvfrom 호출은 지정된 버퍼 크기까지 현재 사용 가능한 만큼의 정보를 반환합니다. 소켓이 OOB 데이터(소켓 옵션 SO_OOBINLINE)의 인라인 수신을 위해 구성되어 있고 OOB 데이터가 아직 읽지 않은 경우 OOB 데이터만 반환됩니다. 애플리케이션은 ioctlsocket 또는 WSAIoctlSIOCATMARK 명령을 사용하여 더 많은 OOB 데이터를 읽을 수 있는지 여부를 확인할 수 있습니다. from 및 fromlen 매개 변수는 연결 지향 소켓에 대해 무시됩니다.
메시지 지향 소켓의 경우 데이터가 첫 번째 큐에 포함된 메시지에서 지정된 버퍼 크기까지 추출됩니다. 데이터그램 또는 메시지가 지정된 버퍼보다 크면 버퍼가 데이터그램의 첫 번째 부분으로 채워지고 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 함수를 사용하는 방법을 보여 줍니다.#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.1 및 Windows 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 |