3.7 Overlapped I/O 혹은 비동기 I/O
지금까지 우리는 논블록 소켓을 다루는 방법을 살펴보았습니다. 논블록 소켓의 장점은 다음과 같습니다.
• 스레드 블로킹이 없으므로 중도 취소 같은 통제가 가능합니다.
• 스레드 개수가 1개이거나 적어도 소켓을 여러 개 다룰 수 있습니다.
• 스레드 개수가 적거나 1개이므로 연산량이 낭비되지 않습니다. 그리고 호출 스택 메모리도 낭비되지 않습니다.
그러나 단점도 있습니다.
• 소켓 I/O 함수가 리턴한 코드가 would block인 경우 재시도 호출 낭비가 발생합니다(뒤에서 자세히 설명합니다).
• 소켓 I/O 함수를 호출할 때 입력하는 데이터 블록에 대한 복사 연산이 발생합니다(뒤에서 자세히 설명합니다).
• connect() 함수는 재시도 호출을 하지 않지만, send() 함수나 receive() 함수는 재시도 호출해야 하는 API가 일관되지 않는다는 문제가 있습니다.
논블록 소켓에서 재시도용 호출의 낭비가 어떤 경우에 있는지 알아봅시다.
TCP 소켓의 send() 처리 부분을 살펴봅시다. 이는 송신 버퍼에 1바이트라도 비어 있으면 I/O 가능이 됩니다. 이 상태에서 TCP 소켓에 대해 send() 함수를 호출하면 would block은 절대 발생하지 않습니다. 보내려는 데이터가 5바이트인데 송신 버퍼에 빈 공간이 1바이트라면, 1바이트만 소켓 송신 버퍼에 채워집니다. 그리고 성공적으로 리턴합니다. 즉, 보낼 데이터의 일부만 성공적으로 송신 큐에 넣었지만 어쨌든 성공이네요. 결론적으로 문제없습니다.