等于比较相等的字符串时返回false

时间:2014-10-26 11:34:08

标签: java string client-server equals bootp

我正在尝试用Java编写BOOTP客户端/服务器,RFC中的一个规范是客户端可以编写它想要连接的服务器的昵称。如果数据包到达的服务器不是指定的服务器,它应该丢弃bootrequest。

我有三个类(BOOTPClient,BOOTPServer和BOOTPMessage)。截至目前,我已成功将bootrequest从客户端发送到服务器,服务器接收它并开始处理它。

问题在于:

String sname = new String(btpmsg.getSname());
String serverName = args[0];
boolean discard = false;
System.out.println("|"+serverName+"|"+sname+"|");
if (!sname.equalsIgnoreCase("") && !sname.equalsIgnoreCase(serverName)) {
    discard = true;
    System.out.println("The request was not for this server. Server requested: "+sname);
}

这意味着:如果字符串不为null(在这种情况下我们不关心它到达的服务器),请确保它是正确的服务器。如你所见,我在“|”之间打印了两个字符串100%确定没有空格或任何可能搞砸比较的东西。然而,它进入if块并执行里面的句子。如果字符串与服务器名称相同并且它是空白的,则会发生这种情况。

澄清一下:btpmsg是BOOTPMsg类的一个实例,服务器名称存储为一个字节数组(所有内容都编码为字节数组,ByteArrayOutputStream用DatagramPacket发送它),然后转换为String。我不知道问题出在哪里。

输出样本:

服务器(使用“java BOOTPServer bootpserver”调用):

Server bootpserver running. Awaiting requests.
Bootrequest received.
|bootpserver|bootpserver|
The request was not for this server. Server requested: bootpserver

客户端:

Enter your IP if known. Otherwise, press enter.

Enter the IP of the server if known. Otherwise, press enter.

Enter the name of the server if known. Otherwise, press enter.
bootpserver
Enter the file name if known. Otherwise, press enter.

我很感激任何帮助,因为我不知道还能找到什么错误。我最好的选择是在DataInputStream中使用ByteArrayOutputStream或readFully上的“write”方法,但所有其他参数都可以正常工作。非常感谢。

1 个答案:

答案 0 :(得分:1)

您的getSname()方法返回固定长度为64的byte[],这是BOOTP协议中sname字段的指定长度。当你直接将它传递给String(byte[])构造函数时,你会得到一个右边填充的字符串,长度为64,带有零字符。

要解决此问题,您需要找到数组中的第一个零字节,并在构造字符串时使用它。另外,请确保传入明确的字符编码;否则你将受到平台默认的支配。

所以,使用这样的代码:

sname2string(byte[] sname) {
   int length = 0;
   while (length < 64 && sname[length] != 0) length++;
   return new String(sname, 0, length, StandardCharsets.ISO_8859_1);
}