我是Java多线程中的新手。实际上,我想通过使用Socket编程在LAN上的Java上进行两人游戏。我只希望当两个玩家都将连接到服务器后,游戏才能开始。我的GameServer基本上是使用线程。客户端将何时连接到服务器,谁在创建线程。我的逻辑是,当一个客户端将与服务器建立连接之后,该线程将等待直到第二个线程建立连接。当第二个线程成功建立连接时。然后,两个线程将处于活动状态并开始工作。这是我的GameServer逻辑的连接部分。

for(int i = 0; i <= 1; i++) {
    connectionSocket = welcomeSocket.accept();
    System.out.println("Connection has been accepted");
    no++;
}


但是此代码在逻辑上不起作用。有什么想法或建议吗?

最佳答案

您的服务器每次运行仅支持一场比赛-您启动服务器,连接玩家,玩游戏,并且要开始另一款游戏,您必须杀死服务器并重新启动-因为编写循环的方式。

while(true) {
    playerOneSocket = welcomeSocket.accept(); // 1
    playerTwoSocket = welcomeSocket.accept(); // 2
    startNewMatch(playerOneSocket,playerTwoSocket);
}

public void startNewMatch(final Socket pOne, final Socket pTwo) {
    new Thread(new Runnable() {
        @Overrride
        public void run() {
            // pOne, pTwo variables visible here
        }
      }).start();
}


(任何)服务器必须始终可以自由地接受新请求,这就是为什么您在一个处理单个匹配逻辑的新线程中传递两个套接字的原因。 startNewMatch函数的参数已定为最终参数,可以在run方法中看到,但您可能需要创建一个扩展Thread的新类,并将其传递给构造函数。希望能有所帮助。

编辑:

while循环在您的主线程中运行,例如在内部:

public static void main(String[] args)


函数,并且每次匹配都会启动一个新线程。您并不需要每个线程都在自己的线程中,因为那样会浪费资源(请参阅EDIT ^ 3),并且编写此类代码会更加繁重。看看以下教程123

编辑^ 2:

“但是我的困惑是服务器如何知道现在播放器正在通信,而当播放器2正在通信.... Bcz服务器为两个客户端具有相同的套接字。”

不,服务器始终会侦听给定的端口,并且accept方法会为每个请求提供一个新的连接(端口)。

Java API文档是您最好的朋友-专门针对ServerSocket accept,它表示:


  侦听与此套接字建立的连接并接受它。该方法将阻塞直到建立连接


所以,当

playerOneSocket = welcomeSocket.accept();


执行后,在playerOneSocket变量中,您已经建立了与
播放器一个(在服务器和播放器都知道的其他端口上),并且服务器可以在同一端口上接受另一个连接-第二个播放器也一样。例如。 1345是您的游戏端口:


  P1:连接@服务器:1345
  接受方法开始-第1行
  服务器:让我们在端口9999见面
  P1:连接@服务器:9999
  服务器:确定连接
  接受方法结束-第1行
  P2:连接@服务器:1345
  接受方法开始-第2行
  服务器:让我们在端口10000见面
  P2:连接@服务器:10000
  服务器:确定连接
  接受方法第二行


编辑^ 3:

我建议您这样做:首先,使其每场比赛只能使用一个线程,然后再将每个玩家移至一个线程(如Tudor所示)-游戏将在更大的网络延迟(例如,通过Internet)上做出更好的响应。为了对每个播放器模型执行一个线程,您需要了解良好的线程和线程通信-请参见this tutorial

10-06 09:34