我正在使用完成端口在Windows NT中編寫一個tcp服務器來利用異步I/O。 我有一個TcpSocket類,一個TcpServer類和一些(虛函數)回調函數,以在I/O操作完成時調用,例如onRead()用於讀取完成時。我還爲連接建立時的onOpen()和連接關閉時的onEof()等等。 我總是有一個未決的讀取套接字,所以如果套接字有效地獲取數據(讀取將完成大小> 0)它調用onRead(),而不是如果客戶端關閉套接字從客戶端(讀取將以size == 0完成)它調用onEof(),並且服務器知道客戶端何時用closesocket(server_socket)關閉套接字;從它的側面。可以將臭名昭着的ERROR_NETNAME_DELETED錯誤視爲錯誤嗎?
所有工作正常,但我注意到一件事:
當我打電話關閉套接字(client_socket);在連接的服務器端端點上,而不是客戶端端(不管是否設置了linger {true,0}),掛起的讀操作將被錯誤地完成,即,讀大小不僅僅是= = 0,但GetLastError()返回一個錯誤:64或'ERROR_NETNAME_DELETED'。我在網上搜索了很多這方面的內容,但沒有發現任何有趣的內容。
然後我問自己:但這是一個真正的錯誤?我的意思是,這真的可以被認爲是一個錯誤?
問題是,在服務器端,當我closesocket(client_socket)時會調用onError()回調函數;而不是onEof()。所以我認爲這:
如果我收到這個'ERROR_NETNAME_DELETED'「錯誤」,請調用onEof()而不是onError()? 會引入一些錯誤或未定義的行爲? 讓我問這個問題的另一個重要的一點是:
當我收到這個讀取完成與「ERROR_NETNAME_DELETED」,我已經檢查重疊 結構,特別是其中含有NTSTATUS錯誤overlapped->內部參數代碼 的底層驅動程序。如果我們看到NTSTATUS錯誤代碼列表[http://www.tenox.tc/links/ntstatus.html] 我們可以清楚地看到'ERROR_NETNAME_DELETED'由NTSTATUS 0xC000013B生成,這是一個錯誤,但它被稱爲'STATUS_LOCAL_DISCONNECT'。那麼,它看起來不像一個錯誤的名稱。看起來更像是`ERROR_IO_PENDING',這是一個錯誤,也是一個正確行爲的狀態。
那麼如何檢查OVERLAPPED結構的內部參數,當這是=='STATUS_LOCAL_DISCONNECT'對onEof()回調執行調用?會搞砸了嗎?另外,我不得不說從服務器端,如果我調用 closesocket(client_socket)之前調用DisconnectEx();我不會收到那個錯誤。但是我不想調用DisconnectEx()?例如。當服務器關閉並且不想等待所有的DisconnectEx()完成時,只想關閉所有連接的客戶端。
@Hans,我認爲他在描述他是如何遇到這個錯誤方面做得非常出色。 –