发送时UDP包内容发生变化

时间:2015-12-07 16:52:14

标签: java sockets network-programming udp

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

嗯,它应该是那样的。

我已经运行了程序,只有一个客户端可以连接到服务器,一切正常。但现在我发送了一个" portreq"应该给出端口回复的服务器的字符串。但是当我检查时,如果传入的请求是" portreq"它让我虚伪。如果我对.contains做同样的话,它给了我真实的。这是第一个问题,其次是:

当服务器将port-Integer转换为String并发送它时,我无法再在客户端将其转换为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)

我没有得到,因为String看起来和我发送的几乎一样。

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

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);
        }

...

DatagramPacket in = new DatagramPacket(inData,inData.length);
                socket.receive(in);
                InetAddress senderIP = in.getAddress();
                int senderPort = in.getPort();
                byte[] inc = in.getData();
                message = new String(inc,0,inc.length);

                System.out.println("Got " + message + " from " + senderIP + ":" + senderPort + " (byte array: " + inc.toString());

...

if(message.contains("portreq"))
                    {
                        System.out.println("Creatinfg answer");
                        outData = String.valueOf(portcount).getBytes();
                        DatagramPacket out = new DatagramPacket(outData,outData.length, senderIP, senderPort);
                        socket.send(out);

                        System.out.println("Sent " + String.valueOf(portcount));

                        UDPTraffic udpt = new UDPTraffic(portcount, this.mode);
                        udpt.start();
                        portcount++;
                    }

我非常感谢能解决/解释我为何会发生这种情况的人:D

2 个答案:

答案 0 :(得分:0)

inD = in.getData();

这仅仅重申了相同的价值。删除。

message = new String(inD,0,inD.length);

错误。您忽略了接收数据报的实际长度。改为:

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

答案 1 :(得分:-1)

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