为啥服务器在非多线程的情况下会同时处理多个客户端?

Posted

技术标签:

【中文标题】为啥服务器在非多线程的情况下会同时处理多个客户端?【英文标题】:Why does server process multiple clients at the same time when it's not multithreaded?为什么服务器在非多线程的情况下会同时处理多个客户端? 【发布时间】:2021-05-17 17:30:12 【问题描述】:

所以在下面的代码中,我有一个单线程服务器和一个多线程客户端。这样做的原因是因为我希望客户端同时发送数据包和接收数据包。但是,当我启动服务器并运行多个客户端时,服务器可以同时处理多个客户端,即使服务器不是多线程的?你能解释一下吗?

服务器:

public class server 

public static void main(String[] args) throws IOException
    new server();



//declare the UDP server socket
DatagramSocket datagramSocket;
int port = 3741;

public server() throws IOException 
    
    //create UDP server with a specific port number
    datagramSocket = new DatagramSocket(port);
    System.out.println("[UDP server] Datagram socket started on port " + port);
    
    //prepare the packet structure for received packets
    int dataLength = 100; //must be large enough so some part of packet doesn't get lost
    byte[] receiveData = new byte[dataLength];
    DatagramPacket packet = new DatagramPacket(receiveData, receiveData.length);
    
while(true) 
        datagramSocket.receive(packet);
        System.out.println("client connected");
        
        InetAddress inetAddress = packet.getAddress();
        int clientPort = packet.getPort();
        byte[] data = packet.getData();

        
        
        //send response back to the client host
        byte[] sendData = new byte[1024];
        
        DatagramPacket datagramPacket = new DatagramPacket(data, data.length, inetAddress, clientPort);
        datagramSocket.send(datagramPacket); //sending data from server to client
        




客户:

public class client 

public static void main(String[] args) throws Exception 
    new client();



public client() throws Exception
    
    DatagramSocket socket = new DatagramSocket();
    
    InetAddress ip = InetAddress.getByName("127.0.0.1");
    String message = "hello from client"; 
    
    DatagramPacket packetSend = new DatagramPacket(message.getBytes(), message.getBytes().length, ip, 3741);
    
    Thread th = new Thread(new Runnable() 
        
        @Override
        public void run() 
            for(int i = 0; i < 100; i++) 
                try 
                    Thread.sleep(1000);
                 catch (InterruptedException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                
                
                try 
                    socket.send(packetSend);
                 catch (IOException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                
            
            
        
    );
    th.start();
    
    byte[] buffer = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    
    //this part can't be in a thread because the loop above us will finish first before this starts
    //we can put this code before the loop and start a thread this would also work
    while(true) 
        try 
            socket.receive(packet);
         catch (IOException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        
        String data = new String(packet.getData()).trim();
        
        System.out.println(data);
    



【问题讨论】:

“服务器可以同时处理多个客户端”-请编辑问题更具体-您到底看到了什么对您没有意义?来自不同客户端的交错打印,每个请求一个? 【参考方案1】:

你认为 “服务器可以同时处理多个客户端,即使服务器不是多线程的” 会导致你的大脑欺骗你。实际上,他们正在以相对较快的速度逐一处理。很容易看出您是使用wireshark 还是tcpdump 来捕获服务器端数据包。你会发现有趣的真相。

【讨论】:

我将 thread.sleep() 放在服务器中,它显示了每个客户端是如何被一一处理的。无需为此用途安装应用程序。这样可以更轻松地完成。 如果想深入网络编程,总有一天需要wireshark和tcpdump。 我是一名全栈 Web 开发人员,没有必要深入研究任何特定主题。

以上是关于为啥服务器在非多线程的情况下会同时处理多个客户端?的主要内容,如果未能解决你的问题,请参考以下文章

7. Redis的管道技术

与非多处理情况相比,使用 AllenNLP 解码的多处理是缓慢的

多线程

如何让Task在非线程池线程中执行?

实现多个客户端可以同时跟服务器通信

如何同时从多个线程访问 MySQL