Java String Equals 不适用于 UDP 服务器收到的数据包

Java String Equals not working for UDP server received packet

这是简单的 UDP 客户端-服务器 classes:

UDP服务器:

import java.net.*;
/**
 * Source:https://systembash.com/a-simple-java-udp-server-and-udp-client/
 * 
 */
class UDPServer {    
    public static void main(String args[]) throws Exception {            
        DatagramSocket serverSocket = new DatagramSocket(9876);            
        byte[] receiveData = new byte[1024];
        byte[] sendData = new byte[1024];            
        while (true) {            
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

            serverSocket.receive(receivePacket);                
            String sentence = new String(receivePacket.getData());                 

            // Sentence here is not equal "PING" ?
            if(sentence.equals("PING")) {                       
                System.out.println("It is PING: " + sentence);          
            } else {
                System.out.println(sentence.getClass());
                System.out.println("It is not equal PING. It is <" + sentence + ">");
            }                          
            System.out.println("RECEIVED: " + sentence);

            InetAddress IPAddress = receivePacket.getAddress();                
            int port = receivePacket.getPort();                
            String capitalizedSentence = "PONG"; 
            sendData = capitalizedSentence.getBytes();
            DatagramPacket sendPacket
                    = new DatagramPacket(sendData, sendData.length, IPAddress, port);
            serverSocket.send(sendPacket);
        }
    }
}

UDP客户端:

import java.net.*;
/**
 * Source:
 * https://systembash.com/a-simple-java-udp-server-and-udp-client/
 *
 * @author  
 */
class UDPClient {
    public static void main(String args[]) throws Exception {       
        DatagramSocket clientSocket = new DatagramSocket();        
        InetAddress IPAddress = InetAddress.getByName("localhost");        
        byte[] sendData = new byte[1024];
        byte[] receiveData = new byte[1024];

        String sentence =  "PING";
        sendData = sentence.getBytes();

        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
        clientSocket.send(sendPacket);        
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        clientSocket.receive(receivePacket);        
        String modifiedSentence = new String(receivePacket.getData());
        System.out.println("FROM SERVER:" + modifiedSentence);        
        clientSocket.close();
    }
}

在 UDPServer 中有一个响应检查(可变语句)。出于某种原因,equals 在必须时没有检测到 "PING"。而且它输出的句子字符串是"PING"、class字符串。 这是为什么 ?

UDPServer的输出是else:

class java.lang.String
It is not equal PING. It is:<PING>
RECEIVED: PING

如果重要,java 版本是“1.7.0_91”。

DatagramPacket的getData方法returns底层缓冲区,也就是你之前创建的1024字节的缓冲区。您从这个缓冲区创建一个字符串。所有未填充的字节都将为 0(默认初始化),因此您的字符串将包含很多额外的零。这就是为什么 equals 方法 returns false。如果您确定发送的消息不会有前导或尾随空格(或者至少 none 这对程序的其余部分很重要),您可以使用 trim 方法解决此问题。

getData() 为您提供了一个缓冲区,您可以从中获取数据。

不要使用 trim(),因为这可能会删除您实际想要保留的字符(除了昂贵)

相反,您应该使用消息的长度

String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength()); 

这样您将只提取您想要的数据到缓冲区的一部分。

调用 equals 时你没有得到 true,因为响应是 1024 字节长。您可以 trim 您在 UDPServer 上的回复来解决这个问题:

String sentence = new String(receivePacket.getData()).trim();