소켓 이중 된 I/O 대 차단/비차단 모드


요약


이 문서에서는 소켓의 겹친 I/O 특성과 소켓의 차단 또는 비차단 모드의 차이점에 대해 설명합니다.

추가 정보


소켓을 만들 때 기본적으로 차단 소켓입니다. ioctlsocket API 호출, WSAEventSelect 또는 WSAAysncSelect에서 FIONBIO 명령을 사용하여 소켓 모드를 차단에서 비차단으로 변경할 수 있습니다. Winsock 호출을 즉시 완료할 수 없는 경우 호출이 실패하고 WSAGetLastError가 비차단 소켓인 경우 WSAEWOULDBLOCK 오류를 반환하거나 차단 소켓인 경우 작업이 완료될 때까지 호출 블록이 됩니다. 소켓 이 중첩된 I/O 특성은 소켓의 차단 또는 비차단 모드와 다릅니다. 현재 Winsock 구현에는 비차단 소켓 모드에 대해 겹친 I/O 특성이 필요하지만 개념적으로 독립적이며 프로그래밍 모델도 다릅니다. 겹친 I/O 특성이 있는 소켓을 만들려면 WSA_FLAG_OverLAPPED 플래그 집합에서 소켓 API 또는 WSASocket API를 사용할 수 있습니다. 중첩된 I/O 작업을 즉시 완료할 수 없는 경우 호출이 실패하고 WSAGetLastError 또는 GetLastError 반환 WSA_IO_PENDING 또는 ERROR_IO_PENDING(실제로 WSA_IO_PENDING)와 동일한 정의입니다. 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
179942 정보: 비차단 소켓에 WSA_FLAG_overlapped 필요
소켓이 만들어지면 겹친 소켓 특성을 변경할 수 없습니다. 그러나 INVALID_SOCKET을 포함한 모든 소켓 핸들에서 SO_OPENTYPE 옵션을 사용하여 setockopt API를 호출하여 동일한 스레드의 모든 연속된 소켓 호출에 대해 겹친 특성을 변경할 수 있습니다. 기본 SO_OPENTYPE 옵션 값은 0이며 겹친 특성을 설정합니다. 영하지 않은 모든 옵션 값은 소켓을 동기로 만들고 완료 함수를 사용할 수 없도록 합니다. 소켓의 겹친 I/O 특성을 설정한다고 해서 소켓이 겹친 I/O 작업을 수행한다는 의미는 아닙니다. 예를 들어 WSARecv 및 WSASend에서 완료 함수와 겹친 구조 모두에 대해 NULL을 지정하거나 recv를 호출하거나 함수를 보내는 경우 차단 방식으로 완료됩니다. I/O가 중첩된 방식으로 수행되도록 하려면 사용하는 기능에 따라 I/O 함수에 중첩된 구조를 제공해야 합니다.

중첩된 I/O

Winsock 1에서는 소켓 API를 사용하여 겹친 소켓을 만들고 Win32 파일 I/O API ReadFile, ReadFileEx, WriteFile, WriteFileEx를 사용하여 소켓 핸들에서 겹친 I/O를 수행합니다. Winsock 2에서는 WSA_FLAG_OverLAPPED 플래그가 있는 WSASocket을 사용하거나 소켓 API를 사용하는 중첩된 소켓을 만듭니다. 위의 Win32 파일 I/O API 또는 Winsock 2 WSASend, WSASendTo, WSARecv 및 WSARecvFrom를 사용하여 중첩된 I/O 작업을 시작할 수 있습니다. SO_RCVBUF 및 SO_SNDBUF 옵션을 사용하여 0TCP 스택 수신 및 전송 버퍼를 설정하는 경우 기본적으로 TCP 스택에 I/O 호출에 제공된 버퍼를 사용하여 I/O를 직접 수행하도록 지시합니다. 따라서 겹친 소켓 I/O의 비차단 이점 외에도 TCP 스택 버퍼와 각 I/O 호출에 대한 사용자 버퍼 간에 버퍼 복사본을 저장하기 때문에 다른 장점은 성능이 향상됩니다. 그러나 겹친 작업을 위해 제출된 후 겹친 작업이 완료되기 전에 사용자 버퍼에 액세스하지 않도록 해야 합니다. 중첩된 I/O 작업이 완료되었는지 확인하려면 다음 옵션 중 하나를 사용할 수 있습니다.
  • I/O 호출에 사용되는 중첩된 구조에서 이벤트 핸들을 제공하고 이벤트 핸들에서 신호를 기다릴 수 있습니다.
  • GetOverlappedResult 또는 WSAGetOverlappedResult를 사용하여 겹친 I/O 작업의 상태를 폴링합니다. Windows NT에서 중복된 구조의 이벤트 핸들로 NULL을 지정할 수 있습니다. 그러나 Windows 95에서 겹친 구조에는 수동 재설정 이벤트 핸들이 포함되어야 합니다. WSAGetOverlappedWindows 98 및 Windows 밀레니엄 에디션(ME)에서 Windows NT처럼 작동하며 중첩된 구조의 NULL 이벤트 핸들을 통해 완료 상태를 폴링할 수 있도록 수정되었습니다.
  • ReadFileEx, WriteFileEx, WSARecv, WSARecvFrom, WSASend 또는 WSASendTo를 사용하고 중첩된 I/O 작업이 완료되면 호출할 완료 함수를 제공하도록 선택합니다. 완료 함수 접근 방식을 사용하는 경우 중첩된 I/O 작업을 실행한 후 Win32 대기 함수 또는 WSA 버전의 대기 함수를 실행하여 신호가 지정되지 않은 핸들에서 현재 스레드를 경고 가능한 대기 상태로 전환해야 합니다. 중첩된 I/O 작업이 완료되면 완료 함수가 호출되고 대기 함수가 WAIT_IO_COMPLETION를 반환하고 경고 가능한 대기 스레드가 절전 모드해제됩니다.
  • GetQueuedCompletionStatus를 사용하고 겹친 I/O 특성 집합과 함께 소켓을 Windows NT I/O 완료 포트(IOCP)와 연결합니다. IOCP를 사용하면 완료 함수를 제공하거나, 이벤트 핸들에서 신호를 표시하거나, 중첩된 작업의 상태를 폴링할 필요가 없습니다. IOCP를 만들고 중첩된 소켓 핸들을 IOCP에 추가하면 위에서 언급한 I/O API(recv, recvfrom, send or sendto 제외)를 사용하여 중첩된 작업을 시작할 수 있습니다. GetQueuedCompletionStatus API에서 I/O 완료 패킷을 기다리는 작업자 스레드 블록이 있습니다. 중첩된 I/O가 완료되면 I/O 완료 패킷이 IOCP에 도착하고 GetQueued완료 상태가 반환됩니다. IOCP는 겹친 I/O 작업에서 매우 간단한 스레딩 및 차단 코드를 사용하여 확장 가능한 높은 처리량 의 서버를 작성하기 위한 Windows NT 운영 체제 지원입니다. 따라서 Windows NT IOCP와 겹친 소켓 I/O를 사용하면 성능이 크게 상할 수 있습니다.

차단 및 비차단 모드

소켓을 만들 때 기본적으로 차단 소켓입니다. 차단 모드 소켓 I/O 작업에서 해당 작업이 완료될 때까지 모든 블록을 연결하고 수락합니다. 소켓 작동 모드를 차단 모드에서 비차단 모드로 변경하려면 ioctlsocket API 호출에서 WSASyncSelect, WSAEventSelect 또는 FIONBIO 명령을 사용할 수 있습니다. WSAAsyncSelect는 소켓 알림을 Windows 메시지에 매핑하며 단일 스레드 GUI 응용 프로그램에 가장 적합한 모델입니다. WSAEventSelect는 WSAEnumNetworkEvents를 사용하여 시그널링 이벤트에서 소켓 알림의 특성을 확인하고 이벤트를 신호로 매핑하여 소켓 알림을 매핑합니다. 이 모델은 Windows NT 서비스 응용 프로그램과 같이 메시지 펌프가 없는 비GUI 응용 프로그램에 유용한 모델입니다. ioctlsocket API 호출의 FIONBIO 명령은 소켓을 비차단 모드로 전환합니다. 그러나 선택 API를 사용하여 소켓의 상태를 폴링해야 합니다. 업데이트: 중첩된 recv를 사용하여 SO_RCVBUF를 0으로 설정하는 것은 Windows 2000에서 응용 프로그램의 recv 버퍼에 직접 데이터를 복사할 수 있는 것은 필요하지 않습니다. WINDOWS 2000에서 겹치는 전송을 사용하여 SO_SNDBUF를 0으로 설정하면 Windows NT 4.0과 동일한 메모리 복사본을 절약할 수 있습니다. 응용 프로그램이 해당 스택 버퍼를 0으로 설정하는 경우 응용 프로그램에서 몇 가지 미해결 중첩된 send 또는 recv를 발행하는 것도 중요합니다.