Share via


Windows 소켓 1.1 차단 루틴 및 EINPROGRESS

Berkeley Sockets 환경에서 Windows 환경으로 애플리케이션을 포팅하는 주요 문제 중 하나는 차단과 관련이 있습니다. 즉, 연결된 작업이 완료될 때까지 반환되지 않는 함수를 호출합니다. 작업이 완료되는 데 임의로 시간이 오래 걸리는 경우 문제가 발생합니다. 예를 들어 피어 시스템에서 데이터를 받을 때까지 차단할 수 있는 recv 함수가 있습니다. 버클리 소켓 모델 내의 기본 동작은 프로그래머가 작업을 비블로킹으로 처리하도록 명시적으로 요청하지 않는 한 소켓이 차단 모드에서 작동하는 것입니다. Windows 소켓 1.1 환경에서는 선점 예약을 가정할 수 없습니다. 따라서 프로그래머는 Windows 소켓 1.1에서 가능한 경우 비동기식 비동기 작업을 사용하는 것이 좋습니다. 항상 가능한 것은 아니므로 다음에 설명된 의사 차단 기능이 제공되었습니다.

참고

Windows 소켓 2는 교착 상태가 문제가 되지 않는 선점형 32비트 운영 체제에서만 실행됩니다. Windows 소켓 2에서는 Windows 소켓 1.1에 권장되는 프로그래밍 사례가 필요하지 않습니다.

 

차단 소켓에서도 바인딩, getsockoptgetpeername 과 같은 일부 함수는 즉시 완료됩니다. 이러한 함수에 대한 차단 및 비블로킹 작업 간에는 차이가 없습니다. recv와 같은 다른 작업은 다양한 전송 조건에 따라 즉시 완료하거나 완료하는 데 임의의 시간이 걸릴 수 있습니다. 차단 소켓에 적용된 경우 이러한 작업을 차단 작업이라고 합니다. 다음 함수는 차단할 수 있습니다.

16비트 Windows 소켓 1.1에서는 즉시 완료할 수 없는 차단 작업이 다음과 같이 의사 차단에 의해 처리됩니다.

서비스 공급자는 작업을 시작한 다음, Windows 메시지를 디스패치하는 루프(필요한 경우 프로세서를 다른 스레드로 생성)를 입력한 다음 Windows Sockets 함수의 완료를 확인합니다. 함수가 완료되었거나 WSACancelBlockingCall 이 호출된 경우 차단 함수가 적절한 결과로 완료됩니다.

서비스 공급자는 차단 작업이 미해결 상태인 동안 메시지를 다시 입력할 가능성을 방지하기 위해 메시지를 처리하지 않는 차단 후크 함수의 설치를 허용해야 합니다. 가장 간단한 차단 후크 함수는 FALSE를 반환 합니다. Windows 소켓 DLL이 내부 작업을 위한 메시지에 의존하는 경우 애플리케이션 차단 후크를 실행하기 전에 PeekMessage(hMyWnd...)를 실행하여 시스템의 나머지 부분에 영향을 주지 않고 메시지를 가져올 수 있습니다.

16비트 Windows 소켓 1.1 환경에서 차단 작업이 진행 중인 프로세스에 대해 Windows 메시지가 수신되면 애플리케이션이 다른 Windows 소켓 호출을 실행하려고 시도할 위험이 있습니다. 이 조건을 안전하게 관리하는 데 어려움이 있기 때문에 Windows Sockets 1.1은 이러한 애플리케이션 동작을 지원하지 않습니다. 애플리케이션은 둘 이상의 중첩된 Windows Sockets 함수 호출을 할 수 없습니다. 특정 작업에는 하나의 미해결 함수 호출만 허용됩니다. 유일한 예외는 이 상황에서 프로그래머를 지원하기 위해 제공되는 두 가지 함수인 WSAIsBlockingWSACancelBlockingCall입니다.

WSAIsBlocking 함수는 언제든지 호출하여 차단 Windows Sockets 1.1 호출이 진행 중인지 여부를 확인할 수 있습니다. 마찬가지로 WSACancelBlockingCall 함수는 진행 중인 차단 호출을 취소하기 위해 언제든지 호출할 수 있습니다. 다른 Windows 소켓 함수 중첩은 WSAEINPROGRESS 오류와 함께 실패합니다.

이 제한은 차단 및 비블로킹 작업 모두에 적용된다는 점을 강조해야 합니다. WSAStartup을 호출할 때 버전 2.0 이상을 협상하는 Windows 소켓 2 애플리케이션의 경우 작업 중첩에 대한 제한이 종료되지 않습니다. WSAAccept 조건부 승인 콜백 중 또는 서비스 공급자가 Windows Sockets 2 함수를 차례로 호출하는 경우와 같이 드문 상황에서 작업이 중첩될 수 있습니다.

이 메커니즘은 간단한 애플리케이션에 충분하지만 고급 애플리케이션(예: MDI 모델을 사용하는 애플리케이션)의 복잡한 메시지 디스패치 요구 사항을 지원할 수 없습니다. 이러한 애플리케이션의 경우 Windows 소켓 API에는 WSASetBlockingHook 함수가 포함되어 있으며, 이를 통해 애플리케이션은 이전 설명에서 설명한 기본 메시지 디스패치 루틴 대신 호출할 수 있는 특수 루틴을 지정할 수 있습니다.

Windows 소켓 공급자는 다음이 모두 true인 경우에만 차단 후크를 호출합니다.

  • 루틴은 차단할 수 있는 것으로 정의된 루틴입니다.
  • 지정된 소켓이 차단 소켓입니다.
  • 요청을 즉시 완료할 수 없습니다.

소켓은 기본적으로 차단으로 설정되지만 FIONBIO IOCTL 또는 WSAAsyncSelect 함수를 사용하는 ioctlsocket 함수는 소켓을 비블로킹 모드로 설정할 수 있습니다.

애플리케이션이 다음 지침을 따르는 경우 차단 후크가 호출되지 않으며 애플리케이션은 차단 후크가 도입할 수 있는 재입력 문제를 염려할 필요가 없습니다.

  • 차단 해제 소켓만 사용합니다.
  • 선택getXbyY 루틴 대신 WSAAsyncSelect 및/또는 WSAAsyncGetXByY 루틴을 사용합니다.

Windows Sockets 1.1 애플리케이션이 메모리 개체(예: 버퍼 또는 전역 변수)에 대한 포인터를 인수로 사용하는 비동기 또는 비블로킹 작업을 호출하는 경우 작업 전체에서 Windows 소켓에서 개체를 사용할 수 있도록 하는 것은 애플리케이션의 책임입니다. 애플리케이션은 관련된 메모리의 매핑 또는 주소 실행 가능성에 영향을 줄 수 있는 Windows 함수를 호출해서는 안됩니다.