用于网络游戏的Java MultiThreading套接字编程

时间:2012-10-06 06:47:47

标签: java multithreading sockets serversocket

我是java Multithreading的新手。实际上我想通过使用Socket编程在lan上制作两个玩家游戏。我只是希望当两个玩家都将连接到服务器后,游戏将开始。我的GameServer基本上是使用线程。当客户端连接到服务器时谁创建线程。我的逻辑是,当一个客户端与服务器建立连接之后,该线程将等到第二个线程进行连接。当第二个线程成功连接时。然后两个线程都将生效并开始工作。这是我的GameServer逻辑的连接部分。

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

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

2 个答案:

答案 0 :(得分:2)

你的服务器每次运行只支持一个匹配 - 你启动服务器,玩家连接,玩游戏,另一个游戏开始,你必须杀死服务器并重新启动 - 因为写入循环的方式。 / p>

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) 

功能,每次匹配都会启动一个新线程。你不是每个玩家都在他自己的线程中,因为会浪费资源(参见编辑^ 3)并且会更加重写很多码。请查看以下教程123

EDIT ^ 2:

“但我的困惑在于服务器如何知道现在播放器正在通信以及播放器2正在通信时...... Bcz服务器对于两个客户端都具有相同的套接字。”

不,服务器总是在给定端口侦听,并且每个请求都通过accept方法给出一个新连接(端口)。

java API doc是您最好的朋友 - 专门针对ServerSocket accept它说:

  

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

所以,当

playerOneSocket = welcomeSocket.accept();
执行了

,在playerOneSocket变量中你已经建立了“连接” 播放器一(在服务器和播放器都知道的某些其他端口上),服务器可以接受同一端口上的另一个连接 - 第二个播放器也是如此。例如。 1345是你的游戏端口:

  

P1:connect @ server:1345
  接受方法开始 - 第1行
  服务器:让我们在9999港口见面   P1:connect @ server:9999
  服务器:确定已连接
  接受方法第1行
  P2:connect @ server:1345
  接受方法开始 - 第2行
  服务器:让我们在港口10000见面   P2:connect @ server:10000
  服务器:确定已连接
  接受方法第2行

EDIT ^ 3:

我建议你这样做:首先,让它在每个匹配中使用一个线程,然后移动到每个玩家一个线程(如Tudor所示) - 游戏将对更大的网络延迟更敏感(例如,通过互联网)。为了在每个玩家模型中执行一个线程,您需要了解良好的线程和线程通信 - 请参阅this tutorial

答案 1 :(得分:1)

我认为你的意思是这样的?

class Player implements Runnable {

     private Socket socket;

     public Player(Socket socket) {
         this.socket = socket;
     }

     public void run() {
     }
}

List<Socket> players = new ArrayList<Socket>();
// accept two connections
for(int i = 0; i <= 1; i++)
{
     Socket playerSocket = welcomeSocket.accept();
     players.add(playerSocket);
}

// start one thread per connection
for(Socket socket: players) {
     new Thread(new Player(socket)).start();         
}