0

I'm new to java and especially to java networking, but what I'm trying to do is set up a server (for a game). When TWO clients are connected to the server, I want to refuse any other connection. Am I able to close the ServerSocket? And if the ServerSocked is closed, those two connections which has been ran as threads and stored in a collection are still alive and able to cummunicate with the server? I hope you've got my point.

Here's the source code:

//Server
public synchronized List<ClientThread> getClients(){
    return clients;
}


public void run() {
    try {
        while(true){

            Socket clsock = srvsock.accept();

            if(getClients().size() == 2){
                System.out.println("Too many connections!");
                clsock.close();
                continue;
            }

            ClientThread clt = new ClientThread(clsock);
            clients.add(clt);
            clt.start();
            System.out.println("Connection accepted.");

        }
    } catch (IOException ex) {
        ex.printStackTrace(System.err);
    }
}

And with this code, I'm not able to detect on the Client if the connection is still alive, or the server has closed the connection. Thanks in advance.

kubisma1
  • 307
  • 5
  • 13
  • I think it will work as you describe but have you tested it? Have your ClientThread read from the socket's input stream with a BufferedReader and output each line as it is read. Then write a test client that writes to the output stream line by line with a Thread.sleep between each line. Run three instances of your test client and if (in the server output stream) you see the "Too many connections" message followed by output from the other two clients then it is working as you want. – Paul Medcraft Feb 06 '15 at 14:38

2 Answers2

1

Code for test client:

Socket s = new Socket("localhost", 8932);               
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

for (int i=0; i<20; i++) {
    bw.write(String.valueOf(i));
    bw.newLine();
    bw.flush();
    Thread.sleep(1000);
}
bw.close();

And for the ClientThread:

BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
while (true) {
    String misc = in.readLine();
    System.out.println(misc);
    if (misc==null || misc.length()==0)
        break;
}
in.close();

Output:

Connection accepted.
0
Connection accepted.
0
1
Too many connections!
1
2
2
3

So it works as you intended. By the way, it is usually better to implement Runnable rather than extend Thread - see "implements Runnable" vs. "extends Thread"

Community
  • 1
  • 1
Paul Medcraft
  • 1,386
  • 11
  • 23
  • No worries. Instead of closing the ServerSocket, you could change while (true) to while (clients.size() < 2) – Paul Medcraft Feb 06 '15 at 16:16
  • I would like to ask you one more question. I'm doing the application with GUI. When the user presses create button, it will create a thread (my GUI class extending JFrame implements Runnable) in this way: Thread t1 = new Thread(this); t1.start(); In run() method it creates instance of Server... Is it a good idea make the same user as a Client after that he created the server? After t1.start(); I'm doing this: Client cl = new Client("localhost"); – kubisma1 Feb 06 '15 at 16:39
  • So you'd have two players, one of them providing the server and a client, and one acting solely as client? Sounds a little unwieldy. I would either have one player as client and one as server, or both as clients of a separate server. – Paul Medcraft Feb 06 '15 at 16:49
  • I'm trying to imagine it. (player as Server and player as Client). Correct me if I'm wrong but the class ClientThread won't be needed, the cycle in the Server class would be also unnecessary? – kubisma1 Feb 06 '15 at 17:04
  • @PaulMedcraft i know this is kind of random, but using the while(clients.size() < 2), when the client closes the connection, will it still be on the "clients" List? I mean, after one closes, if another client connects will it still be blocked? If it's not automatic, how do we know on the server when to remove it? – Pedro Lino Jan 07 '16 at 23:03
  • @PedroLino yes, you'd need to remove`clt` from `clients` when you are finished with it. – Paul Medcraft Jan 09 '16 at 09:05
0

Every time a connection is established, the server returns a new socket ( when you use srvsock.accept() ) for the next connection. So you can close "srvsock" without affecting "clsock". To test if they are alive, check this post How do I check if a Socket is currently connected in Java?. Hope you can solve your problem.

Community
  • 1
  • 1
diningphil
  • 416
  • 5
  • 18
  • I wasn't sure about that. Thanks a lot. – kubisma1 Feb 06 '15 at 14:47
  • I've tried to break the cycle after reaching two connections, closed the srvsock and exception has been thrown: Closing server. //Output after srvsock.close(); java.net.SocketException: Socket closed at java.net.SocketInputStream.socketRead0(Native Method)... – kubisma1 Feb 06 '15 at 15:02
  • Can you paste the code that is reading from the socket? Presumably that is inside ClientThread? – Paul Medcraft Feb 06 '15 at 15:20