0

I have the following code that I call from my main as follows...

Thread tcpMultiServerThread = new Thread(new TCPMultiServer());
tcpMultiServerThread.start();

The class is as follows:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;


public class TCPMultiServer implements Runnable
{
    /**
     * The port that the server listens on.
     */
    private static final int PORT = 6788;

    /**
     * The set of all the print writers for all the clients.  This
     * set is kept so we can easily broadcast messages.
     */
    public static HashSet<PrintWriter> writers = new HashSet<PrintWriter>();

    /**
     * The appplication main method, which just listens on a port and
     * spawns handler threads.
     */
    public void run() {

        System.out.println("The TCP multi server is running.");
        ServerSocket listener = null;
        try
        {
            listener = new ServerSocket(PORT);
            while (true)
            {
                new Handler(listener.accept()).start();
            }
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
        finally
        {
            try
            {
                listener.close();
                System.out.println("Client Disconnected");
            }
            catch (IOException e)
            {

            }
        }

    }

    private static class Handler extends Thread {
        private Socket socket;
        private PrintWriter out;

        public  Handler(Socket socket) {
            this.socket = socket;
        }

        public void run()
        {
            try {
                // Create character streams for the socket.
                out = new PrintWriter(socket.getOutputStream(), true);

                System.out.println("Client Connected");
                writers.add(out);

                while (true)
                {
                    try
                    {
                        long millis = System.currentTimeMillis();
                        Thread.sleep(1000 - millis % 1000);
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            } catch (IOException e)
            {
                System.out.println(e);
            }
            finally
            {
                if (out != null) {
                    writers.remove(out);
                }
                try
                {
                    System.out.println("Client Disconnected");
                    socket.close();
                } catch (IOException e) {

                }
            }
        }
    }


}

This accepts new connections but a detection of remote closure never happens. My HashSet of writers therefore never decreases and only increases! None of my closure code seems to be caught and the connections eternally stay on!

Lee Armstrong
  • 11,420
  • 15
  • 74
  • 122

3 Answers3

0

Loop w/o any conditions - inifinity

           while (true)
            {
                try
                {
                    long millis = System.currentTimeMillis();
                    Thread.sleep(1000 - millis % 1000);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }

you must do something with socket, read/write/select, to detect that it actually closed by remote peer. for example (bad usage, just for example)

while (socket.getInputStream().read() >= 0)
rustot
  • 331
  • 1
  • 11
  • Yes I get that, but when I set a breakpoint in there the socket says it is still open! – Lee Armstrong Nov 02 '16 at 14:02
  • what way? isClosed()? it true only if you from your side have closed it. see http://stackoverflow.com/questions/10240694/java-socket-api-how-to-tell-if-a-connection-has-been-closed – rustot Nov 02 '16 at 15:32
0

Turns out the way to check client side is to check readLine() for null.

while (true)
                {
                    try
                    {
                        String line = in.readLine();
                        if (line == null)
                            return;
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
Lee Armstrong
  • 11,420
  • 15
  • 74
  • 122
0

In TCPMultiServer you're continuosly creating new Handlers

  while (true)
  {
       new Handler(listener.accept()).start();
  }

So you are continuously adding and adding clients. Maybe you should work on this

Massimo Petrus
  • 1,881
  • 2
  • 13
  • 26