我有简单的UDP客户端和服务器代码。当服务器从客户端获取请求时,我想从客户端发送的数据和一些其他数据中形成一个回复,如代码所示。
import java.io.*;
import java.net.*;
public class UDPClient {
public static void main(String args[]){
// args give message contents and destination hostname
DatagramSocket aSocket = null;
try {
aSocket = new DatagramSocket();
byte [] m = args[0].getBytes();
InetAddress aHost = InetAddress.getByName(args[1]);
int serverPort = 8211;
DatagramPacket request =
new DatagramPacket(m, args[0].length(), aHost, serverPort);
aSocket.send(request);
byte[] buffer = new byte[1000];
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
aSocket.receive(reply);
System.out.println("Reply: " + new String(reply.getData()));
}catch (SocketException e){System.out.println("Socket: " + e.getMessage());
}catch (IOException e){System.out.println("IO: " + e.getMessage());
}finally {if(aSocket != null) aSocket.close();}
}
}
public class UDPServer {
public static void main(String args[]){
DatagramSocket aSocket = null;
try{
aSocket = new DatagramSocket(8211);
// create socket at agreed port
byte[] buffer = new byte[1000];
while(true){
buffer = ("Hello "+new String(request.getData()).toUpperCase()+" Goodbye").getBytes();
System.out.print("Replying to client: "+buffer);
DatagramPacket reply = new DatagramPacket(buffer, buffer.length,
request.getAddress(), request.getPort());
aSocket.send(reply);
}
}catch (SocketException e){System.out.println("Socket: " + e.getMessage());
}catch (IOException e) {System.out.println("IO: " + e.getMessage());
}finally {if(aSocket != null) aSocket.close();}
}
}
问题是,作为输出我得到:回复客户端:Hello PAUL和客户端收到的相同,Goodbye被省略。为什么要省略?有趣的是,如果我这样做:
buffer = ("Hello "+"Goodbye " +new String(request.getData()).toUpperCase()).getBytes();
输出是Hello Goodbye PAUL,同样发送给客户端。
答案 0 :(得分:2)
简单地调用new String(request.getData())
是危险的。 DatagramPacket
请求不仅仅是你的字符串,而是整个数据包。在转换为字符串之前,您应该使用DatagramPacket
提供的其他方法来获取实际数据。
byte[] packet = new byte[request.getLength()];
packet = Arrays.copyOfRange(request.getData(), request.getOffset(), request.getLength() + request.getOffset());
//packet now contains just the string portion of your request, use that instead