我正在开发一个Java工具来测试与嵌入式设备的RPC通信。我们使用UDP(这是接口要求的一部分),并且有自己的机制来处理错误和丢弃数据包。
我有一些客户端和服务器代码使用DatagramChannel
来发送/接收数据。它们打开的东西近似于下面的东西,然后装饰着一些其他ByteChannel
装饰器。我正在使用连接,主要是因为我喜欢利用read/write
方法,而不是必须使用send/receive
。
DatagramChannel channel =
DatagramChannel.open(StandardProtocolFamily.INET)
.setOption(StandardSocketOptions.SO_REUSEADDR, true)
.bind(localAddress/localPort) // SocketAddress
.connect(remoteAddress/remotePort); // SocketAddress
channel.configureBlocking(true);
我正在测试代码的机器运行Win7 64位,并有两个专用适配器,一个配置为localAddress
,另一个配置remoteAddress
。
在此计算机上运行该工具(一个配置为服务器,另一个配置为客户端)时,客户端可以成功将数据写入通道,然后服务器将从其通道读取数据。然后,服务器将对其通道写入响应,但客户端将永远被阻止,从不接收数据。在WireShark中观察交换表明,所有数据都是在客户端适配器上接收的。
客户端:
// writer thread
ByteBuffer source; // contains some data
channel.write(source) // causes the datagram to be sent to the server
// reader thread
ByteBuffer dest;
channel.read(dest); // blocks awaiting server's response, which never
// arrives.
服务器:
ByteBuffer dest; // destination for data
channel.read(dest); // blocks until datagram from client is available
// do some stuff with data found in buffer
ByteBuffer response;
channel.write(response); // causes response datagram to be sent to client
// WireShark shows the packet on both adapters.
// Server sends, client adapter receives
有趣的是,当在另一台机器上运行客户端代码,并与目标设备作为服务器(而不是我的模拟服务器代码)进行通信时,交换机没有问题。我还为客户端使用DatagramSocket
给了它一个镜头,同时仍在服务器上运行DatagramChannel
,这似乎也有效。我在套接字上调用send
,其中DatagramPacket
包含我将写入通道的数据,然后receive
作为响应,阻塞直到包含响应的数据报到达。
这似乎是Windows的问题,但我想确定,并且想知道我是否遗漏了一些东西。除了WireShark之外,我还会去哪里诊断socket读取?我发现SocketSniff,但它似乎不适用于Java进程。