2014-09-27 159 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(..)。否則將使用「默認編碼」,如果不同的系統使用不同的默認值,則會導致問題。

相關問題