2009-05-28 11 views
1

私の会社が生産するデバイスからの信号を受信するネットワークサーバーで問題が発生しました。デバイスは、たまに使用した送信元ポートを再利用することがあります。これにより、サーバーによってSYNが削除されます。古いソケットがサーバー上のTIME_WAITから脱落するまで、デバイスは再試行します。サーバは次にSYN-ACKを送ります。JavaネットワークサーバーとTIME_WAIT

サーバーはJavaで書かれています。残念ながら、ポートを正しく循環させるためにデバイスを変更することはオプションではありません。フィールドには数が多く、既存のユニットを更新することはオプションではありません。古いソフトウェアはC++で書かれていて、Windows TCPスタックのリストからTIME_WAITポートを削除していました。

WindowsでJavaからTIME_WAITを回避する方法については、誰にでも助言できますか?

編集:私は実際にデバイスが最近使用されたポートを再利用していることをWiresharkで確認しました。

socket = new ServerSocket(); 
socket.setPerformancePreferences(3, 2, 1); 
socket.setReuseAddress(true); 
socket.setSoTimeout(CLIENT_READ_TIMEOUT); 
socket.bind(new InetSocketAddress(group.getPort()), MAX_TCP_BACKLOG); 

を、クライアントソケットが受信した後、次のように設定しています:私は、次のオプションを使用していますサーバソケット上で

私は真と偽の両方としてSO_LINGERを試してみました

Socket client = server.accept(); 
client.setKeepAlive(false); 
client.setSoLinger(true, 0); 
client.setReuseAddress(true); 
client.setTcpNoDelay(true); 
client.setSoTimeout(CLIENT_READ_TIMEOUT); 

を、まったく同じトレース結果となります。 CLIENT_READ_TIMEOUTは10秒に設定されます。

答えて

3

TIME_WAITを回避するために、古いない推奨トリックは{ 1, 0 }SO_LINGERソケットオプションを設定することである - そして、代わりに通常のフラッシュ/ 4ウェイ交換シーケンスを行うのRSTを送信close、これTIME_WAITを避け、すべて一緒に(警告されます - あなたはまだ送信バッファにあるものの尾を失う可能性があります。)私はこれがJavaで行うことができるかどうかについてはコメントできません。

編集:tcpdumpで、クライアントが実際に送信元ポート番号を再使用することを確認できますか。そうでない場合、Jonが指摘したようにSO_REUSEADDRリッスンソケットオプションの古典的なケースかもしれません。ニコライの答えに

4

ビル、

Socket s; 
... 
s.setSoLinger(true,0); 

Javaで同等のでしょう。

EDIT:あなたが見たいかもしれない別のものは、setReuseAddress(true)です。

0

サーバは、古い送信元ポートを使用する新しいセッションのものと古いセッションの再送信を区別できないため、クライアントからのSYNパケットを無視しています。サーバー上のTIME_WAIT状態を回避する場合は、コントロールブロックテーブルのTIME_WAIT状態エントリをエージングするためのシステムタイマーインターバルを設定することにより、サーバーは既に終了しているセッションのSYN再送信をどのように適切に無視しますか?

関連する問題