9

序章

私のクライアント アプリケーションの 1 つのインスタンスは、リモート サーバーへの 2 つの送信 TCP 接続 (メイン接続ファイル転送接続) を作成します。

クライアント アプリケーションが強制的に閉じ られると、両方のソケット接続が切断されたことをサーバーが認識しないことがあります。

サーバーは、両方の接続がドロップされたこと、または望ましくないメイン接続のみがドロップされたことを検出します。

問題が発生するのは複数のテスト マシンのうちの 1 つだけであること、およびクライアントが強制的に閉じられたときにファイル転送接続がアクティブにデータを送信していることを理解してください。

ネットワーク トラフィックを分析したところ、OS が実際には 2 つのRSTフラグを認識していたことがわかりました。このため、問題はサーバー コードにあると考えがちです。

コード

メソッドを使用するSocket.BeginReceiveと、主に切断の検出を担当するコールバックは次のようになります。

private void ReadCallback(IAsyncResult asyncResult) 
{
    try 
    {
        int bytesTransferred = _clientSocket.EndReceive(asyncResult);
        _logger.Debug(GetHashCode() + " Received " + bytesTransferred + " bytes from " + RemoteEndPoint);

        if (bytesTransferred > 0) 
        {
            _clientSocket.BeginReceive(_readMessageBuffer, ReadCallback);
            _logger.Debug(GetHashCode() + " Issued asynchronous read for " + RemoteEndPoint);
        } 
        else 
        {
            _logger.Debug(GetHashCode() + " Client disconnected. Received zero bytes. ");
        }
    } 
    catch (SocketException socketException) 
    {
        _logger.DebugException(GetHashCode() + " Client disconnected. SocketException thrown", socketException);
    }
    catch (ObjectDisposedException objectDisposedException)
    {
        _logger.DebugException(GetHashCode() + " Client disconnected. ObjectDisposedException thrown", objectDisposedException);
    }
    catch (Exception exception) 
    {
        _logger.DebugException(GetHashCode() + " Client disconnected. Exception thrown", exception);
    }
}

問題を切り分けるために、データの一部がネットワークから読み取られるたびにサーバーが非同期読み取りのみを発行するように、コードを削除しました。

特定のマシンでサーバー アプリケーションが常に両方のソケットの切断を検出しない理由について、誰か洞察や憶測を共有していただけませんか?


これは、基になるソケット接続が両方ともドロップされたことをサーバー アプリケーションが認識できなかった場合に生成される、変更されていないログです。

これは、基になるソケット接続が両方ともドロップされたことをサーバー アプリケーションが正常に確認したときに生成される未変更のログです。

4

3 に答える 3