简体   繁体   English

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

[英]Java MultiThreading socket Programming for Network Game

I am new in java Multithreading. 我是java多线程中的新手。 Actually I want to make two player game on java on lan by using Socket programming. 实际上,我想通过使用Socket编程在LAN上的Java上进行两个玩家的游戏。 I just want that when both player will connect to the server after that the game will start. 我只希望当两个玩家都将连接到服务器后,游戏才能开始。 My GameServer is basically using thread. 我的GameServer基本上是使用线程。 Who make thread when client will connect to the server. 客户端将何时连接到服务器,谁在创建线程。 My logic is that when one client will make a connection with the server after that this thread will wait until the 2nd thread will make connection. 我的逻辑是,当一个客户端将与服务器建立连接之后,该线程将等待直到第二个线程建立连接。 When second thread successfully make a connectin. 当第二个线程成功建立连接时。 Then both thread will be live and start work. 然后,两个线程将处于活动状态并开始工作。 This is connection part of my GameServer logic. 这是我的GameServer逻辑的连接部分。

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

But this code will not work logically. 但是此代码在逻辑上不起作用。 Any idea or suggestion please? 有什么想法或建议吗?

Your server will support only one match per running - you start the server, players connect, play the game and, for another game to start, you must kill the server and restart - because of the way for loop is written. 您的服务器每次运行仅支持一次比赛-您启动服务器,连接玩家,玩游戏,并且要开始另一款游戏,您必须杀死服务器并重新启动-因为编写循环的方式。

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();
}

(Any) server always must be free to accept new requests, that's why you pass the two socket's in a new Thread where you handle the single match logic. (任何)服务器必须始终可以自由接受新请求,这就是为什么要在处理单个匹配逻辑的新线程中传递两个套接字的原因。 The arguments of the startNewMatch function have been made final to be seen inside of the run method, but you'll probably want to make a new class extending Thread and pass them in a constructor. startNewMatch函数的参数已定为最终参数,可以在run方法中看到,但您可能需要创建一个扩展Thread的新类,并将其传递给构造函数。 Hope that helps. 希望能有所帮助。

EDIT: 编辑:

The while loop runs in your main thread, eg inside: while循环在您的主线程中运行,例如在内部:

public static void main(String[] args) 

function, and you start one new thread per every match. 函数,并且每次匹配都会启动一个新线程。 You don't wan't every player in his own thread since that would be a waste of resources (see EDIT^3) and would be a lot heavier to write such code. 你不wan't每个球员在自己的线程,因为 那将是对资源的浪费 (请参阅编辑^ 3),将重很多写这样的代码。 Take a look at following tutorials 1 , 2 , 3 看看下面的教程123

EDIT^2: 编辑^ 2:

"But my confusion is that how server will know that now playerone is communicating and when player two is communicating....Bcz server has same socket for both of the client." “但是我的困惑是服务器如何知道现在玩家正在通信以及何时玩家2正在通信……Bcz服务器为两个客户端都具有相同的套接字。”

No, server always listens at the given port, and each request is given a new connection (port) by the accept method. 不,服务器始终会侦听给定的端口,并且accept方法会为每个请求提供一个新的连接(端口)。

java API doc is your best friend - specifically for for ServerSocket accept it says: Java API文档是您最好的朋友-专门为ServerSocket接受的文档说:

Listens for a connection to be made to this socket and accepts it. 监听与此套接字建立的连接并接受它。 The method blocks until a connection is made 该方法将阻塞直到建立连接

So, when 所以,当

playerOneSocket = welcomeSocket.accept();

is executed, in the playerOneSocket variable you ve got the established "connection" to the player one (on some other port known to both server and player), and the server can accept another connection on the same port - same goes again for the second player. 执行后,在playerOneSocket变量中,您已经与播放器建立了“连接”(在服务器和播放器都知道的其他端口上),并且服务器可以在同一端口上接受另一个连接-第二个连接再次进行播放器。 Eg 1345 is your game port: 例如1345是您的游戏端口:

P1: connect @ server:1345 P1:连接@服务器:1345
accept method start - line 1 接受方法开始-第1行
SERVER: lets meet at port 9999 服务器:让我们在端口9999见面
P1: connect @ server:9999 P1:连接@服务器:9999
SERVER: ok connected 服务器:确定连接
accept method end - line 1 接受方法第1行
P2: connect @ server:1345 P2:连接@服务器:1345
accept method start - line 2 接受方法开始-第2行
SERVER: lets meet at port 10000 服务器:让我们在端口10000见面
P2: connect @ server:10000 P2:连接@服务器:10000
SERVER: ok connected 服务器:确定连接
accept method end - line 2 接受方法第二行

EDIT^3: 编辑^ 3:

I suggest you do like this: First, make it work with one thread per match, then move to one thread per player (as shown by Tudor)- the game will be more responsive on bigger network lag (eg over the Internet). 我建议您这样做:首先,使其每场比赛只能使用一个线程,然后每位玩家移至一个线程(如Tudor所示)-游戏将在更大的网络延迟(例如通过Internet)上做出更好的响应。 In order to do one thread per player model you'll need to understand good threading and thread communication - see this tutorial 为了每个玩家模型做一个线程,您需要了解良好的线程和线程通信-请参阅本教程

I think you mean something like this? 我想你的意思是这样的?

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();         
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM