我正在构建一个可以与一系列不同服务器通信的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(),将数据分派到适合我应用程序预期响应的位置?
答案 0 :(得分:0)
如果您只使用一个通道(以及一个绑定的本地端口),则需要避免使用connect
和write
方法。相反,请使用send
方法。
send
方法。在rewind()
之后,您可能需要send
字节缓冲区......我不确定send
是否克隆了缓冲区。receive
获取返回的数据(缓冲区参数)和返回它的服务器(方法返回值)。继续循环,直到服务器列表耗尽,但你想在循环本身上设置一个时间限制(对于死服务器或丢失的数据包)理想情况下,在接收循环中,您希望接收方法在超时前暂停一段时间。如果找不到配置阻塞的方法,可以使用非阻塞,并在循环中放入Thread.sleep。试着让定时阻止工作,这是最好的方式。
答案 1 :(得分:-2)
您应该为要与之通信的每个服务器打开一个单独的数据报通道,并将该通道的管理(读/写)移交给单独的线程。