다음 자료는 소켓을 닫는 소켓 연결을 종료하는 주제에 대한 설명으로 제공됩니다. 소켓 연결을 종료하고 소켓을 닫는 것의 차이를 구분하는 것이 중요합니다.
소켓 연결을 종료하려면 두 엔드포인트 간의 프로토콜 메시지 교환이 포함되며, 그 후에는 종료 시퀀스라고 합니다. 종료 시퀀스의 두 가지 일반 클래스가 정의됩니다. 정상 및 중단(하드라고도 함). 정상적인 종료 시퀀스에서 큐에 대기되었지만 아직 전송되지 않은 데이터는 연결을 닫기 전에 보낼 수 있습니다. 중단된 종료에서는 전송되지 않은 데이터가 손실됩니다. 종료 시퀀스(정상 또는 중단)의 발생을 사용하여 종료가 진행 중임을 나타내는 관련 애플리케이션에 FD_CLOSE 표시를 제공할 수도 있습니다.
반면에 소켓을 닫으면 소켓 핸들의 할당이 취소되어 애플리케이션이 더 이상 소켓을 참조하거나 어떤 방식으로든 사용할 수 없게 됩니다.
Windows 소켓에서는 종료 함수와 WSASendDisconnect 함수를 모두 사용하여 종료 시퀀스를 시작할 수 있으며, closesocket 함수는 소켓 핸들의 할당을 취소하고 연결된 리소스를 해제하는 데 사용됩니다. 그러나 closesocket 함수로 인해 아직 발생하지 않은 경우 종료 시퀀스가 암시적으로 발생하므로 약간의 혼란이 발생합니다. 실제로 이 기능을 사용하고 closesocket 사용하여 종료 시퀀스를 시작하고 소켓 핸들의 할당을 취소하는 것이 일반적인 프로그래밍 방식입니다.
이러한 사용을 용이하게 하기 위해 소켓 인터페이스는 프로그래머가 암시적 종료 시퀀스가 정상인지 아니면 중단되어야 하는지를 나타낼 수 있는 소켓 옵션 메커니즘을 통해 컨트롤을 제공하고, closesocket 함수가 정상 종료 시퀀스가 완료될 때까지 시간을 허용하기 위해 남아 있어야 하는지 여부도 제공합니다. 이러한 중요한 차이점과 이러한 방식으로 closesocket 사용하는 파급 효과는 여전히 널리 이해되지 않습니다.
소켓 옵션 SO_LINGER 및 SO_DONTLINGER 적절한 값을 설정하면 closesocket 함수를 사용하여 다음 유형의 동작을 가져올 수 있습니다.
- 중단 종료 시퀀스, closesocket즉시 반환합니다.
- 정상 종료, 종료 시퀀스가 완료되거나 지정된 시간 간격이 경과할 때까지 반환을 지연합니다. 정상 종료 시퀀스가 완료되기 전에 시간 간격이 만료되면 중단된 종료 시퀀스가 발생하고 closesocket 반환됩니다.
- 정상 종료, 즉시 반환 - 백그라운드에서 종료 시퀀스를 완료할 수 있습니다. 기본 동작이지만 애플리케이션은 정상적인 종료 시퀀스가 실제로 완료되는 시기(또는 여부)를 알 수 없습니다.
SO_LINGER 및 SO_DONTLINGER 소켓 옵션 및 관련 느린 구조의 사용은 SOL_SOCKET 소켓 옵션 참조 섹션에서 자세히 설명하고 느린 구조체에 대해 설명합니다.
연결 중단 중에 발생하는 문제를 최소화하는 데 사용할 수 있는 한 가지 방법은 closesocket암시적 종료가 시작되지 않도록 하는 것입니다. 대신종료 또는 WSASendDisconnect두 명시적 종료 함수 중 하나를 사용합니다. 그러면 피어 애플리케이션에서 보류 중인 모든 데이터를 수신했음을 나타내는 FD_CLOSE 표시가 수신됩니다. 이를 설명하기 위해 다음 표에서는 클라이언트가 정상적인 종료를 시작할 책임이 있는 애플리케이션의 클라이언트 및 서버 구성 요소에서 호출할 함수를 보여 줍니다.
클라이언트 쪽 | 서버 쪽 |
---|---|
(1) 종료(즉, SD_SEND)를 호출하여 세션 종료 신호를 보내고 클라이언트에 보낼 데이터가 더 이상 없습니다. | |
(2) 진행 중인 정상 종료 및 모든 데이터가 수신되었음을 나타내는 FD_CLOSE 받습니다. | |
(3) 나머지 응답 데이터를 보냅니다. | |
(로컬 타이밍 중요도만 해당) FD_READ 가져오고 recv 호출하여 서버에서 보낸 응답 데이터를 가져옵니다. | (4) 종료(즉, SD_SEND)를 호출하여 서버에 보낼 데이터가 더 이상 없음을 나타냅니다. |
(5) FD_CLOSE 표시를 받습니다. | (로컬 타이밍 중요도만 해당) closesocket 호출합니다. |
(6) closesocket호출합니다. |