LPWSPRECVFROM 콜백 함수(ws2spi.h)
LPWSPRecvFrom 함수는 데이터그램을 수신하고 원본 주소를 저장합니다.
구문
LPWSPRECVFROM Lpwsprecvfrom;
int Lpwsprecvfrom(
[in] SOCKET s,
[in, out] LPWSABUF lpBuffers,
[in] DWORD dwBufferCount,
[out] LPDWORD lpNumberOfBytesRecvd,
[in, out] LPDWORD lpFlags,
[out] sockaddr *lpFrom,
[in, out] LPINT lpFromlen,
[in] LPWSAOVERLAPPED lpOverlapped,
[in] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
\[in\] LPWSATHREADID lpThreadId,
[in, out] LPINT lpErrno
)
{...}
매개 변수
[in] s
소켓을 식별하는 설명자입니다.
[in, out] lpBuffers
WSABUF 구조체의 배열에 대한 포인터입니다. 각 WSABUF 구조체에는 버퍼에 대한 포인터와 버퍼 길이(바이트)가 포함됩니다.
[in] dwBufferCount
lpBuffers 배열의 WSABUF 구조체 수입니다.
[out] lpNumberOfBytesRecvd
이 호출에서 받은 바이트 수에 대한 포인터입니다.
[in, out] lpFlags
플래그에 대한 포인터입니다.
[out] lpFrom
겹치는 작업이 완료될 때 원본 주소를 보유할 sockaddr 구조체의 버퍼에 대한 선택적 포인터입니다.
[in, out] lpFromlen
lpFrom이 지정된 경우에만 필요한 lpFrom 버퍼의 크기(바이트)에 대한 포인터입니다.
[in] lpOverlapped
WSAOverlapped 구조체에 대한 포인터입니다(오버랩되지 않은 소켓의 경우 무시됨).
[in] lpCompletionRoutine
형식: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
수신 작업이 완료되었을 때 호출되는 완료 루틴에 대한 포인터입니다(오버랩되지 않은 소켓의 경우 무시됨).
\\[in\\] lpThreadId
WPUQueueApc에 대한 후속 호출에서 공급자가 사용할 WSATHREADID 구조체에 대한 포인터입니다. 공급자는 WPUQueueApc 함수가 반환될 때까지 참조된 WSATHREADID 구조체(동일한 포인터가 아님)를 저장해야 합니다.
[in, out] lpErrno
오류 코드에 대한 포인터입니다.
반환 값
오류가 발생하지 않고 수신 작업이 즉시 완료되면 LPWSPRecvFrom 은 0을 반환합니다. 이 경우 지정된 경우 완료 루틴이 이미 큐에 대기되어 있습니다. 그렇지 않으면 SOCKET_ERROR 값이 반환되고 lpErrno에서 특정 오류 코드를 사용할 수 있습니다. 오류 코드 WSA_IO_PENDING 겹치는 작업이 성공적으로 시작되었으며 나중에 완료가 표시됨을 나타냅니다. 다른 오류 코드는 겹치는 작업이 시작되지 않았으며 완료 표시가 발생하지 않음을 나타냅니다.
오류 코드 | 의미 |
---|---|
네트워크 하위 시스템이 실패했습니다. | |
lpFromlen 매개 변수가 잘못되었습니다. lpFrom 버퍼가 너무 작아서 피어 주소를 수용할 수 없거나 lpbuffers가 사용자 주소 공간의 유효한 부분에 완전히 포함되지 않았습니다. | |
(차단) 호출이 LPWSPCancelBlockingCall을 통해 취소되었습니다. | |
Windows 소켓 호출 차단이 진행 중이거나 서비스 공급자가 여전히 콜백 함수를 처리하고 있습니다. | |
소켓이 바인딩되지 않았거나(예: LPWSPBind 사용) 소켓이 겹치는 플래그로 만들어지지 않았습니다. | |
소켓이 연결되어 있습니다. 이 함수는 소켓이 연결 지향인지 아니면 연결이 없는지 여부에 관계없이 연결된 소켓에서 허용되지 않습니다. | |
해당 작업이 진행되는 동안 오류가 발생하여 연결이 끊겼습니다. | |
설명자가 소켓이 아닙니다. | |
MSG_OOB 지정되었지만 소켓이 SOCK_STREAM 형식과 같은 스트림 스타일이 아니거나, OOB 데이터가 이 소켓과 연결된 통신 도메인에서 지원되지 않거나, 소켓이 단방향이며 보내기 작업만 지원합니다. | |
소켓이 종료되었습니다. LPWSPShutdown이 SD_RECEIVE 또는 SD_BOTH 로 설정된 방법을 사용하여 호출된 후에는 소켓에서 LPWSPRecvFrom을 실행할 수 없습니다. | |
**Windows NT:** 겹치는 소켓: 미해결 겹치는 I/O 요청이 너무 많습니다. 오버랩되지 않은 소켓: 소켓이 차단 해제로 표시되고 수신 작업을 즉시 완료할 수 없습니다. |
|
메시지가 너무 커서 지정된 버퍼에 맞지 않으며(신뢰할 수 없는 프로토콜에만 해당) 버퍼에 맞지 않는 메시지의 후행 부분이 삭제되었습니다. | |
가상 회로가 하드 또는 중단한 닫기를 실행하는 원격 쪽에서 재설정되었습니다. 더 이상 소켓을 사용할 수 없으므로 응용 프로그램이 소켓을 닫아야 합니다. UDP 데이터그램 소켓에서 이 오류는 이전 보내기 작업으로 인해 ICMP "포트 연결할 수 없음" 메시지가 발생했음을 나타냅니다. | |
소켓 은 메시지 지향이며 가상 회로는 원격 쪽에서 정상적으로 닫혔습니다. | |
겹치는 작업이 성공적으로 시작되었으며 나중에 완료가 표시됩니다. | |
소켓의 닫기로 인해 겹치는 작업이 취소되었습니다. |
설명
LPWSPRecvFrom 함수는 주로 s에 지정된 연결 없는 소켓에서 사용됩니다. 소켓을 연결하면 안 됩니다. 소켓의 로컬 주소를 알고 있어야 합니다. 이 작업은 LPWSPBind 를 통해 명시적으로 수행되거나 LPWSPSendTo 또는 LPWSPJoinLeaf를 통해 암시적으로 수행될 수 있습니다.
겹치는 소켓의 경우 이 함수는 클라이언트가 지정한 완료 표시(이벤트 개체의 완료 루틴 호출 또는 설정)가 발생한 후 들어오는 데이터가 (연결될 수 있음) 소켓에서 사용할 수 있게 되면 들어오는 데이터가 배치되는 하나 이상의 버퍼를 게시하는 데 사용됩니다. 작업이 즉시 완료되지 않으면 완료 루틴 또는 LPWSPGetOverlappedResult를 통해 최종 완료 상태 검색됩니다. 또한 lpFrom 및 lpFromlen에서 가리키는 값은 완료가 표시될 때까지 업데이트되지 않습니다. 애플리케이션은 업데이트될 때까지 이러한 값을 사용하거나 방해해서는 안 되므로 클라이언트는 이러한 매개 변수에 대해 자동(즉, 스택 기반) 변수를 사용하지 않아야 합니다.
lpOverlapped 및 lpCompletionRoutine이 모두 null이면 이 함수의 소켓은 오버랩되지 않은 소켓으로 처리됩니다.
오버랩되지 않은 소켓의 경우 lpOverlapped, lpCompletionRoutine 및 lpThreadId 매개 변수는 무시됩니다. 전송에 의해 이미 수신되고 버퍼링된 모든 데이터는 제공된 사용자 버퍼에 복사됩니다. 현재 전송에 의해 수신되고 버퍼링된 데이터가 없는 차단 소켓의 경우 LPWSPRecv에 대해 할당된 차단 의미 체계에 따라 데이터가 수신될 때까지 호출이 차단됩니다.
제공된 버퍼는 lpBuffers가 가리키는 배열에 표시되는 순서대로 채워지고 버퍼는 구멍이 생성되지 않도록 압축됩니다.
lpBuffers 매개 변수가 가리키는 WSABUF 구조체의 배열은 일시적입니다. 이 작업이 겹치는 방식으로 완료되면 이 호출에서 반환하기 전에 WSABUF 구조체에 대한 이 포인터 배열을 캡처하는 것은 서비스 공급자의 책임입니다. 이렇게 하면 Windows 소켓 SPI 클라이언트가 스택 기반 WSABUF 배열을 빌드할 수 있습니다.
연결 없는 소켓 유형의 경우 데이터가 시작된 주소가 lpFrom이 가리키는 버퍼에 복사됩니다. 입력 시 lpFromlen 이 가리키는 값은 이 버퍼의 크기로 초기화되고 완료 시 수정되어 저장된 주소의 실제 크기를 나타냅니다.
이전에 겹치는 소켓에 대해 설명한 대로 lpFrom 및 lpFromlen 매개 변수는 겹치는 I/O가 완료될 때까지 업데이트되지 않습니다. 따라서 이러한 매개 변수가 가리키는 메모리는 서비스 공급자가 계속 사용할 수 있어야 하며 Windows 소켓 SPI 클라이언트의 스택 프레임에 할당할 수 없습니다. lpFrom 및 lpFromlen 매개 변수는 연결 지향 소켓에 대해 무시됩니다.
바이트 스트림 스타일 소켓(예: 형식 SOCK_STREAM)의 경우 버퍼가 채워지거나, 연결이 닫히거나, 내부적으로 버퍼링된 데이터가 소진될 때까지 들어오는 데이터가 버퍼에 배치됩니다. 들어오는 데이터가 모든 버퍼를 채우는지 여부에 관계없이 겹치는 소켓에 대한 완료 표시가 발생합니다.
메시지 지향 소켓의 경우 제공된 버퍼의 총 크기까지 들어오는 단일 메시지가 제공된 버퍼에 배치되고 겹치는 소켓에 대한 완료 표시가 발생합니다. 메시지가 제공된 버퍼보다 크면 버퍼가 메시지의 첫 번째 부분으로 채워집니다. 서비스 공급자가 MSG_PARTIAL 기능을 지원하는 경우 MSG_PARTIAL 플래그는 소켓에 대해 lpFlags 로 설정되고 후속 수신 작업은 나머지 메시지를 검색합니다. MSG_PARTIAL 지원되지 않지만 프로토콜이 신뢰할 수 있는 경우 LPWSPRecvFrom 은 WSAEMSGSIZE 오류를 생성하고 더 큰 버퍼가 있는 후속 수신 작업을 사용하여 전체 메시지를 검색할 수 있습니다. 그렇지 않으면(즉, 프로토콜이 신뢰할 수 없고 MSG_PARTIAL 지원하지 않음), 초과 데이터가 손실되고 LPWSPRecvFrom에서 WSAEMSGSIZE 오류가 발생합니다.
lpFlags 매개 변수를 사용하여 연결된 소켓에 대해 지정된 옵션 외에 함수 호출의 동작에 영향을 줄 수 있습니다. 즉, 이 함수의 의미 체계는 소켓 옵션 및 lpFlags 매개 변수에 의해 결정됩니다. 후자는 다음 값과 함께 비트 OR 연산자를 사용하여 생성됩니다.
값 | 의미 |
---|---|
MSG_PEEK | 들어오는 데이터를 피킹합니다. 데이터는 버퍼에 복사되지만 입력 큐에서 제거되지 않습니다. 이 플래그는 오버랩되지 않은 소켓에만 유효합니다. |
MSG_OOB | OOB(Out of Band) 데이터를 처리합니다. |
MSG_PARTIAL | 이 플래그는 메시지 지향 소켓에만 사용됩니다. 출력에서 은 제공된 데이터가 보낸 사람에서 전송하는 메시지의 일부임을 나타냅니다. 메시지의 나머지 부분은 후속 수신 작업에서 제공됩니다. MSG_PARTIAL 플래그가 지워진 후속 수신 작업은 보낸 사람의 메시지 끝을 나타냅니다. 입력 매개 변수인 MSG_PARTIAL 서비스 공급자가 메시지의 일부만 수신한 경우에도 수신 작업이 완료되어야 했음을 나타냅니다. |
메시지 지향 소켓의 경우 부분 메시지가 수신되면 MSG_PARTIAL 비트가 lpFlags 매개 변수에 설정됩니다. 전체 메시지가 수신되면 lpFlags에서 MSG_PARTIAL 지워집니다. 완료가 지연되는 경우 lpFlags 가 가리키는 값은 업데이트되지 않습니다. 완료가 표시되면 Windows 소켓 SPI 클라이언트는 LPWSPGetOverlappedResult 를 호출하고 lpdwFlags 매개 변수가 가리키는 플래그를 검사해야 합니다.
겹치는 작업이 즉시 완료되면 LPWSPRecv 는 값 0을 반환하고 lpNumberOfBytesRecvd 매개 변수는 수신된 바이트 수로 업데이트되고 lpFlags 매개 변수가 가리키는 플래그 비트도 업데이트됩니다. 겹치는 작업이 성공적으로 시작되고 나중에 완료될 경우 LPWSPRecv 는 SOCKET_ERROR 반환하고 오류 코드 WSA_IO_PENDING 나타냅니다. 이 경우 lpNumberOfBytesRecvd 및 lpFlags 는 업데이트되지 않습니다. 겹치는 작업이 완료되면 전송되는 데이터의 양은 완료 루틴(지정된 경우)의 cbTransferred 매개 변수를 통해 또는 LPWSPGetOverlappedResult의 lpcbTransfer 매개 변수를 통해 표시됩니다. 플래그 값은 LPWSPGetOverlappedResult의 lpdwFlags 매개 변수를 검사하여 가져옵니다.
공급자는 이전 LPWSPRecv, LPWSPRecvFrom, LPWSPSend 또는 LPWSPSendTo 함수의 완료 루틴 내에서 이 함수 를 호출하도록 허용해야 합니다. 그러나 지정된 소켓의 경우 I/O 완료 루틴을 중첩할 수 없습니다. 이렇게 하면 시간이 중요한 데이터 전송이 선점 컨텍스트 내에서 완전히 발생할 수 있습니다.
lpOverlapped 매개 변수는 겹치는 작업 기간 동안 유효해야 합니다. 여러 I/O 작업이 동시에 미해결 상태이면 각각 겹치는 별도의 구조를 참조해야 합니다. WSAOverlapped 구조체는 자체 참조 페이지에 정의되어 있습니다.
lpCompletionRoutine 매개 변수가 null이면 서비스 공급자는 유효한 이벤트 개체 핸들이 포함된 경우 겹치는 작업이 완료될 때 lpOverlapped의 hEvent 멤버에 신호를 보냅니다. Windows Sockets SPI 클라이언트는 LPWSPGetOverlappedResult 를 사용하여 이벤트 개체를 기다리거나 폴링할 수 있습니다.
lpCompletionRoutine이 null이 아닌 경우 hEvent 멤버는 무시되며 Windows Sockets SPI 클라이언트에서 컨텍스트 정보를 완료 루틴에 전달하는 데 사용할 수 있습니다. 겹치는 작업이 완료될 때 지정된 클라이언트 호출-완료 루틴을 정렬하는 것은 서비스 공급자의 책임입니다. 겹치는 작업을 시작한 동일한 스레드의 컨텍스트에서 완료 루틴을 실행해야 하므로 서비스 공급자에서 직접 호출할 수 없습니다. 이 Ws2_32.dll 완료 루틴을 쉽게 호출할 수 있도록 APC(비동기 프로시저 호출) 메커니즘을 제공합니다.
서비스 공급자는 WPUQueueApc를 호출하여 적절한 스레드 및 프로세스 컨텍스트에서 실행할 함수를 정렬합니다. 이 함수는 겹치는 작업을 시작하는 데 사용된 스레드 및 프로세스와 다른 컨텍스트라도 모든 프로세스 및 스레드 컨텍스트에서 호출할 수 있습니다.
WPUQueueApc 는 WSATHREADID 구조체에 대한 포인터( lpThreadId 입력 매개 변수를 통해 공급자에게 제공됨), 호출할 APC 함수에 대한 포인터 및 이후에 APC 함수에 전달되는 컨텍스트 값을 입력 매개 변수로 사용합니다. 단일 컨텍스트 값만 사용할 수 있으므로 APC 함수 자체는 클라이언트가 지정한 완료 루틴이 될 수 없습니다. 대신 서비스 공급자는 제공된 컨텍스트 값을 사용하여 겹치는 작업에 필요한 결과 정보에 액세스하는 자체 APC 함수에 대한 포인터를 제공한 다음 지정된 클라이언트 완료 루틴을 호출해야 합니다.
클라이언트에서 제공하는 완료 루틴의 프로토타입은 다음과 같습니다.
void CALLBACK
CompletionRoutine(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
CompletionRoutine은 클라이언트에서 제공하는 함수 이름의 자리 표시자입니다. dwError는 lpOverlapped에 표시된 대로 겹치는 작업에 대한 완료 상태 지정합니다. cbTransferred는 수신된 바이트 수를 지정합니다. dwFlags 에는 수신 작업이 즉시 완료된 경우 lpFlags 에 표시되었을 정보가 포함됩니다. 이 함수는 값을 반환하지 않습니다.
겹치는 작업이 완료된 순서와 동일한 순서로 반드시 호출되는 것은 아니지만 완료 루틴을 순서대로 호출할 수 있습니다. 그러나 게시된 버퍼는 제공된 순서와 동일한 순서로 채워지도록 보장됩니다.
참고
지정된 스레드에서 시작된 모든 I/O는 해당 스레드가 종료될 때 취소됩니다. 겹치는 소켓의 경우 작업이 완료되기 전에 스레드가 닫히면 보류 중인 비동기 작업이 실패할 수 있습니다. 자세한 내용은 ExitThread 를 참조하세요.
요구 사항
지원되는 최소 클라이언트 | Windows 2000 Professional[데스크톱 앱만] |
지원되는 최소 서버 | Windows 2000 Server[데스크톱 앱만] |
머리글 | ws2spi.h |