Java 为什么我的echo服务器有时会在消息末尾有垃圾数据?

Java 为什么我的echo服务器有时会在消息末尾有垃圾数据?,java,networking,udp,Java,Networking,Udp,嗨,我用数据报制作了一个echo客户机-服务器代码。代码正在运行,从客户端发送的消息在服务器端被接收,然后它们被回显到客户端。下面的场景显示了我遇到的问题 1->客户端:hi,服务器:hi, 回音:嗨 2->客户端:你好,服务器:你好, 回音:你好 现在,当客户端键入一条比上一条短的消息时,会发生以下事情 3->客户端:K,服务器:Kello, 回音:K 我不明白为什么服务器会打印上一条消息的其余字符,以下是服务器端代码: import java.awt.BorderLayout;

嗨,我用数据报制作了一个echo客户机-服务器代码。代码正在运行,从客户端发送的消息在服务器端被接收,然后它们被回显到客户端。下面的场景显示了我遇到的问题

1->客户端:hi,服务器:hi, 回音:嗨

2->客户端:你好,服务器:你好, 回音:你好 现在,当客户端键入一条比上一条短的消息时,会发生以下事情

3->客户端:K,服务器:Kello, 回音:K

我不明白为什么服务器会打印上一条消息的其余字符,以下是服务器端代码:

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;

    import javax.swing.SwingUtilities;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JScrollBar;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;

    public class Server extends JFrame {
int port;
// JTextField textField;
JButton resendPacket;
JTextArea chatWindow;
DatagramSocket socket;
private final int PACKET_SIZE = 124;
private final int port_Number = 6789;
DatagramPacket packet =  new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);

    InetAddress host;


public Server() {
    super("INSTANT ECHO - SERVER");
    resendPacket = new JButton("Echo");
    chatWindow = new JTextArea();

//  add(resendPacket, BorderLayout.SOUTH);
    add(new JScrollPane(chatWindow));
    setSize(300, 300);
    setVisible(true);
}

public void startRunning() {

    try {
        port = 6777;
        socket = new DatagramSocket(port);
        showMessage("Server is Ready... \n");
        /*resendPacket.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                try {
                    socket.send(packet);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }); */
        while(true)
        {
            processPacket();
        }


    } catch (SocketException e) {
        // TODO: handle exception
        showMessage("\n Could not send packet!\n");
        e.printStackTrace();
    } 
}

private void processPacket() {




    // create a packet

    // receive a packet

    try {
        socket.receive(packet);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        showMessage("\nCould not receive Packet");
        e.printStackTrace();
    }
    try {
        socket.send(packet);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    // display the contents of the packet
    showMessage(new String(packet.getData()));



    // send the packet again to the sender

}

public void showMessage(final String text) {
    SwingUtilities.invokeLater(

    new Runnable() {

        public void run() {
            chatWindow.append("\n Packet Data : " + text);
        }
    });

}
}

这是客户端代码

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;

    public class Client extends JFrame {
int port = 6777;
JTextField textField;
String data = "hello" ;
// JButton sendPacket;
JTextArea chatWindow;
DatagramSocket socket;
DatagramPacket packet;
private final int PACKET_SIZE = 124;
InetAddress host;

public Client() {
    super("INSTANT ECHO - CLIENT");

    textField = new JTextField();
    try {
        host = InetAddress.getByName("127.0.0.1");
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        showMessage("\n Could not find local host");
        e.printStackTrace();
    }
试一试{

}

有人能告诉我为什么要打印前面的字符吗?

具有已使用的缓冲区长度

试一试


您一次又一次地重复使用同一个数据包,因此当它从网络读取信息时,它会用新内容覆盖现有的数据包缓冲区内容。客户端没有写入空终止符,因此没有写入缓冲区。同样,当您使用
showMessage(新字符串(packet.getData())打印数据时如果刚刚收到的消息长度不足以完全覆盖旧内容,则返回的数据中仍有旧数据的残余

它不会回显额外的数据,因为当您发送数据包时,套接字遵循
packet.getLength()
,它控制要发送的字节数

您可以:

  • 将showMessage调用更改为:

    showMessage("\n Echoed Message --> " + 
                new String(packet.getData(), 0, packet.getLength()));
    
  • 每次使用不同的数据包

其中任何一个都可以修复。

您还可以提供客户端代码吗?具体来说,处理输入缓冲区的部分,直到打印的时候。请在发布之前删除死代码或注释代码。这闻起来像是一个典型的错误:数组缓冲区未被清理…如果它为您解决了问题,请确保您接受答案。要求男士接受您的答案真的很烦人,不是吗@Wug?我讨厌那个--我不是为了想象中的互联网点数而来的,所以说实话,这并不困扰我。好吧,你说得对。不要在意这些要点(现在我有足够的声誉去做这些事情),只要。。。您知道,注意事项(:在Java中不使用尾随null,也无法解决此问题。
showMessage(new String(packet.getData(), 0, packet.getLength()));
showMessage("\n Echoed Message --> " + 
            new String(packet.getData(), 0, packet.getLength()));