Java UDP客户端接收服务器返回结果异常问题求助
问题修复:UDP客户端无法正确显示服务器返回的二进制IP
错误原因
客户端直接打印DatagramPacket对象,而该类默认的toString()方法返回的是对象的内存标识(如java.net.DatagramPacket@12d4bf7e),并非数据包中的实际内容。需要从DatagramPacket中提取字节数据并转换为字符串才能显示正确结果。
修复方案
修改客户端中接收数据后的打印逻辑,从DatagramPacket的字节缓冲区中提取有效数据并转换为字符串:
修改后的客户端代码
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; public class SocketUDPClientIP { public static void main(String[] args) throws IOException { Scanner scanner = new Scanner(System.in); DatagramSocket clienteSocket = new DatagramSocket(); InetAddress ipServidor = InetAddress.getLocalHost(); int puerto = 6666; System.out.println("PROGRAMA CLIENTE INICIADO...."); while (scanner.hasNextLine()) { // 替换hasNext()为hasNextLine()避免换行问题 System.out.println("Introduzca una IP en formato decimal:"); String ipAd = scanner.nextLine(); System.out.println("Socket Cliente envía IP " + ipAd); byte[] enviados = ipAd.getBytes(); // Enviar DatagramPacket envio = new DatagramPacket(enviados, enviados.length, ipServidor, puerto); clienteSocket.send(envio); byte[] recibidos = new byte[1024]; DatagramPacket recibo = new DatagramPacket(recibidos, recibidos.length); clienteSocket.receive(recibo); System.out.println("Socket Cliente esperando Datagrama del Socket Servidor .........."); // 修复:提取数据包中的有效字节并转换为字符串 String binaryIp = new String(recibo.getData(), 0, recibo.getLength()).trim(); System.out.println("IP " + ipAd + " en binario: " + binaryIp); if (ipAd.equals("0.0.0.0")) { break; } } clienteSocket.close(); // 关闭socket释放资源 scanner.close(); } }
额外优化(服务器端)
服务器端目前缺少对输入IP的合法性校验(比如输入非IP格式字符串会抛出ArrayIndexOutOfBoundsException或NumberFormatException),可以添加简单的校验逻辑:
// 替换服务器中解析IP的部分 String ipAd = new String(recibo.getData()).trim(); System.out.println("Recibiendo del CLIENTE: \n\t" + ipAd); String[] ipAdS = ipAd.split("\\."); String ipAdBinary = ""; // 校验IP格式是否为四段数字 if (ipAdS.length != 4) { ipAdBinary = "El IP " + ipAd + " es un IP no valida, introduzca otra IP"; } else { try { int ipAd1 = Integer.parseInt(ipAdS[0]); int ipAd2 = Integer.parseInt(ipAdS[1]); int ipAd3 = Integer.parseInt(ipAdS[2]); int ipAd4 = Integer.parseInt(ipAdS[3]); if (ipAd1 >=0 && ipAd1 < 256 && ipAd2 >=0 && ipAd2 < 256 && ipAd3 >=0 && ipAd3 < 256 && ipAd4 >=0 && ipAd4 < 256) { String ipad1S = Integer.toBinaryString(ipAd1); String ipad2S = Integer.toBinaryString(ipAd2); String ipad3S = Integer.toBinaryString(ipAd3); String ipad4S = Integer.toBinaryString(ipAd4); ipAdBinary = ipad1S + "." + ipad2S + "." + ipad3S + "." + ipad4S; } else { ipAdBinary = "El IP " + ipAd + " es un IP no valida, introduzca otra IP"; } } catch (NumberFormatException e) { ipAdBinary = "El IP " + ipAd + " es un IP no valida, introduzca otra IP"; } } System.out.println(ipAdBinary);
关键修改点说明
- 客户端中使用
new String(recibo.getData(), 0, recibo.getLength()).trim()提取数据包中的有效数据,recibo.getLength()可以获取实际接收的字节数,避免缓冲区中多余的空字符影响结果。 - 将
scanner.hasNext()改为scanner.hasNextLine(),解决第一次输入时可能出现的空字符串问题。 - 服务器端添加格式和数字校验,避免非法输入导致程序崩溃。
内容的提问来源于stack exchange,提问作者Tuan Do
相关产品推荐
相关产品推荐

