정리

GetQueuedCompletionStatus의 0 transferred bytes (1)

저장소/VC++

내가 틀리지 않았당께!! 아닌가? 



원문 출처 : http://javawork.egloos.com/2265358


 ERROR_NETNAME_DELETED는 에러 번호로는 64번이고 한글로는 "지정된 네트워크 이름을 더 이상 사용할 수 없습니다." 정도로 해석됩니다. 구글에 ERROR_NETNAME_DELETED로 검색해보면 거의 IOCP와 관련된 글들이 나옵니다. 어떤 상황에서 이 에러를 만나게 되는지, 해결책은 무엇인지 적어봅니다.

 보통 IOCP에서 소켓 끊어짐의 상징은 0 byte read 입니다. 0 byte read가 통보되는 시점은 상대방 소켓에서 closesocket() 혹은 shutdown() 함수를 호출한 시점입니다. 즉, 상대방이 closesocket() 혹은 shutdown() 을 호출하지 않고 종료해버리면 일반적으로 0 byte read는 발생하지 않습니다. 이렇게 0 byte read가 발생하지 않은 상태에서 read() 혹은 write()를 시도하면 상대는 이미 종료 되었으므로 ERROR_NETNAME_DELETED 에러가 나게 됩니다. 이러한 경우를 우아한 종료와는 반대되는 개념으로 HardClose라고 합니다.

ACE에서는 ACE_Asynch_Read_Stream.read() 나 ACE_Asynch_Write_Stream.write() 에서 0 이 아닌 다른 정수를 리턴하고(에러), ACE_OS::last_error() 하면 64번이 리턴됩니다. ACE를 사용하지 않는 경우에는 Read/Write 혹은 GetQueuedCompletionStatus에서  에러가 발생하고 GetLastError하면 64번이 리턴되겠죠.

다른 분의 설명으로는 accept에서도 발생가능한데, AccpEx호출 시 backlog에 있던 소켓이 accept가 되기 전에 접속을 끊어도 이 에러가 발생한다고 합니다.  아마도 이 글이 그러한 상황인 것 같습니다.

요약하면 ERROR_NETNAME_DELETED가 발생하는 경우는 상대방이 HardClose한 상황 이므로 그냥 종료처리하면 된다 입니다.