2011-07-21 22 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