2011-07-21 28 views
1

我有一個集成測試,需要協調兩個DatagramSockets,每個都在自己的線程中運行。一個套接字等待通過阻塞調用receive()來讀取數據。另一個套接字需要調用send(),但是這必須在receive()被阻塞之後發生,否則數據將會丟失。如何使用UDF協調發送和接收DatagramSockets

的代碼是一個有點像這樣:

接收機

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

發件人

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

我不願意前把一個Thread.sleep()方法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

這可能是go足夠的,儘管它並沒有完全消除競爭條件。我不確定'UDP回覆'是什麼意思。目前,接收方不會將回復發回給發件人。 [Java信號量](http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html)是可中斷的,您可以指定超時。 – hertzsprung

+0

我似乎誤解了 - 接收方不會回覆什麼'數據會丟失'?我假設對方發送了一個UDP回覆,如果接收線程沒有等待它,它將被堆棧丟棄。 –

+0

如果receive()尚未被調用,則從發送方發送到接收方的數據將會丟失。 – hertzsprung