(随笔)udp接收数据 bugfix
在学习udp数据通信的时候偶遇一个bug,具体代码如下
code
sender
package com.udpExample.chat; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; /** * TODO sender * * @author pangyangjian * @since 2023/9/7 20:02 */ public class UDPSender { public static void main(String[] args) throws Exception { DatagramSocket datagramSocket = new DatagramSocket(9090); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); while (true) { // 控制台读取数据 String s = bufferedReader.readLine(); byte[] bytes = s.getBytes(); DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress( "localhost", 9191)); datagramSocket.send(datagramPacket); if ("end".equals(s)) { break; } } datagramSocket.close(); } }
receiver
package com.udpExample.chat; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * TODO receiver * * @author pangyangjian * @since 2023/9/7 20:02 */ public class UDPReceive { public static void main(String[] args) throws Exception { DatagramSocket datagramSocket = new DatagramSocket(9191); while (true) { byte[] bytes = new byte[1024]; DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length); byte[] data = datagramPacket.getData(); String s = new String(data); System.out.println(datagramPacket.getAddress() + " " + s.trim()); if ("end".equals(s)) { break; } } datagramSocket.close(); } }
bug phenomenon
运行接收端的时候,控制台出bug,会一直输出null,不会等待接收sender发送的数据
解释
在receiver中,问题出现在以下行:
byte[] data = datagramPacket.getData(); String s = new String(data);
在这里先从datagramPacket
对象中获取了数据的引用,然后将其转换为字符串。然而,这是一个错误的方式。
在接收UDP数据报时,应该先调用receive()
方法来填充datagramPacket
对象数据,然后通过getData()
方法获取已接收的数据,而不是在还没有接收任何数据之前就尝试获取它。
以下是修复后的代码:
import java.net.DatagramPacket; import java.net.DatagramSocket; public class UDPReceive { public static void main(String[] args) throws Exception { DatagramSocket datagramSocket = new DatagramSocket(9191); while (true) { byte[] bytes = new byte[1024]; DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length); datagramSocket.receive(datagramPacket); // 接收数据 byte[] data = datagramPacket.getData(); String s = new String(data).trim(); System.out.println(datagramPacket.getAddress() + " " + s); if ("end".equals(s)) { break; } } datagramSocket.close(); } }
在修复后的代码中,我们通过调用datagramSocket.receive(datagramPacket)
来接收数据,该方法会在接收到数据之前一直阻塞。然后我们将接收到的数据转换为字符串,并使用trim()
方法去除首尾空格。
本文作者:Joseph·Jonardo
本文链接:https://www.cnblogs.com/Joseph-Jonardo/p/17687024.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步