IOCPスレッドからWSAGetLastError()を呼び出すと、誤った結果が返されます

トム

私はWSARecv()どちらが戻ったかを呼び出しましWSA_IO_PENDING次にRST、もう一方の端からパケットを送信しました。GetQueuedCompletionStatus()別のスレッドに存在する関数が戻ってきたFALSE予想通り、私は呼ばれたときWSAGetLastError()、私は得た64代わりにWSAECONNRESET

では、なぜWSAGetLastError()戻ってこなかったのWSAECONNRESETですか?


編集:

パケットが受信されたために)WSAGetLastError()失敗した直後に呼び出すと、返されるエラーコードはであり、ではないことを忘れましたWSARecv()RSTWSAECONNRESET64

したがって、返されるエラーコードはWSARecv()、呼び出し直後に失敗したか、後で完了パケットを取得するときに失敗したかによって異なるようです。

ハンスパッサン

これはIOCPの一般的な問題であり、TCP / IPドライバースタックに対して低レベルの呼び出しを行っています。これは、すべてのドライバーがWindowsで行うように、NTSTATUSエラーコードで失敗を報告します。ここで予想されるエラーはSTATUS_CONNECTION_RESETです。

これらのネイティブエラーコードは、winapiエラーコードに変換する必要があります。この変換は通常、状況依存であり、どのwinapiライブラリがドライバーコマンドを発行したかによって異なります。つまり、変換を行ったのがWinsockライブラリである場合にのみ、WSAECONNRESETエラーを返すことができます。しかし、それはあなたのプログラムで起こったことではなく、エラーを処理したのはGetQueuedCompletionStatus()でした。

これは、任意のデバイスドライバーのIOCPを処理する汎用ヘルパー関数です。コンテキストはありません。OVERLAPPED構造は、I / O要求がどのように開始されたかを示すのにほぼ十分ではありません。回し、このKBの記事、それはWINAPIエラーコードにNTSTATUSエラーコードからデフォルトのマッピングを説明しています。GetQueuedCompletionStatus()が使用するマッピング。リストの関連エントリは次のとおりです。

STATUS_NETWORK_NAME_DELETED          ERROR_NETNAME_DELETED
STATUS_LOCAL_DISCONNECT              ERROR_NETNAME_DELETED
STATUS_REMOTE_DISCONNECT             ERROR_NETNAME_DELETED
STATUS_ADDRESS_CLOSED                ERROR_NETNAME_DELETED
STATUS_CONNECTION_DISCONNECTED       ERROR_NETNAME_DELETED
STATUS_CONNECTION_RESET              ERROR_NETNAME_DELETED 

これらは、ええと、素晴らしい選択ではありませんでした。おそらく、Lanmanが選択されたネットワーク層であった非常に初期のWindowsに戻ります。WSAGetLastError()は、ERROR_NETNAME_DELETEDをWSA固有のエラーにマップするのに非常に無力です。GetQueuedCompletionStatus()がスレッドの「最後のエラー」コードを設定すると、NTSTATUSコードが失われました。したがって、そうではなく、可能なものを返すだけです。


何がしたい期待することは、このエラーの翻訳は、Winsockの規則を使用して、正確に起こることができるようにWSAGetQueuedCompletionStatus()関数です。ありません。最近では、Windowsコードを適切に作成するための最終的な権限、つまりリファレンスソースから入手できる.NETFrameworkソースを使用することを好みますSocketAsyncEventArgs.CompletionCallback()メソッドのソースにリンクしました。キーが含まれています:

// The Async IO completed with a failure.
// here we need to call WSAGetOverlappedResult() just so Marshal.GetLastWin32Error() will return the correct error.
bool success = UnsafeNclNativeMethods.OSSOCK.WSAGetOverlappedResult(
    m_CurrentSocket.SafeHandle,
    m_PtrNativeOverlapped,
    out numBytes,
    false,
    out socketFlags);
socketError = (SocketError)Marshal.GetLastWin32Error();

つまり、GetLastError()から適切な戻り値を取得するには、WSAGetOverlappedResult()を追加で呼び出す必要がありますこれはあまり直感的ではありません:)

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

RxJava2は、呼び出されたメソッドでonSuccessからの結果をどのように返すことができますか?

分類Dev

Webサービスから配列を取得すると、誤った結果が返されます

分類Dev

別のメソッドが呼び出されるのを待ってから、結果を続行します

分類Dev

Python:ジェネレータオブジェクトでlist()を呼び出すと、誤った結果が生成されます

分類Dev

ストアドプロシージャから誤った結果が返されますか?

分類Dev

64ビットOfficeでMultiByteToWideChar()を呼び出すと、間違った結果が得られます

分類Dev

APIから新しい結果が返されたときに関数を呼び出す

分類Dev

APIから新しい結果が返されたときに関数を呼び出す

分類Dev

gdbで呼び出されたときにstrlenが誤った値を返す

分類Dev

EventListenerは、それを呼び出さなかったスレッドに戻っています。メインスレッドのメソッドを呼び出すと、デッドロックが発生します。

分類Dev

関数のアドレスをUINTPTR_Tにキャストすると、誤った結果が返されます

分類Dev

Android 10:「UIスレッドがブロックされているときにWebViewAPIが誤ったスレッドで呼び出されたためにデッドロックが検出された可能性があります」

分類Dev

Pythonからctypesを介して呼び出されたC関数が誤った値を返す

分類Dev

getOAuthTokenは、Googleスプレッドシートから呼び出されるとnullを返します

分類Dev

ライブラリなしでJPEGからDPIをフェッチすると、誤った結果が返されます

分類Dev

数値スライサーを適用すると、結果として誤った値が返されます

分類Dev

メソッド 'count'を呼び出すと、間違った数の引数が返されます

分類Dev

WindowsのJulia(0.6.2)から呼び出されたFortran関数の結果が間違っています

分類Dev

> =を使用すると、誤った結果が得られますか?

分類Dev

Angular 2オブザーバブルが変更されたとき/サービスが新しい結果を返したときにサービスメソッドを呼び出すにはどうすればよいですか?

分類Dev

インスタンス名から返されたメソッドを呼び出すことができません

分類Dev

ワーカースレッドから呼び出し元に結果を返す

分類Dev

SQLデータベースにレコードが存在するかどうかを確認すると、間違った結果が返されます

分類Dev

Mockito:任意のインスタンスがメソッドを呼び出すと、何かが返されます

分類Dev

Angularは、呼び出されたメソッドではなく、OPTIONSの結果を返します

分類Dev

文字列からintを解析すると、誤った結果が生成されます

分類Dev

mysql_fetch_assocを呼び出すと、複数回呼び出された場合でも、最初の結果のみが返されます(CLOSED:TYPO)

分類Dev

スレッド内からスレッドを繰り返し呼び出すことはできますか?

分類Dev

従来の方法で関数を呼び出すと良い結果が得られ、guitkinterで関数を呼び出すと例外がスローされます

Related 関連記事

  1. 1

    RxJava2は、呼び出されたメソッドでonSuccessからの結果をどのように返すことができますか?

  2. 2

    Webサービスから配列を取得すると、誤った結果が返されます

  3. 3

    別のメソッドが呼び出されるのを待ってから、結果を続行します

  4. 4

    Python:ジェネレータオブジェクトでlist()を呼び出すと、誤った結果が生成されます

  5. 5

    ストアドプロシージャから誤った結果が返されますか?

  6. 6

    64ビットOfficeでMultiByteToWideChar()を呼び出すと、間違った結果が得られます

  7. 7

    APIから新しい結果が返されたときに関数を呼び出す

  8. 8

    APIから新しい結果が返されたときに関数を呼び出す

  9. 9

    gdbで呼び出されたときにstrlenが誤った値を返す

  10. 10

    EventListenerは、それを呼び出さなかったスレッドに戻っています。メインスレッドのメソッドを呼び出すと、デッドロックが発生します。

  11. 11

    関数のアドレスをUINTPTR_Tにキャストすると、誤った結果が返されます

  12. 12

    Android 10:「UIスレッドがブロックされているときにWebViewAPIが誤ったスレッドで呼び出されたためにデッドロックが検出された可能性があります」

  13. 13

    Pythonからctypesを介して呼び出されたC関数が誤った値を返す

  14. 14

    getOAuthTokenは、Googleスプレッドシートから呼び出されるとnullを返します

  15. 15

    ライブラリなしでJPEGからDPIをフェッチすると、誤った結果が返されます

  16. 16

    数値スライサーを適用すると、結果として誤った値が返されます

  17. 17

    メソッド 'count'を呼び出すと、間違った数の引数が返されます

  18. 18

    WindowsのJulia(0.6.2)から呼び出されたFortran関数の結果が間違っています

  19. 19

    > =を使用すると、誤った結果が得られますか?

  20. 20

    Angular 2オブザーバブルが変更されたとき/サービスが新しい結果を返したときにサービスメソッドを呼び出すにはどうすればよいですか?

  21. 21

    インスタンス名から返されたメソッドを呼び出すことができません

  22. 22

    ワーカースレッドから呼び出し元に結果を返す

  23. 23

    SQLデータベースにレコードが存在するかどうかを確認すると、間違った結果が返されます

  24. 24

    Mockito:任意のインスタンスがメソッドを呼び出すと、何かが返されます

  25. 25

    Angularは、呼び出されたメソッドではなく、OPTIONSの結果を返します

  26. 26

    文字列からintを解析すると、誤った結果が生成されます

  27. 27

    mysql_fetch_assocを呼び出すと、複数回呼び出された場合でも、最初の結果のみが返されます(CLOSED:TYPO)

  28. 28

    スレッド内からスレッドを繰り返し呼び出すことはできますか?

  29. 29

    従来の方法で関数を呼び出すと良い結果が得られ、guitkinterで関数を呼び出すと例外がスローされます

ホットタグ

アーカイブ