简体   繁体   中英

Java Handling Multiple Client Sockets

What is an efficient way to handle multiple client connections to the same server/ip.

Currently I have a server socket that creates a new thread every time a new players joins the game.

How do I handle the players? I'm thinking that I can do it via IP address however I do not know how to do that. Also, as I'm testing on a local connection and how players could use multiple accounts on the same IP this method doesn't seem efficient.

I would like to be able to manage players with the ability to boot them out of the game and modify their accounts. Thanks in advance. :)

this is how I do my networking (feel free to comment if you'd like):

"Master" Server contains the ServerSocket. "Sub" Server deals with the individual clients. As an analogy, consider a restaurant. The "Master Server" is the receptionist. When a client comes in, he takes the client's request and assigns him to a "Sub Server." "Sub Servers" are the waiters. They process individual client requests. Thus, you'd have something like this:

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
            }
        }
    }
}

So, with all this, you should be able to serve many clients. If you want to kick the client, just do

clientConnection[ i ].close();

the id of each client is stored in the SubServer object.

You can store additional properties within each subserver if you want. Once the networking is set up, this is more "normal" like an un-networked program.

Edit:

To answer you questions directly now:

Q. How do I handle the players?

A. You handle the players using the SubServer object. You can define additional methods within the SubServer class to achieve functionality you want. Specifically, if you need to distinguish between users, force them to provide a unique username before they can start playing the game.

Q. I would like to be able to manage players with the ability to boot them out of the game and modify their accounts

A. Boot using the close() method and they will be disconnected from the server. You can specify account properties in the SubServer object, and modify these properties while the Server is running.

Edit:

So now, you might have an ActionListener that observes your JList with all the users

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

Edit:

In the server class

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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