【问题标题】:Two clients on a single thread Java单线程 Java 上的两个客户端
【发布时间】:2015-08-08 22:20:44
【问题描述】:

我正在编写一个程序,其中我有一个持续监听请求的服务器(就像大多数服务器一样)。我希望它在每次获得客户端连接时创建一个新线程(我已经完成了这部分),并且我希望它在它之后立即将客户端添加到同一个线程。所以我将有两个客户端连接到同一个线程。

类似的东西:

.....
try(ServerSocket serversocket = new ServerSocket();
    Socket client1 = serversocket.accept();
    Socket client2 = serversocket.accept();){

    //spawn new thread with sockets to client1 and client2

这可能吗?有没有其他选择?是否有可能让两个不同的线程相互交谈?

是否可以从延伸到客户端的线程创建一个新的服务器套接字?

...
try(ServerSocket serversocket = new ServerSocket();
    Socket client1 = serversocket.accept();){
    //spawn thread
}

现在在线程中:

....
try(ServerSocket serversocket2 = new ServerSocket();
    Socket client2 = serversocket2.accept();){
    //exchange information between two clients and do other stuff
}

有什么想法吗?非常感谢所有帮助。

【问题讨论】:

  • 想到的问题是,为什么?
  • 我正在尝试制作许多不同的两人棋盘游戏的虚拟版本。如果您还有其他方法可以做到这一点,请随时回答。
  • 连接一,建立某种组/标识符,连接二要求加入同一个“组”(如果存在)。两个连接都驻留在各自的线程中...?
  • 但是我该如何创建组呢?!我带来了几乎相同的东西,但我不知道如何让两个线程相互通信。
  • 这取决于你。您可以使用Map 或其他某种查找机制,其中组管理两个连接之间传递的信息

标签: java multithreading sockets network-programming serversocket


【解决方案1】:

创建一个ArrayList 怎么样,你可以创建一个ClientThread 类或其他东西,它的构造函数需要一个Socket 参数。然后,当您获得新连接时,请执行以下操作

Socket clientSocket = serverSocket.accept();
arrayList.add(new ClientThread(clientSocket));

【讨论】:

  • 这不是我想要的。我的服务器类中有它,每次收到连接时都会产生一个新线程。在新创建的那个线程中,我想创建一个新套接字并将一个客户端添加到该套接字。您正在尝试做的似乎是将无限客户端添加到同一个套接字并让他们等待轮到他们。那不是我想做的。
  • 那么你是想让两个客户端线程相互通信吗?
  • 是的,是的。这正是我想要做的。
  • 所以您需要实际创建线程部分的帮助,而不是通信部分,对吧?
  • 您不会在您的代码中确定这一点吗?等等,假设你有客户端 1、2 和 3。所以你不知道客户端 1 应该与 2 交谈,还是 2 应该与 3 交谈,等等?
【解决方案2】:

我们为不同的客户端使用不同的线程的主要原因是为了可以单独处理客户端,而不会阻塞可能想要不同东西的其他客户端。如果您想在之后扩展您的程序,例如为客户设置不同的难度级别,您将需要不同的设置。

当客户端连接时,会启动一个新线程并在服务器上的标志表中设置一个标志,表示“客户端可用”(可能包含有关客户端的更多信息;例如难度级别)。然后服务器告诉客户端正在等待一个合适的对手,然后返回等待。当合适的对手确实连接时,相应的标志包含对两个客户端的references,现在您有两个具有合适客户端的线程。

假设游戏是回合制的,不是实时的,游戏可以这样玩:开始时,每个客户端向服务器请求与另一个客户端对应的套接字,服务器给它,查找上面标志表中的参考。然后,客户端通过套接字通信决定它们之间的游戏、选项等。一旦两个客户都知道空棋盘的样子,他们就开始玩了;他们在棋盘上互相发送更改,例如“knight to d5”。他们自己处理完成,或者在服务器上保存记录。

在代码中,您需要使用同步方法线程安全对象来处理试图通信的单独线程。您可以通过the Java Tutorials page 进一步了解它。

【讨论】:

  • 但是在这种情况下,我只能在每台服务器上进行一场比赛。如果我想要尽可能多的游戏怎么办?那我怎么知道哪个thread1(连接的第一个客户端)与哪个thread2(连接的第二个客户端)通信?
  • @Fazer 已相应编辑。
  • 您将什么定义为参考?它们在客户对之间有何不同?
  • 就像@I1zZY 所说,您可以简单地将线程添加到包含线程的 ArrayList 中。或者你可以给他们起名字,并通过名字来引用他们。
  • 当我尝试将线程添加到数组列表时,它给了我这个错误消息:“'void' type not allowed here”。
猜你喜欢
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-06
  • 1970-01-01
  • 2016-04-27
相关资源
最近更新 更多