比较字符串与字符串(来自 DatagramPacket 的字节数组)

Compare String with String (Byte array from DatagramPacket)

所以我被要求创建一个 UDP 消息传递应用程序。我在同一台计算机上有两个来自命令行的 运行 客户端,我试图让每个客户端在从另一个客户端收到字符串 "exit" 时跳出 while 循环,所以他们都同时终止。

String input 是在此代码之上创建的,因此如果此客户端输入 "exit",则会跳过 while(这很好用!)。

DatagramSocket receiveSocket = new DatagramSocket(8000); //Port 8000
byte[] receiveBuffer = new byte[65508];

while(!input.equals("exit")) {

    DatagramPacket packetToReceive = new DatagramPacket(receiveBuffer, receiveBuffer.length);

    receiveSocket.receive(packetToReceive);
    receiveBuffer = packetToReceive.getData();

    String receivedMessage = new String(receiveBuffer);


    if(!receivedMessage.equals("exit")) {   
        System.out.println("A says: " + receivedMessage);
    }
    else {
        input = "exit";
    }
}

我遇到的问题是我无法让 !receivedMessage.equals("exit") 等同于 false,即使当我执行 System.out.println(receivedMessage) 时,我得到 "exit"。它们看起来完全一样,但显然不是。 我试过强制编码,例如...

String receivedMessage = new String(receiveBuffer, "UTF-8");

...但没有任何效果。我已经尝试了许多强制编码的其他组合,加上将 receivedMessage 转换为字节数组、字符数组等进行比较,并且我检查了 receivedMessage 两边的空格,仍然没有。

如有任何帮助,我们将不胜感激。它必须是我遗漏的小东西。 谢谢。

receivedMessage 中可能有一些前导或尾随空格。试试trim吧。

receiveBuffer 大小可能有问题。当前您在数据包中发送 "exit",该数据包足够小以适合 65508 字节。因此,receiveBuffer 中的剩余字节只是空的或包含特殊字符。这就是为什么当您收到数据包并将数据放入字符串中时,剩余的字节也在字符串中。

您可以使用 contains() 而不是 equals() 来比较字符串,或者您可以只将包含实际消息的所需字节放入 receiveBuffer。这是实现该目标的一种可能方法:

receiveSocket.receive(packetToReceive);
receiveBuffer = new byte[packetToReceive.getLength()];
System.arraycopy(packetToReceive.getData(), packetToReceive.getOffset(), receiveBuffer, 0, packetToReceive.getLength());

String receivedMessage = new String(receiveBuffer);

if(!receivedMessage.equals("exit")) {   
    System.out.println("A says: " + receivedMessage);
}
else {
    input = "exit";
}
receiveSocket.receive(packetToReceive);
receiveBuffer = packetToReceive.getData();
String receivedMessage = new String(receiveBuffer);

问题就在这里。您忽略了接收到的数据包的长度。最后两行可以改成这样:

String receivedMessage = new String(packetToReceive.getData(), packetToReceive.getOffset(), packetToReceive.getLength());