Java 传输时UDP数据包内容发生变化

Java 传输时UDP数据包内容发生变化,java,sockets,network-programming,udp,Java,Sockets,Network Programming,Udp,我正在编写一个服务器-客户机软件,其中客户机通过端口请求连接到服务器,服务器打开一个新端口并发送回新端口号。然后,客户端与RSA共享AES密钥加密和来自端口请求的端口通信 嗯,应该是这样的 我的程序已经在运行了,只有一个客户端可以连接到服务器,而且一切正常。但是现在我将向服务器发送一个“portreq”字符串,它将给出一个端口回复。但是当我检查时,如果传入的请求是一个“portreq”,它会给出false。如果我也这样做。它给我真实的。这是第一个问题,第二个问题: 当服务器将端口整数转换为字符串

我正在编写一个服务器-客户机软件,其中客户机通过端口请求连接到服务器,服务器打开一个新端口并发送回新端口号。然后,客户端与RSA共享AES密钥加密和来自端口请求的端口通信

嗯,应该是这样的

我的程序已经在运行了,只有一个客户端可以连接到服务器,而且一切正常。但是现在我将向服务器发送一个“portreq”字符串,它将给出一个端口回复。但是当我检查时,如果传入的请求是一个“portreq”,它会给出false。如果我也这样做。它给我真实的。这是第一个问题,第二个问题:

当服务器将端口整数转换为字符串并发送时,我无法在客户端再次将其转换为int:

java.lang.NumberFormatException: For input string: "6002������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:580)
    at java.lang.Integer.parseInt(Integer.java:615)
    at application.PowerPanelController.addDataToCpu(PowerPanelController.java:360)
    at application.PowerPanelController.lambda$0(PowerPanelController.java:143)
    at application.PowerPanelController$$Lambda$200/357277047.handle(Unknown Source)
    at com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:226)
    at com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:167)
    at javafx.animation.Timeline.impl_playTo(Timeline.java:176)
    at javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
    at com.sun.scenario.animation.shared.InfiniteClipEnvelope.timePulse(InfiniteClipEnvelope.java:110)
    at javafx.animation.Animation.impl_timePulse(Animation.java:1102)
    at javafx.animation.Animation$1.lambda$timePulse$25(Animation.java:186)
    at javafx.animation.Animation$1$$Lambda$186/1977464318.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at javafx.animation.Animation$1.timePulse(Animation.java:185)
    at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
    at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:447)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:431)
    at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$363(QuantumToolkit.java:298)
    at com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$42/317723766.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
我不明白,因为字符串看起来和我发送的差不多

这是我的客户端发送和接收功能

private String sendCommandNoAES(String command)
{
    byte[] outData = new byte[1024];
    byte[] inD = new byte[1024];
    String message = "";
    try
    {
        // create Socket
        DatagramSocket socket = new DatagramSocket();
        // build Packet
        InetAddress serverIP = InetAddress.getByName(PowerPanelMain.ip);
        outData = command.getBytes();
        DatagramPacket out = new DatagramPacket(outData,outData.length, serverIP, PowerPanelMain.port); // send packet
        socket.send(out);
        logger.info("Sent an " + command + " Request non encrypted to " + PowerPanelMain.ip + ":" + PowerPanelMain.port);
        // Receive answer
        byte[] inData = new byte[1024];
        DatagramPacket in = new DatagramPacket(inData,inData.length);
        socket.receive(in);
        inD = in.getData();
        message = new String(inD,0,inD.length);
        // Close Socket
        socket.close();

        logger.info("Go answer " + message + " from " + in.getAddress().toString() + ":" + in.getPort());
    }
    catch(Exception ee)
    {
        logger.error("Error while requesting data from server \n" + getStackTrace(ee));
        return "offline";
    }
    return message;
}
这是我发送portreq的地方:

String portString = sendCommandNoAES("portreq");
int port = Integer.parseInt(portString);
这就是服务器代码:

byte[] inData = new byte[1024];
        byte[] outData = new byte[1024];
        String message;

        DatagramSocket socket = null;
        try
        {
            socket = new DatagramSocket(port);
            System.out.println("Bound to " + port);
            //JOptionPane.showMessageDialog(null, "Bound to " + String.valueOf(port), "Yeay", JOptionPane.OK_CANCEL_OPTION);
        }
        catch(Exception ee)
        {
            JOptionPane.showMessageDialog(null, "Error occured! \n#002", "Error #002", JOptionPane.OK_CANCEL_OPTION);
        }


我真的很感谢任何能为我解答/解释为什么会发生这种情况的人:D

您正在发送一个大小相同的字符串,而在另一端您正在读取1024字节的字符串,而您从未发送过。这不行。您应该使用serialize()方法序列化字符串,或者,如果要发送原始字符串字节,请将字符串长度作为消息的单独部分发送

inD = in.getData();
这只是重申了同样的价值。移除

message = new String(inD,0,inD.length);
错。您忽略了接收到的数据报的实际长度。改为:

message = new String(in.getData(), in.getOffset(), in.getLength());

是否可能
portString
包含网络中嵌入的空字符?请参见此处:
DatagramPacket
已包含实际数据长度。@EJP,如果试图读取的数据比字符串中的数据多得多,则从错误中可以清楚看出。我发现遵循发布的代码有点困难,但问题的根源是无可争议的——有人从字符串中读取的字节数超过了传递的字节数。当然这很清楚,但当UDP已经为您传输了长度,并且当
DatagramPacket
有API提供给您时,您不必传输长度。@EJP,前提是数据报中除了字符串之外没有其他内容。这里是这样吗?不,只提供了
DatagramPacket.getLength()
可以工作,不管数据报包含什么内容。
message = new String(inD,0,inD.length);
message = new String(in.getData(), in.getOffset(), in.getLength());