0

I connect multiple clients to a server using Sockets and a ServerSocket. Currently my servers run() method has a while(bool) loop that creates a new socket whenever a client tries to connect but I want to break the loop from another method. Sounds easy but simply changing the boolean to false won't do since something waits on serverSocket.accept() for it to, well, accept.

Using setSoTimeout didn't work for me, as it throws an exception. I need the thread to loop and wait for new clients until one of them sends a "CLOSE" String via Stream, not for a set period of time, but I could be doing something wrong. I would like to keep serverSocket in try-with-resources so that everything closes when I close the JFrame with mouseclick, still I need it to close from code too. I also tried creating a "Ghost" client that should break the cycle but I think it's not an elegant solution and now I get socket closed exception in ClientThread first line ine while loop. I am so lost please help me.

the code:

class ClientThread implements Runnable{
    private Socket socket;
    private String name;
    private boolean running;
    private PhoneBookServer server;

    private ObjectOutputStream outputStream = null;

    ClientThread(PhoneBookServer server, Socket socket){
        this.server = server;
        this.socket = socket;
        new Thread(this).start();
    }

    public String getName(){
        return name;
    }

    public void disconnect(){
        try {
            outputStream.writeObject("OK BYE");
            server.printMessage("OK BYE");
            running = false;
            socket.close();
            socket = null;
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public void run(){
        String message;
        try(ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream input = new ObjectInputStream(socket.getInputStream());){
            outputStream = output;
            name = (String) input.readObject();
            running = true;
            server.addClient(this);
            while(running){
                message = (String) input.readObject();
                server.printMessage(this, message);

                if(message.equals("BYE")){
                    disconnect();
                    server.removeClient(this);
                }
                if(message.equals("CLOSE")){
                    server.disconnectAll();
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

interesting methods from the Server class:

    synchronized void disconnectAll(){
        for(ClientThread c : connectedClients){
            c.disconnect();
        }
        running = false;
    }

    public void run(){
        boolean socket_created = false;

        try(ServerSocket serverSocket = new ServerSocket(SERVER_PORT)){
            String host = InetAddress.getLocalHost().getHostName();
            System.out.println("Serwer został uruchomiony na hoście " + host);
            socket_created = true;

            while(running){
                Socket socket = serverSocket.accept();
                if (socket != null){
                    new ClientThread(this, socket);
                }
            }

        }catch (IOException e){
            e.printStackTrace();
            }
        }
    }
  • Does this answer your question? [How can I interrupt a ServerSocket accept() method?](https://stackoverflow.com/questions/2983835/how-can-i-interrupt-a-serversocket-accept-method) – rveerd Jan 11 '23 at 15:16

0 Answers0