具有多个服务器的Java NIO UDP客户端

时间:2014-01-14 20:39:44

标签: java udp nio

我正在构建一个可以与一系列不同服务器通信的UDP客户端。鉴于NIO应用程序涉及使用单个接收线程,如何将传入的数据报分发到我的应用程序的正确部分?即将传入的数据包与传出的数据包相关联。

理论上,在向服务器发送(或连接?)时,应该可以在传出数据报中获取源ip /端口,然后通过检查目标IP /端口将传入数据包识别为其响应。 (因为:http://www.dcs.bbk.ac.uk/~ptw/teaching/IWT/transport-layer/source-destination.gif

大多数UDP客户端示例似乎都假设使用单个服务器,因此将传入的数据报识别为对传出数据报的响应非常简单,例如:

ByteBuffer textToEcho = ByteBuffer.wrap("blah");
ByteBuffer echoedText = ByteBuffer.allocateDirect(MAX_PACKET_SIZE);

DatagramChannel datagramChannel = DatagramChannel.open(StandardProtocolFamily.INET)
datagramChannel.connect(new InetSocketAddress(REMOTE_IP, REMOTE_PORT));

while(true)
{
     int sent = datagramChannel.write(textToEcho);
     datagramChannel.read(echoedText);
}

也许我可以使用多个DatagramChannel并在每个上迭代调用read(),将数据分派到适合我应用程序预期响应的位置?

2 个答案:

答案 0 :(得分:0)

如果您只使用一个通道(以及一个绑定的本地端口),则需要避免使用connectwrite方法。相反,请使用send方法。

  1. 循环访问您的服务器,对每台服务器使用send方法。在rewind()之后,您可能需要send字节缓冲区......我不确定send是否克隆了缓冲区。
  2. 当所有服务器都已发送时:在循环中,只要有服务器没有响应,使用receive获取返回的数据(缓冲区参数)和返回它的服务器(方法返回值)。继续循环,直到服务器列表耗尽,但你想在循环本身上设置一个时间限制(对于死服务器或丢失的数据包)
  3. 理想情况下,在接收循环中,您希望接收方法在超时前暂停一段时间。如果找不到配置阻塞的方法,可以使用非阻塞,并在循环中放入Thread.sleep。试着让定时阻止工作,这是最好的方式。

答案 1 :(得分:-2)

您应该为要与之通信的每个服务器打开一个单独的数据报通道,并将该通道的管理(读/写)移交给单独的线程。