2011-12-03 15 views
3

私は最近Javaアプリケーションの操作上の問題を調査していました。 processAとprocessBの2つのプロセスが同じホスト上で実行されています。ソケットソケットの#接続タイムアウトのJava

processAはprocessBにソケット接続を行います。 processBが再起動されましたが、何とか再起動後、processAからのすべてのSocket#connect呼び出しがブロックされました(分)。

私はprocessBがどうにかしてソケットが壊れた状態(SYNを受け取っていますが応答しない)であったと思います。問題はそれ自体が修正されました(自動再起動)ので、確実にtcpトラフィックを取得できませんでした。

私のソケットクライアントは接続時に短いタイムアウトが必要であることがわかります(この場合、デフォルトは大量です)。

私は、ソケットクライアントのテストに失敗した方法を書いているかどうか不安でした。

はこのような何かをすることが可能です:

@Test 
public void testClientTimeoutOnConnectionAttempt() { 
    startBrokenSocketServer() 
    assertConnectionExceptionWithinOneSecond(myClient); 
} 

私は手動でIPFWとのnetcatを使用して、これらの条件を作成する方法を考え出しました。

sudo ipfw add 100 drop ip from 127.0.0.1 6969 to any 
nc -l -p 6969 

(RST ACKを送信し、OSを防止する)、6969に耳を傾け、そしてIPFWは、NCから任意SYN_ACK受信私のJavaプロセスを妨げNC。

Socket#connectでタイムアウトを設定しないと、SocketExceptionの前に75秒(mac osで)かかりました。タイムアウトを指定すると、それより早く失敗します。

私が変更する必要があるクライアントは、別のチームに所属しています。私はそれを実証する自動化されたテストと一緒にそれらの修正を出荷したいと思います。どのようにそれを行う上の任意のアイデアですか?

答えて

2

私は、ソケットクライアントに失敗したテストを書く方法について興味がありました。

Javaではこれが可能ではないと思います。確かにnetcatの機能の多くではシミュレートできますが、ipfwではシミュレートできません。私はあなたが非常にOS特有のカーネルコールをしない限り、C言語でも可能であるとは確信していません。

私はJavaからできることは、存在しないホストに接続することだと思います。ローカルのイーサネットハードウェアが速く失敗する可能性があるため、存在しないローカルネットワーク上のIPに接続するだけでは問題ありません。あなたが望むのは、存在しないことが分かっているリモートネットワーク上の無効なIPに接続することです。あなたのローカルネットワークに対応していない10-netアドレスを選ぶことが効果的かもしれません。

不明な回答ですが、他の方法では見えません。

+0

グレーありがとうございます。それは助けになる。おそらく、これらのことを捕まえる最良の方法は、findbugのようなコード解析ツールを使うことです。私は、タイムアウトなしで接続のバージョンを避けるべきだと思います。 – darraghc

+0

うん、合意した。これは、Cの世界でさえ長い間真実でした。デフォルトのカーネルのタイムアウトは、現代のすべてのWebアプリケーションの99%でちょうどはるかに長い分のようなものです。 – Gray

関連する問題