2014-09-27 161 views
1

我正在通过UDP发送数据包,出于某种原因,我无法比较从数据包中提取的字符串和创建的字符串,即使打印它们时的值相同(无尾随空格)。为什么这两个字符串不等于?

byte[] incoming = new byte[1000]; 
DatagramPacket request = new DatagramPacket(incoming, incoming.length); 
serverSocket.receive(request); 
String str = new String(request.getData()); 
String str2 = new String("message received"); 

if(str.equals(str2)) 
{ 
    System.out.println("equal"); 
} 

这是有什么理由吗?

+0

检查字符串的长度。传输中必须有错误。 – 2014-09-27 00:38:50

回答

3

发生这种情况是因为new String(request.getData())确实不是返回"message received"

问题是[有可能],因为这样的事实:new String(byte[])尝试使用供给所有(1000)的字节数,在默认的编码,这与一群NUL的(“\ 0”)字符结束该追加到实际的字符串内容使其与文字不等于。这可以很容易地看到一个调试器,虽然这样的NUL字符通常在与普通文本一样显示时“丢失”,如println

Trivially:"hello".equals("hello\0") is false。

几种解决方案包括:

  1. 字符串,如与构成该字符串的字节数前缀所发送的数据,然后使用a String constructor that takes a limit/length或;

  2. 阻止任何尾随0被处理,再次通过指定解码限制或;

  3. 删除解码数据后的任何NUL字符。

由于选项#3是容易(直到它可被固定到使用#1 /#2),考虑:

String str = new String(request.getData(), "UTF-8"); // Specify an encoding! 
int nul = str.indexOf('\0'); 
if (nul > -1) { 
    str = str.substring(0, nul); 
} 

虽然修整是最简单的,这是不是一般合适。 #3超过#2的最大问题是它首先解码全部的字节和然后过滤字符。在不同的编码下(尽管ASCII和UTF-8应该是“安全的”),这可能会导致实际字符串内容之后的非NUL垃圾,具体取决于缓冲区中存在的内容。

此外,手动指定编码new String(byte[] ..)String.getBytes(..)。否则将使用“默认编码”,如果不同的系统使用不同的默认值,则会导致问题。

相关问题