2012-03-01 15 views
2

私は30台の車のモデムからのメッセージを聞いているアプリケーションを持っています。私は(エラー処理は省略さ)次のようになり、サーバーのコードを実装するTcpListenerを使用しました:なぜTcpListenerはESTABLISHED接続を漏らしていますか?

... 
listener.Start() 
... 
void 
BeginAcceptTcpClient() 
{ 
    if(listener.Server.IsBound) { 
     listener.BeginAcceptTcpClient(TcpClientAccepted, null); 
    } 
} 

void 
TcpClientAccepted(IAsyncResult ar) 
{ 
    var buffer = new byte[bufferSize]; 

    BeginAcceptTcpClient(); 
    using(var client = EndAcceptTcpClient(ar)) { 
    using(var stream = client.GetStream()) { 
     var count = 0; 
     while((count = stream.Read(buffer, total, bufferSize - total)) > 0) { 
      total += count; 
     } 
    } 
    DoSomething(buffer) 
} 

私が正しくメッセージを取得し、私の問題は、切断です。 12時間ごとにモデムがリセットされ、新しいIPアドレスが取得されますが、サーバーは古い接続をアクティブに保ち続けます(tcpviewにESTABLISHEDとしてマークされています)。古い接続のタイムアウトを設定する方法はありますか?私は、TcpClientを閉じることで、TCP接続が閉じられたと思っていました(ローカルテストではどうなりますか)、間違っていますか?

答えて

1

私は実際にコードサンプルで少し混乱しています - 質問は、これらの質問がかなり長い時間開いているが、コードは非常に短いバーストではより典型的であることを示唆しています;長時間実行している接続では、同期APIではなく、非同期APIの1つがここに表示されます。

トレースなしで停止するソケットは非常に一般的です。特に、すべてのシャットダウンを検出する必要がある多数の中間デバイスが搭載されている場合は非常に一般的です。無線ネットワークは、ソケットが人工的に生き残るようにしようとすることがあります。なぜなら、デバイスは毎回すべての接続を切断したくないからです。

このように、あなたがまだ本当に生きている人を追跡することができるように、接続でハートビートのいくつかの種類を実装するためにかなり一般的です。例として

- しかし19K接続 - 私は理論的にはどのハンドル正常な停止(閉鎖を示す特定の配列を介して)、及び(不意に接続を終了)無様ソケット閉鎖両方、ここでのWebSocketサーバを有します私は最後の1時間かそこらで見たことがある、70人はどちらかを打つことなく死んだ。そうではなく、私は(遅い)心拍に対して活動を追跡し、あまりにも長く応答しなければそれらを殺す。

再タイムアウト。 ReceiveTimeoutを試すことはできますが、通常はトラフィックの大きなギャップを予想していない場合にのみ役立ちます。

+0

私は、接続の受け入れにAsync APIを使用していますが、メッセージを読み取るための同期APIは1時間に1回または2回しかありません。私は、モデムがサーバに接続する方法(ハードウェアプロバイダがそれらを制御し、その動作を非常にうまく説明できなかった)をあまり制御できません。受け入れられたTcpClientのDispose()はクライアントとの接続を終了しませんか?私の問題は、クライアントが私の上で死んでいるということではなく、私の問題は彼らがIPを変えたときに彼らが死なないということです! –

+0

@Pabloあなたは明確にすることができます:一度クライアントが接続した - それはすぐにいくつかのデータを送信しますか?それともしばらく開いていますか? –

+0

クライアントが接続し、いくつかのデータを送信して...クローズしますか?それは問題の一部ですが、わかりません。私は接続のリセット(正常に受け入れられ、部分的なデータが使用されています)を受信しましたが、モデムを手動でリセットしても接続は常にESTABLISHED状態に保たれているようです。 –

関連する問題