2

タイトルにあるように、I / O完了ポートに関連付けられたソケットで正常 WSASendに呼び出された場合、スレッドの終了以外の理由で完了を通知しない可能性はありますか?

完了が投稿されていないように見える奇妙な状況がありWSASend、その結果、ソケットリークが発生します。アプリケーションは、送信がまだソケットに対して保留中であると見なし、それを解放することを拒否します。

送信コードは次のとおりです。

void CSocketServer::Write(
    Socket *pSocket,
    CIOBuffer *pBuffer) const
{
    pSocket->AddRef();

    pBuffer->SetOperation(IO_Write_Completed);
    pBuffer->SetupWrite();
    pBuffer->AddRef();

    DWORD dwFlags = 0;
    DWORD dwSendNumBytes = 0;

    if (SOCKET_ERROR == ::WSASend(
        pSocket->m_socket,
        pBuffer->GetWSABUF(), 
        1, 
        &dwSendNumBytes,
        dwFlags,
        pBuffer, 
        NULL))
    {
        DWORD lastError = ::WSAGetLastError();

        if (ERROR_IO_PENDING != lastError)
        {
            pSocket->OnConnectionError(WriteError, pBuffer, lastError);

            pSocket->WriteCompleted();  // this pending write will never complete...

            pSocket->Release();
            pBuffer->Release();
        }
    }
    // Note: even if WSASend returns SUCCESS an IO Completion Packet is 
    // queued to the IOCP the same as if ERROR_IO_PENDING was returned.
    // Thus we need no special handling for the non error return case.
    // See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q192800
    // for details.
}
4

2 に答える 2

2

を使用して成功した通話の完了をオフにするなど、ファンキーな新機能のいずれかを使用していFILE_SKIP_COMPLETION_PORT_ON_SUCCESSますか?

送信に対して何らかのフロー制御を行っていますか、それとも好きなときに好きなだけ送信していますか?TCPスタックが輻輳制御を行っており、データをまだ送信できないため、表示される可能性があるのは単にSLOW完了です。制御されていない方法でデータを送信し続けると、完了に時間がかかり始める状況に陥ることがよくあります。特に、TCP接続がデータを反対側に正常に取得するよりも速い速度でデータを送信している場合、特にTCPウィンドウがそれほど大きくない場合。詳細については、http://www.lenholgate.com/blog/2008/07/write-completion-flow-control.htmlを参照してください。

もちろん、それは単に送信ロジックのバグである可能性があります。コードを投稿できますか?

WSARecv()とUDPには既知のバグがあることに注意してください(したがって、質問とはまったく関係ありません)。FILE_SKIP_COMPLETION_PORT_ON_SUCCESSこれにより、データグラムが指定したバッファーよりも大きく、WSARecv()呼び出しによって生成された場合の状況がわかります。 WSAEMOREDATA; ここを参照してください:http://www.lenholgate.com/blog/2010/01/file-skip-completion-port-on-success-and-datagram-socket-read-errors.html

于 2011-03-31T07:48:22.567 に答える
1

OVERLAPPED構造体の有効な下位ビットを設定することにより、完了ポートがポストされないようにすることができますhEvent

のドキュメントからGetQueuedCompletionStatus

完了ポートに関連付けられたファイルハンドルと有効なOVERLAPPED構造体を関数に渡した場合でも、アプリケーションは完了ポートの通知を防ぐことができます。これは、OVERLAPPED構造体のhEventメンバーに有効なイベントハンドルを指定し、その下位ビットを設定することによって行われます。下位ビットが設定されている有効なイベントハンドルは、I/O完了が完了ポートにキューイングされないようにします。

于 2011-03-31T13:52:00.133 に答える