【问题标题】:When sending datagram packets, the data of the packet is duplicated. (java)发送数据报包时,包的数据是重复的。 (爪哇)
【发布时间】:2018-09-17 21:41:41
【问题描述】:

UDP客户端:

public static void main(String[] args) {
    // TODO Auto-generated method stub
    DatagramSocket socket;
    DatagramPacket packet;
    String str = "";
    byte[] buffer;
    String serverIP = "192.168.0.16";
    int serverPORT = 10789;
    Scanner sc = new Scanner(System.in);

    try {
        socket = new DatagramSocket();
        while(true) {
            System.out.print("To server : ");
            str = sc.nextLine();
            if(str.equals("exit")) {
                System.out.println("exit");
                break;
            }
            buffer = str.getBytes();
            packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(serverIP), serverPORT);
            socket.send(packet);
            System.out.println("sent message : " + str);
        } 
        socket.close();
    } catch (skip)

UDP服务器:

byte[] buffer = new byte[1024];

public static void main(String[] args){
    int port = 10789;
    DatagramSocket socket;
    DatagramPacket packet;
    byte[] buffer = new byte[1024];

    try {
        socket = new DatagramSocket(port);
        packet = new DatagramPacket(buffer, buffer.length);
        while(true){
            socket.receive(packet);
            String text = new String(packet.getData());
            if(text.equals("exit")){
                System.out.println("exit");
                break;
            }
            System.out.println("received : "+text);
        }
    }

当我多次输入时,数据包的数据重复。

示例:当我打字时:

输入abcdeg

在服务器上显示abcdeg

输入qwe

在服务器上显示qwedeg

怎么了?如何清理缓冲区?

【问题讨论】:

  • 在客户端,当您调用buffer.length 时,buffer 仍然为空,这应该会抛出 NPE。我想有些代码丢失了?
  • 我将packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName(serverIP), serverPORT);移动到buffer = str.getBytes();的底部

标签: java udp buffer packet datagram


【解决方案1】:

在服务器代码中,所有接收到的数据包都重复使用相同的缓冲区(这是一件好事)。然而,这意味着来自先前数据包的数据存在于缓冲区中,直到被覆盖。如您所见,当您收到一个比前一个更短的数据包时,只有缓冲区中的第一个字节被覆盖,直到收到的消息的长度为止。

new String(packet.getData()) 让 String 构造函数通过查看缓冲区的内容来计算数据的长度。相反,请使用 another constructor 来指定数据的长度:new String(packet.getData(), 0, packet.getLength())

【讨论】:

  • 我理解并成功了。真的很感激。顺便一提。在客户端收到“exit”字符串时,如何检测“exit”字符串?我添加了if(text.equals("exit")){ System.out.println("exit") break; },但什么也没发生
  • while 语句仍在循环中。
  • @H.Bin 问题是当用户在客户端输入“exit”时,客户端立即退出,没有将字符串发送给服务器。要解决此问题,您可以将 if(str.equals("exit")) { System.out.println("exit"); break; } 块放在客户端的 while 循环的末尾
【解决方案2】:

您无法从服务器端清除缓冲区,因为所有连接都使用相同的缓冲区。但是,您可以使用packet.getLength()packet.getOffset() 来检查接收到的数据的长度和偏移量。

String received 
          = new String(packet.getData(), packet.getOffset(), packet.getLength());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多