Java DatagramPacket和DatagramSocket发送的字符串不等于其本身的文字表示
答案是我的另一条评论 我有一个问题,我正在通过DatagramPack和DatagramSocket将用户和密码字符串发送到远程机器,我想在数据库中执行select语句,但问题是,接收到的字符串似乎与预期的相同,下面是一些代码:Java DatagramPacket和DatagramSocket发送的字符串不等于其本身的文字表示,java,sockets,datagram,Java,Sockets,Datagram,答案是我的另一条评论 我有一个问题,我正在通过DatagramPack和DatagramSocket将用户和密码字符串发送到远程机器,我想在数据库中执行select语句,但问题是,接收到的字符串似乎与预期的相同,下面是一些代码: //build and send method public void packetCompose(String user, String password) { try { byte[] userBytes = user.getBytes();
//build and send method
public void packetCompose(String user, String password) {
try {
byte[] userBytes = user.getBytes();
byte[] passwordBytes = password.getBytes();
byte[] buf = new byte[256];
System.arraycopy( userBytes , 0, buf, 0, Math.min( userBytes.length, 128 ) );
System.arraycopy( passwordBytes, 0, buf, 128, Math.min( userBytes.length, 128 ) );
DatagramPacket packet = new DatagramPacket(buf, 256, serverAddress, 4445);
socket.send(packet);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
现在是分组方法的分解
public void packetDecompose(DatagramPacket packet) {
// packet has this structure
// 128 bytes user String
// 128 bytes password String
clientAddress = packet.getAddress();
String user = new String(packet.getData(),0,128);
String password = new String(packet.getData(),128,128);
System.out.println("Packet content: \nuser: "+user+"\npassword: "+password);
boolean exists = userExists(user, password);
byte[] buf = new byte[128];
if(exists) {
System.out.println("User exists");
System.arraycopy( accessGranted.getBytes(), 0, buf, 0, Math.min(
accessGranted.getBytes().length, 128 ) );
send(new DatagramPacket(buf, 128, clientAddress, 4445));
} else {
System.out.println("User does not exist");
System.arraycopy( accessDenied.getBytes(), 0, buf, 0, Math.min(
accessDenied.getBytes().length, 128 ) );
send(new DatagramPacket(buf, 128, clientAddress, 4445));
}
}
public boolean userExists(String user, String password) {
boolean exists = false;
System.out.println("user: "+user.equals("asdf"));
System.out.println(" pass: "+password.equals("asdf"));
try {
ResultSet result = dataBase.Select("SELECT ipaddress FROM users
WHERE name='"+user+"' AND pass='"+password+"'");
while(result.next()) {
exists = true;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return exists;
}
我通过应用程序界面介绍了asdf作为用户和密码,因此:
System.out.println("user: "+user.equals("asdf"));
System.out.println(" pass: "+password.equals("asdf"));
应该打印为真,但他们打印为假。
有什么建议吗?提前谢谢大家您似乎有128字节长的字符串。这些字符串后面是正常文本,后面是空字节,您可能无法在屏幕上看到这些字节
我建议您使用DataOutputStream.writeUTF()编写字符串,这样它将发送长度,并且只发送字符串中的实际字节(没有空填充)。多亏Peter Lawrey的帮助,我终于解决了这个问题 您必须插入包含用户字符串长度的第一个字节,该字节与pasword相同,因此当您分解数据包时,您可以在不使用空填充的情况下获得用户和密码。 代码如下: 组成:
public void packetCompose(String user, String password) {
try {
byte[] userBytes = user.getBytes();
byte[] passwordBytes = password.getBytes();
byte[] buf = new byte[256];
//first byte contain user length in bytes
System.arraycopy( new byte[]{(byte)userBytes.length} , 0, buf, 0, 1 );
// Then the user
System.arraycopy( userBytes , 0, buf, 1, userBytes.length );
//a byte containing password length in bytes after user
System.arraycopy( new byte[]{(byte)passwordBytes.length} ,0 , buf, userBytes.length +1, 1);
// password
System.arraycopy( passwordBytes , 0, buf, userBytes.length+2, passwordBytes.length );
DatagramPacket packet = new DatagramPacket(buf, 256, serverAddress, 4445);
socket.send(packet);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void packetDecompose(DatagramPacket packet) {
// packet has this structure
// 1 byte user length in bytes
// ? bytes user String
// 1 byte password length in byte
// ? bytes password String
clientAddress = packet.getAddress();
byte[] userLength = new byte[]{packet.getData()[0]};
String user = new String(packet.getData(), 1, (int)userLength[0]);
byte[] passwordLength = new byte[]{packet.getData()[(int)userLength[0]+1]};
String password = new String(packet.getData(), (int)userLength[0]+2, (int)passwordLength[0]);
System.out.println("Packet content: \nuser: "+user+"\npassword: "+password);
boolean exists = userExists(user, password);
byte[] buf = new byte[128];
if(exists) {
System.out.println("User exists");
System.arraycopy( accessGranted.getBytes(), 0, buf, 0, Math.min(
accessGranted.getBytes().length, 128 ) );
send(new DatagramPacket(buf, 128, clientAddress, 4445));
} else {
System.out.println("User does not exist");
System.arraycopy( accessDenied.getBytes(), 0, buf, 0, Math.min(
accessDenied.getBytes().length, 128 ) );
send(new DatagramPacket(buf, 128, clientAddress, 4445));
}
}
分解:
public void packetCompose(String user, String password) {
try {
byte[] userBytes = user.getBytes();
byte[] passwordBytes = password.getBytes();
byte[] buf = new byte[256];
//first byte contain user length in bytes
System.arraycopy( new byte[]{(byte)userBytes.length} , 0, buf, 0, 1 );
// Then the user
System.arraycopy( userBytes , 0, buf, 1, userBytes.length );
//a byte containing password length in bytes after user
System.arraycopy( new byte[]{(byte)passwordBytes.length} ,0 , buf, userBytes.length +1, 1);
// password
System.arraycopy( passwordBytes , 0, buf, userBytes.length+2, passwordBytes.length );
DatagramPacket packet = new DatagramPacket(buf, 256, serverAddress, 4445);
socket.send(packet);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void packetDecompose(DatagramPacket packet) {
// packet has this structure
// 1 byte user length in bytes
// ? bytes user String
// 1 byte password length in byte
// ? bytes password String
clientAddress = packet.getAddress();
byte[] userLength = new byte[]{packet.getData()[0]};
String user = new String(packet.getData(), 1, (int)userLength[0]);
byte[] passwordLength = new byte[]{packet.getData()[(int)userLength[0]+1]};
String password = new String(packet.getData(), (int)userLength[0]+2, (int)passwordLength[0]);
System.out.println("Packet content: \nuser: "+user+"\npassword: "+password);
boolean exists = userExists(user, password);
byte[] buf = new byte[128];
if(exists) {
System.out.println("User exists");
System.arraycopy( accessGranted.getBytes(), 0, buf, 0, Math.min(
accessGranted.getBytes().length, 128 ) );
send(new DatagramPacket(buf, 128, clientAddress, 4445));
} else {
System.out.println("User does not exist");
System.arraycopy( accessDenied.getBytes(), 0, buf, 0, Math.min(
accessDenied.getBytes().length, 128 ) );
send(new DatagramPacket(buf, 128, clientAddress, 4445));
}
}
我明白你说的,但我想这样发送,因为在不久的将来,数据包将包含更多的内容,例如文件的字节,我想我会尝试发送一个包含字符串长度的字节。这样做不应该读空字节我已经解决了这样做的问题,我会把它包括在我的问题中,但是你的回答给了我一些帮助,所以我对它进行了升级。writeUTF()就是这样做的,只是它使用16位而不是8位作为长度。它已经存在了。同时解决了其他几个问题。