Java UDP 套接字 - 数据留在服务器端 [英] Java UDP socket - Data are left over at the server-side

查看:25
本文介绍了Java UDP 套接字 - 数据留在服务器端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 UDP 套接字在 Java 中实现一个非常基本的服务器-客户端模型,但我遇到了一个非常奇怪的问题.

I am implementing a really basic server-client model in Java, by using UDP sockets and I have come across a really strange issue.

我要做的就是让用户(客户端)向服务器发送一条消息,然后服务器将其打印出来.

All I want to do is let the user (client) send a message to the server and then the server will print it.

我有一个例子,但由于我有以下问题,我遗漏了一些东西:

I have an example but I am missing something since I have the following issue:

如果客户端发送消息a"到服务器,它被正确接收.如果客户端发送消息bbb"到服务器,它被正确接收.如果客户端发送消息c"到服务器,然后服务器将打印cbb"作为收到的消息.

If the client sends the message "a" to the server it gets received correctly. If the client sends the message "bbb" to the server it gets received correctly. If the client sends the message "c" to the server, then the server will print "cbb" as the received message.

似乎服务器在收到新消息时确实清理了某种缓冲区.

It seems as if the server does clean some kind of buffer when it gets a new message.

这是我使用的代码:

服务器

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;



public class UDPServer {
public static void main(String args[]) throws Exception {
    byte[] receive_data = new byte[256];
    int recv_port;

    DatagramSocket server_socket = new DatagramSocket(5000);

    System.out.println("Server - Initialized server. Waiting for client on port 5000");

    while (true) {
        // System.out.println("Server - Listening for connections...");
        DatagramPacket receive_packet = new DatagramPacket(receive_data, receive_data.length);
        
        server_socket.receive(receive_packet);
        
        String data = new String(receive_packet.getData());

        InetAddress IPAddress = receive_packet.getAddress();

        recv_port = receive_packet.getPort();

        if (data.equals("q") || data.equals("Q")) {
            System.out.println("Server - Exiting !");
            break;
        } else {
            System.out.println("Server - Client from IP " + IPAddress + " @ port " + recv_port + " said : " + data + " (length: " + receive_packet.getLength() + ")");
        }
    }
}
}

客户

public class UDPClient {
public static void main(String args[]) throws Exception {
    byte[] send_data = new byte[256];

    BufferedReader infromuser = new BufferedReader(new InputStreamReader(System.in));

    DatagramSocket client_socket = new DatagramSocket();

    InetAddress IPAddress = InetAddress.getByName("localhost");

    System.out.println("Client - Initialized the client...");

    while (true) {
        System.out.print("Client - Type Something (q or Q to quit): ");

        String data = infromuser.readLine();

        if (data.equals("q") || data.equals("Q")) {
            System.out.println("Client - Exited !");
            DatagramPacket send_packet = new DatagramPacket(send_data, send_data.length, IPAddress, 5000);
            System.out.println("Client - Sending data : <" + data + ">");
            client_socket.send(send_packet);
            break;
        } else {
            send_data = data.getBytes();
            DatagramPacket send_packet = new DatagramPacket(send_data, send_data.length, IPAddress, 5000);
            System.out.println("Client - Sending data : <" + data + ">");
            client_socket.send(send_packet);
        }
    }

    client_socket.close();
}
}

我认为这个错误是微不足道的,但我在网络编程方面的技能有限,因此我不知道它到底是什么.

I suppose that the mistake is something trivial, but my skills in network programming are limited, therefore I don't know what exactly it is.

为了明确起见,我在不同终端上的同一台机器(mac)上同时运行服务器和客户端,以防万一它影响情况.

Just to make clear, I am running both the server and the client at the same machine (mac) on different terminals, just in case it affects the situation in anyway.

任何帮助将不胜感激.

编辑

...我回来回答我自己的问题.问题是我没有定义服务器套接字应该期望读取的数据量.因此当我改变时

...And I come back to answer my own question. The problem was that I was not defining the amount of data that the server socket should expect to read. Therefore when I change

String data = new String(receive_packet.getData());

String data = new String(receive_packet.getData(), 0, receive_packet.getLength());

一切顺利.

仅供将来参考和可能遇到相同问题的人:)

Just for future reference and for people who might come across the same problem :)

推荐答案

在你第一次打电话时,receive_data 是这样的:

On your first call this is what receive_data looks like:

 --------------
|"a"|    |    |
 --------------

在您的第二次通话中:

 --------------
|"b"|"b"| "b" |             notice that the "a" in data_receive was overwritten
 --------------

在你第三次打电话时,你只发送了一封信,所以数组中唯一被覆盖的部分是第一个元素:

On your third call, you only send a single letter, so the only part of the array that gets overwritten is the first element:

 --------------
|"c"|"b"| "b" | 
 --------------

发生这种情况是因为在发送到服务器的消息之间的 receive_data 数组中仍有数据,解决此问题的一种简单方法是在接收循环内部初始化一个新数组.这样每次收到消息时都会有一个新的数组等着你.

This is happening because there is still data left in the receive_data array in between messages to the server, a simple way around this would to just initialize a new array inside of you receive loop. That way every time you receive a message you will have a fresh array waiting for you.

while (true) 
{
    byte[] receive_data = new byte[256];
    ......
}

这篇关于Java UDP 套接字 - 数据留在服务器端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆