2011-07-21 6 views
1

DatagramSocketsを調整する必要のある統合テストがあり、それぞれ独自のスレッドで実行されています。 1つのソケットはreceive()へのブロッキング呼び出しでデータを読み込むのを待ちます。他のソケットはsend()を呼び出す必要がありますが、これはreceive()がブロックされた後でなければなりません。そうしないと、データが失われます。UDFデータグラムソケットで送受信を調整する方法

コードは少し、このようなものです:

レシーバー

byte[] buf = new byte[1024]; 
new DatagramSocket(7654).receive(new DatagramPacket(buf, buf.length)); 

送信者、私は前のThread.sleep()を入れて嫌がってる

new DatagramSocket(7654).send(
    new DatagramPacket("hello".getBytes(Charset.forName("UTF-8")), 5)); 

send()を呼び出すことができますが、受信者がブロックできるようにするには十分です。これを行うエレガントな方法はありますか?

+0

UDPは、この種の作業を調整するためのハンドシェイクメソッドを持っていない初歩的な。解決策は受信機に「準備完了」信号を待っているパケットを送信することです。送信者が実際のデータを受信すると確認が受信されると、私はこれを返信しませんでした。誰かがあなたを指すことができます。[this](http://www.oracle.com/technetwork/java/socket-140484.html#multi)は役に立ちますか? – Grambot

+0

私はそれも考えていました。 Javaの並行性ツールを使って物事を調整する方法があるかもしれません。 – hertzsprung

答えて

1

send()の直前にセマフォを待つ。 receive()コールの直前にシグナルを送ります。ネットワークの遅延があると、receive()呼び出しが行われてrxソケットが設定される前に、UDP応答が返ってきたら驚くでしょう。受信スレッドの優先度を上げる(または送信スレッドの優先度を下げる)ことで確実に確認できます。

send()の後に別のセマフォを待ってからreceive()の後にシグナルを送ることで、rxが完了するまで送信スレッドが再度送信を試みないようにすることができます。 IIRC、あなたが途切れ障害を検出する方法をわからない、Javaのセマフォ待ちがタイムアウトを持っていない:((

RGDS、 マーティン

+0

これはおそらく行くでしょうそれは競争状態を完全に排除するものではありません。私はあなたが何を意味するのかわからない 'UDPの返信'。現時点では、受信者は送信者に返信しません。 [Javaセマフォ](http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html)は中断可能で、タイムアウトを指定できます。 – hertzsprung

+0

私は誤解しているようです - 受信者は「データが失われる」という返信をしません。私は、受信スレッドがそれを待っていなかった場合に、ピアがスタックによって破棄されるUDP応答を送信したと仮定しました。 –

+0

receive()がまだ呼び出されていなければ、送信者から受信者に送信されたデータは失われます。 – hertzsprung

関連する問題