起因
有一天,我一个微信群内有一个小伙伴在群中求助,他在工作中对接了一个厂家的设备,要求使用udp协议向设备发送一个报文,厂家用UDP测试工具对接设备返回正常后,就将设备和发送的指令交给小伙伴,小伙伴在网上查找资料使用JAVA的DatagramSocket监听和发送数据,但是程序始终无法接收到正确的返回数据,程序后续需要使用设备返回的数据里边的其中几个字节。而工具测试的时候,却能正确的接收到返回的数据。
小伙伴自己尝试了一天都没有解决,于是就在群中求助。
过程
我当时对这个问题十分感兴趣,和小伙伴在群里交流了一段时间后,问题并未解决,于是,我就提出远程看一下代码,看一下能否解决这个问题。
远程之后,我看了一下代码,没有看出什么问题,于是,我就测试了一下,用工具监听端口,然后用程序发送数据,工具正确的接收到了返回数据。
然后又用工具发送数据,程序接收,结果,程序接收到的数据就不正确,工具接收到了83个字节的数据,但是程序只能接收到15个字节。大致程序如下
public static void main(String[] args){
byte[] data = "指令".getBytes(); //指令字节
DatagramSocket server = new DatagramSocket(888); //监听回信息端口
DatagramPacket packet = new DatagramPacket(data,data.length,InetAddress.getByName("目标ip"),999); //封装指令udp数据包
server.send(packet); //发送指令
byte[] buff = new byte[1024];
packet = new DatagramPacket(buff,1024);//定义缓冲区
server.receive(packet); //接收响应数据
System.out.println(new String(packet.getDate(),0,packet.getLength())); //打印接收到的数据
}
以上代码,是我存手敲的,没有捕获异常这些,如果尝试运行,请自行修改错误。
程序就大概是这个样子,总之,找不到程序有任何问题。
就在我准备放弃的时候,我突发奇想的,把工具从设备收到的数据,然后又用工具发给程序看一下。
结果,程序正确的接收到了数据,并没有任何异常,于是,我就猜测,可能设备厂家的程序返回的数据并非标准的UDP数据包,导致程序并没有完整的读取到所有数据。
解决
由于,我是第一次接触JAVA的UDP通讯,我也不知道该怎么解决,像之前遇到TCP协议的问题,一般就是,不使用封装好的工具,自己写一个Socket自己处理所有数据,就能解决问题。
于是,我就在网上查找相关资料,但是并没有查到什么有用的信息,有时候,搜索引擎就是这样,如果没有用正确的关键字,就找不到自己想要的东西。
于是,我就试着问了一下ChatGLM4(清华和一个叫智谱清言的公司合作的AI),AI给了我一个解决方案,使用DatagramChannel来接收数据
public static void main(String[] args) throws Exception {
// 打开 DatagramChannel
try (DatagramChannel channel = DatagramChannel.open()) {
// 绑定端口
channel.bind(new InetSocketAddress(888));
// 分配缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 发送数据到另一个节点
String message = "Hello P2P!";
buffer.put(message.getBytes());
buffer.flip();
channel.send(buffer, new InetSocketAddress("192.168.1.2", 999)); // 假设您知道另一个节点的IP和端口
// 接收数据
buffer.clear();
channel.receive(buffer);
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
System.out.println("Received: " + new String(data, "UTF-8"));
}
}