Java 套接字:一台服务器和多个客户端

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18582708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 09:13:52  来源:igfitidea点击:

Java Sockets: One Server and Multiple Clients

javamultithreadingsockets

提问by projectdelphai

So I created a basic client-server program in java. It starts out like this:

所以我用java创建了一个基本的客户端-服务器程序。它开始是这样的:

  1. Client connects to Server
  2. Server asks for Client's name
  3. Client responds with name
  4. Server greets Client
  5. After this, Client speaks and the Server repeats the words back
  1. 客户端连接到服务器
  2. 服务器询问客户的名字
  3. 客户端以名称响应
  4. 服务器问候客户端
  5. 在此之后,客户端说话,服务器重复的话

I got this to work without too much trouble using this tutorial. The problem comes whenever I try to introduce multiple clients. I thought that it would work because I'm using multiple threads, however, the second clients just hangs until the first client quits and then it starts it work (the server does accept input from the second client, but it doesn't respond with anything until the first client quits).

使用本教程我没有太多麻烦就可以正常工作。每当我尝试介绍多个客户时,问题就会出现。我认为它会起作用,因为我使用了多个线程,但是,第二个客户端只是挂起,直到第一个客户端退出,然后它才开始工作(服务器确实接受来自第二个客户端的输入,但它不响应直到第一个客户退出为止)。

Here is the code I'm using:

这是我正在使用的代码:

import java.net.*;
import java.io.*;

public class Server extends Thread {
  private ServerSocket listener;

  public Server(int port) throws IOException {
    listener = new ServerSocket(port);
  }

  public void run() {
    while(true) {
      try {
        Socket server = listener.accept();
        DataOutputStream out = new DataOutputStream(server.getOutputStream());
        out.writeUTF("What is your name?");
        DataInputStream in = new DataInputStream(server.getInputStream());
        String user_name = in.readUTF();
        out.writeUTF("Hello "+user_name);
        while(true) {
          String client_message = in.readUTF();
          out.writeUTF(client_message);
        }
      }
      catch(IOException e) {
        e.printStackTrace();
      }
    }
  }

  public static void main(String[] args) {
    int port = 6006;
    try {
      Thread t = new Server(port);
      t.start();
    } catch(IOException e) {
      e.printStackTrace();
    }
  }
}

Can someone explain what I'm doing wrong?

有人可以解释我做错了什么吗?

I have looked at the using Runnable instead of Extends Thread, but I ran into even more problems there, so I want to try and work with this first.

我已经看过使用 Runnable 而不是 Extends Thread,但我在那里遇到了更多问题,所以我想先尝试使用它。

采纳答案by dst

Incoming connections are only handled by the line listener.accept();. But after you got a client connected, you're stuck in the while loop. You need to create a new Thread(or Runnableexecuted on an ExecutorServiceif you expect high load), and start it, then immediatelyaccept the next connection.

传入连接仅由线路处理listener.accept();。但是当你连接了一个客户端之后,你就被困在了 while 循环中。您需要创建一个新的Thread(或RunnableExecutorService您期望高负载的情况下执行),并启动它,然后立即接受下一个连接。

回答by Neeraj

In a nutshell, this is what is going wrong.

简而言之,这就是问题所在。

  1. You are using exactly ONE thread as the server.
  2. Blocking this thread when you call listener.accept()
  1. 您正在使用一个线程作为服务器。
  2. 调用 listener.accept() 时阻塞此线程

This is what you need to do:

这是你需要做的:

Create two classes 1: Server - Similar to what you have now, but instead of doing the actual work of acting as an echo server, it just spawns a new Thread which starts listening on a NEW PORT (which you can select randomly), and sends the client the address for this new port. The client will then get the new port number and would try to connect to the server on the new port. 2: The Echo thread - This starts a new listener on the port passed, and does the job of echoing to whoever is listening.

创建两个类 1:服务器 - 与您现在拥有的类似,但它没有执行充当回显服务器的实际工作,它只是生成一个新线程,该线程开始侦听新端口(您可以随机选择),以及向客户端发送这个新端口的地址。然后客户端将获得新的端口号并尝试连接到新端口上的服务器。2:Echo 线程 - 这会在所通过的端口上启动一个新的侦听器,并完成向正在侦听的任何人进行回显的工作。

OR:

或者:

You start a UDP server rather than a TCP server, and all this will not matter then, but that is out of the purview of this specific question.

您启动 UDP 服务器而不是 TCP 服务器,然后所有这些都无关紧要,但这超出了这个特定问题的范围。