【问题标题】:How to coordinate send and receive with UDF DatagramSockets如何使用 UDF DatagramSockets 协调发送和接收
【发布时间】:2011-10-10 14:42:44
【问题描述】:

我有一个集成测试需要协调两个DatagramSockets,每个都在自己的线程中运行。一个套接字等待通过对 receive() 的阻塞调用来读取数据。另一个socket需要调用send(),但是必须在receive()阻塞之后进行,否则数据会丢失。

代码有点像这样:

接收者

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));

我不愿意在 send() 调用之前放置一个 Thread.sleep(),尽管这可能足以让接收者阻塞。有没有优雅的方法来做到这一点?

【问题讨论】:

  • UDP 没有握手方法来协调此类工作。一个基本的解决方案是向接收器发送等待“就绪”信号的数据包,然后一旦发送者收到确认,实际数据就会通过。我没有将此作为答案发布,因为我确信有人可以指出更好的方法。也许this 会有所帮助?
  • 我也想过。我希望有一种方法可以与 Java 并发工具进行协调。

标签: java multithreading sockets udp


【解决方案1】:

在 send() 之前等待一个信号量。在 receive() 调用之前向一个单元发出信号。考虑到网络延迟,如果 UDP 回复在发出 receive() 调用并设置 rx 套接字之前返回,我会感到惊讶。您可以通过提高接收线程的优先级(或降低发送线程的优先级)来确保。

您可以在 send() 之后等待另一个信号量,并在 receive() 之后发出信号,以确保发送线程在 rx 完成之前不会再次尝试发送。不确定如何检测通信故障、IIRC、Java 信号量等待没有超时 :((

Rgds, 马丁

【讨论】:

  • 这可能已经足够好了,尽管它并没有完全消除竞争条件。我不确定您所说的“UDP 回复”是什么意思。目前,接收方不会将响应发送回发送方。 Java semaphores 是可中断的,您可以指定超时时间。
  • 我似乎误解了——如果接收方没有发送回复什么“数据将丢失”?我假设对方发送了一个 UDP 回复,如果接收线程没有等待它,该回复将被堆栈丢弃。
  • 如果还没调用receive(),发送方发送给接收方的数据会丢失。
  • 我了解您正在为测试中的通信模块创建存根,但单台机器上的生产设备是否共享内存?如果不是,那么信号量仅适用于您的测试,可能掩盖生产中存在的并发问题。同样,忽略发送方/接收方是否在共享内存的单台机器上,但我不明白为什么需要 UDP(只需使用带有信号量的通过共享内存的消息传递)
  • @TheCapn 也许我应该提供更多背景知识 :) 接收者是测试存根,发送者是生产代码。在真实环境中,我可以假设 UDP 接收器,它是在不同机器上运行的不同进程,将始终监听,因此无需协调。
猜你喜欢
  • 1970-01-01
  • 2019-12-30
  • 2014-07-15
  • 1970-01-01
  • 2013-12-09
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多