Java处理多个客户端套接字

时间:2013-12-24 02:14:42

标签: java sockets client

处理到同一服务器/ ip的多个客户端连接的有效方法是什么。

目前我有一个服务器套接字,每次新玩家加入游戏时都会创建一个新线程。

我如何处理球员?我想我可以通过IP地址来做,但我不知道该怎么做。此外,由于我正在测试本地连接以及玩家如何在同一IP上使用多个帐户,因此这种方法效率似乎不高。

我希望能够管理能够将其引导出游戏并修改其帐户的玩家。提前致谢。 :)

1 个答案:

答案 0 :(得分:3)

这就是我的网络方式(如果你愿意,可随意发表评论):

“Master”服务器包含ServerSocket。 “Sub”服务器处理各个客户端。作为类比,考虑一家餐馆。 “主服务器”是接待员。当客户端进入时,他接受客户端的请求并将其分配给“子服务器”。 “子服务器”是服务员。他们处理个别客户请求。因此,你会有这样的事情:

public class Server extends Thread {

    final private ServerSocket m_serverSocket;
    final public static int MAX_CLIENTS = 3000;
    final private SubServer[] m_clientConnections = new SubServer[ MAX_CLIENTS ];

    public Server( int port ) throws IOException {
         this.m_serverSocket = new ServerSocket( port );
         start();
    }

    @Override
    public void run() {
        while ( !this.interrupted() ) {
             //wait for clients
             Socket connection = this.m_serverSocket.accept();
             assignConnectionToSubServer( connection );
        }
    }

    public void assignConnectionToSubServer( Socket connection ) {
         for ( int i = 0 ; i < MAX_CLIENTS ; i++ ) {

             //find an unassigned subserver (waiter)
             if ( this.m_clientConnections[ i ] == null ) {
                  this.m_clientConnections[ i ] = new SubServer( connection , i );
                  break;
             }
         }
    }

    protected class SubServer extends Thread {

        final private int m_id;
        final private Socket m_connection;

        //you can store additional client properties here if you want, for example:
        private int m_gameRating = 1500;

        public SubServer( Socket connection , int id ) {
            this.m_id = id;
            this.m_connection = connection;
            start();
        }

        @Override
        public void run() {
             while( !this.interrupted() ) {
                 //process a client request
                 //this is for you to implement
             }
        }

        //as an example, if you read String messages from your client,
        //just call this method from the run() method to process the client request
        public void process( String message ) {

        }

        /**
         * terminates the connection with this client (i.e. stops serving him)
         */
        public void close() {
            try {
                 this.m_connection.close();
            } catch ( IOException e ) {
                 //ignore
            }
        }
    }
}

所以,通过这一切,您应该能够为许多客户提供服务。如果您想踢客户端,请执行

clientConnection[ i ].close();

每个客户端的id都存储在SubServer对象中。

如果需要,您可以在每个子服务器中存储其他属性。一旦建立了网络,这就像非联网计划一样“正常”。

编辑:

现在直接回答你的问题:

Q值。我该如何处理球员?

一个。您使用SubServer对象处理播放器。您可以在SubServer类中定义其他方法以实现所需的功能。具体来说,如果您需要区分用户,请强制他们在开始玩游戏之前提供唯一的用户名。

Q值。我希望能够管理能够将其引导出游戏并修改其帐户的玩家

一个。使用close()方法启动,它们将与服务器断开连接。您可以在SubServer对象中指定帐户属性,并在服务器运行时修改这些属性。

编辑:

现在,您可能拥有一个ActionListener,可以使用所有用户

来观察您的JList
public class UserListListener implements ActionListener {

    final private Server m_networking;

    //you need to pass a reference to the server to your listener
    //you may also need to pass a reference to the user interface (JList) to your listener as well
    public UserListListener( Server networking ) {
        this.m_networking = networking;
    }

    public String getSelectedUser() {
        //determine the selected user on the JList
    }

    @Override
    public void actionPerformed( ActionEvent e ) {
        String command = e.getActionCommand();
        if ( command.equals( "kick" ) ) {

            //so here, you determine the user that was selected and tell the server to kick him
            server.kick( getSelectedUser() );
        }
    }
}

编辑:

在服务器类

public void kick( String username ) {
    for( int i = 0 ; i < MAX_CLIENTS ; i++ ) {
        if ( this.m_clients[ i ].getUsername().equals( username ) {
            this.m_clients[ i ].close();
            this.m_clients[ i ] = null;
        }
    }
}