当我们从 UDP 服务器接收数据包时,为啥我们必须在单独的线程中接收它们?

Posted

技术标签:

【中文标题】当我们从 UDP 服务器接收数据包时,为啥我们必须在单独的线程中接收它们?【英文标题】:When we receive packets from an UDP server, why do we have to receive them in a seperate thread?当我们从 UDP 服务器接收数据包时,为什么我们必须在单独的线程中接收它们? 【发布时间】:2021-05-13 15:10:36 【问题描述】:

所以我的应用程序非常简单。如果您通过扫描仪键入某些内容,它会将其发送到服务器,然后服务器将其发送回客户端。但是,我不明白为什么我们必须把我们处理从服务器接收数据包的代码放到一个线程中?

下面的代码运行良好,但如果我不使用多线程,那么应用程序将无法运行。我发送数据包的部分也停止工作。你能解释一下为什么会这样吗?

public class Client 

private static DatagramSocket socket = null;

public static void main(String[] args) 

    System.out.println("Send to server:");

    Scanner scanner = new Scanner(System.in);

    while (true) 

        try 
            // port shoudn't be the same as in TCP but the port in the datagram packet must
            // be the same!
            socket = new DatagramSocket();
         catch (SocketException e1) 
            System.out.println("[CLIENT] Unable to initiate DatagramSocket");
        

        InetAddress ip = null;

        try 
            ip = InetAddress.getByName("127.0.0.1");
         catch (UnknownHostException e) 
            System.out.println("[CLIENT] Unable to determine server IP");
        

        // must be in a while loop so we can continuously send messages to server
        String message = null;

        Thread thread = new Thread(new Runnable() 
            
            @Override
            public void run() 
                // TODO Auto-generated method stub
                receive();
            
        );
        thread.start();
        
        while (scanner.hasNextLine()) 
            message = scanner.nextLine();

            byte[] buffer = message.getBytes();

            DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ip, 6066);

            try 
                socket.send(packet);
             catch (IOException e) 
                System.out.println("[CLIENT] Unable to send packet to server");
            
        

    



private static void receive() 
    
    // receiving from server

    byte[] buffer2 = new byte[100];

    DatagramPacket ps = new DatagramPacket(buffer2, buffer2.length);

    while (true) 
        try 
            socket.receive(ps);
         catch (IOException e) 
            System.out.println("[CLIENT] Unable to receive packets from server.");
        

        System.out.println("[SERVER] " + new String(ps.getData()));

    

【问题讨论】:

你没有。但是DatagramSocket I/O 操作是阻塞的,所以无论你在哪个线程上运行它们都可能会阻塞。 【参考方案1】:

如果您通过扫描仪输入内容,它会将其发送到 服务器,服务器将其发送回客户端。

所以 main 方法在主线程上运行并完成一些工作。您刚才提到的工作。

阅读一些用户输入以及以下部分

 while (scanner.hasNextLine()) 
            message = scanner.nextLine();

            byte[] buffer = message.getBytes();

            DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ip, 6066);

            try 
                socket.send(packet);
             catch (IOException e) 
                System.out.println("[CLIENT] Unable to send packet to server");
            
        

标题:从 UDP 服务器接收数据包

您想接收数据包,但又不想阻止用户输入内容并将其发送到服务器。

因此,您需要同时完成 2 项工作。又名多线程

【讨论】:

不,不,不。我的意思是:为什么当我们不使用这个名为“MuLtItHrEaDiNg”的美丽概念时客户端无法工作 你的解释很好理解。

以上是关于当我们从 UDP 服务器接收数据包时,为啥我们必须在单独的线程中接收它们?的主要内容,如果未能解决你的问题,请参考以下文章

为啥tcp服务器可以获取客户端的ip?

为啥 SOCKS5 需要通过 UDP 中继 UDP?

在UDP Socket java android上发送和接收数据

从 ASP.NET 执行 SSIS 包时出错

udp为啥收不到广播中的数据,该怎么处理

如何在 linux C 中解除对 recv() 或 recvfrm() 函数的阻塞