UDP 数据包内容在传输时发生变化
UDP Packet content changes while transmitting
我正在编写一个服务器-客户端软件,其中客户端通过端口请求连接到服务器,服务器打开一个新端口并发回新端口号。然后客户端使用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[=10=](PowerPanelController.java:143)
at application.PowerPanelController$$Lambda0/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.lambda$timePulse(Animation.java:186)
at javafx.animation.Animation$$Lambda6/1977464318.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at javafx.animation.Animation.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$runToolkit3(QuantumToolkit.java:298)
at com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda/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);
}
...
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++;
}
我真的很感谢任何人 solve/explain 我为什么会这样 :D
您正在发送一个大小相同的字符串,但在另一端您正在读取 1024 字节的字符串 - 您从未发送过。这不行。您应该使用 serialize() 方法序列化字符串,或者,如果您想发送原始字符串字节,请将字符串长度作为消息的单独部分发送。
inD = in.getData();
这只是重申相同的价值。移除。
message = new String(inD,0,inD.length);
错了。您忽略了接收到的数据报的实际长度。更改为:
message = new String(in.getData(), in.getOffset(), in.getLength());
我正在编写一个服务器-客户端软件,其中客户端通过端口请求连接到服务器,服务器打开一个新端口并发回新端口号。然后客户端使用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[=10=](PowerPanelController.java:143)
at application.PowerPanelController$$Lambda0/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.lambda$timePulse(Animation.java:186)
at javafx.animation.Animation$$Lambda6/1977464318.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at javafx.animation.Animation.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$runToolkit3(QuantumToolkit.java:298)
at com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda/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);
}
...
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++;
}
我真的很感谢任何人 solve/explain 我为什么会这样 :D
您正在发送一个大小相同的字符串,但在另一端您正在读取 1024 字节的字符串 - 您从未发送过。这不行。您应该使用 serialize() 方法序列化字符串,或者,如果您想发送原始字符串字节,请将字符串长度作为消息的单独部分发送。
inD = in.getData();
这只是重申相同的价值。移除。
message = new String(inD,0,inD.length);
错了。您忽略了接收到的数据报的实际长度。更改为:
message = new String(in.getData(), in.getOffset(), in.getLength());