0

I/O-Completion Port を使用して、小さなサーバー クライアントのようなものを書いています。

サーバーとクライアントは、完了ポートを介して AcceptEx 経由で正常に接続されます。クライアントが接続した後、クライアント ソケットは完了ポートに関連付けられ、そのソケットで WSARecv へのオーバーラップ呼び出しが呼び出されます。

クライアント テスト プログラムを閉じるまでは、すべて問題なく動作します。 GetQueuedCompletionStatus()リターンFALSEGetLastErrorリターン

ERROR_NETNAME_DELETED

、これは私には理にかなっています (MSDN の説明を読んだ後)。

しかし、私の問題は、呼び出しが適切な戻り値を返すGetQueuedCompletionStatusため、ソケットの閉鎖による失敗を示すパケットを返すと思ったことです。WSARecvこれは当てはまらないので、どのクライアントのソケットがエラーを引き起こしたのかわからず、必要な方法で動作できません (構造の解放、この特定の接続のクリーンアップなど)...

これを解決する方法に関する提案、またはヒントはありますか?

ありがとう:)

編集: http://codepad.org/WeYINa ​​sO <- 責任のあるコード... "エラー" は、while ループの最初の関数で発生します (呼び出しGetCompletionStatus()は、GetQueuedCompletionStatus() のラッパーであり、正常に動作します)他のケース) [ここはくだらない&乱雑に見えるので、そこに投稿しました]

4

2 に答える 2

6

を呼び出すときに注意する必要があるシナリオは次のGetQueuedCompletionStatusとおりです。

  • GetQueuedCompletionStatus戻り値TRUE:成功した完了パケットが受信され、すべての出力パラメーターが入力されました。
  • GetQueuedCompletionStatus戻り値FALSE, lpOverlapped == NULL:キューから取り出されたパケットはありません。その他の出力パラメータには、不定値が含まれています。
  • GetQueuedCompletionStatus戻り値FALSE, lpOverlapped != NULL:関数は、失敗した完了パケットをキューから取り出しました。エラー コードは、 から入手できますGetLastError

あなたの質問に答えるために、 とがGetQueuedCompletionStatus返されたときに、I/O の完了に失敗しました。気にする必要があるのは、 の値です。FALSElpOverlapped != NULLlpOverlapped

于 2011-03-29T18:30:00.197 に答える
1

私はこれが古い質問であることを知っていますが、ERROR_NETNAME_DELETED. オーバーラップを行っているときに発生するエラーReadfile()です。

closesocket()いくつかのデバッグの後、ソケットに書き込みを行っていたが、使用する前に呼び出すのを忘れていたプログラムが問題の原因であることが判明しましたExitProcess()(ガベージ コレクションの問題のため)。を呼び出しCloseHandle()てもエラーは回避されず、WSACleanup()beforeを追加することもできませんでしたExitProcess()。ただし、クライアントが終了する前に短いスリープを追加すると、エラーは回避されました。たぶん、回避ExitProcess()することで問題も回避できたでしょう。

したがって、ソケットを適切に閉じずにプログラムが終了することが問題の原因であると思われます。

ソケットが単なる通常のファイル記述子である Unix では、これが問題になるとは思いません。

于 2012-01-26T00:59:15.040 に答える