Ted pottel
Ted pottel

Reputation: 6993

cannot get server socket to close

I'm making a simple chat server and just made it so each connection runs on a new thread.

The old version started a single thread for the server, it did a while loop, which would stop when a stop message was sent then close the socket.

The new version loops forever and create a new thread for each new connection. Now I cannot close the socket connection.

If you press a key and the main thread stops, the socket stays open. Thus when I run the program again I need to change the socket number.

code of server

while(true)
            {
                ///////////////////////////////////////////////////
                // get a new connection
                ///////////////////////////////////////////////////
                System.out.println("Aceepting connections on port 1030 \r");

                try{
                    // Get New Connection

                    // wait for ever on accepting new connections
                    server.setSoTimeout(0);  
                    connection=server.accept();

                    cConnection thread = new cConnection("thread3", connection);
             } catch(IOException ec)
             {
                    System.out.println(ec.getMessage());    
             }
}

code that starts server

Now each message comes in on a new thread, so I cannot tell it to stop and close the socket.

Upvotes: 1

Views: 1542

Answers (3)

nIcE cOw
nIcE cOw

Reputation: 24626

Looking into your problem, I understood one thing, that since you are putting

while (true), so your control always gets stuck at connection=server.accept(); listening for a new connection. So in order to stop the sockets you need to first find a way to stop looping in that while loop. Either you can set a Variable, like (int clientsConnected) to check the number of Clients, when that comes to zero stop that while loop. So you can stop your sockets.

Below is my sample code for clients which is doing the same thing for closing the Sockets. Hopefully this solves your problem.

    class GetNamesFromServer implements Runnable
    {  
      private Socket sForName, sForId;

      private BufferedReader in, inForName, inForId;
      private PrintWriter outForName, outForId;

      private static String clientNames;

      public GetNamesFromServer(Socket s1, Socket s2)
      {
        sForName = s1;
        sForId = s2;    
      }

      public void run()
      {    
        try
        {
          outForName = new PrintWriter(sForName.getOutputStream(), true);
          outForName.println(Client.clientName);
          System.out.println("Send Name : " + Client.clientName);
          outForName.flush();
        }
        catch(IOException e)
        {
          System.err.println("Error sending Name to the Server.");
        }

        try
        {
          inForId = new BufferedReader(new InputStreamReader(sForId.getInputStream()));
          Client.clientId = (inForId.readLine()).trim();
          System.out.println("Client ID is : " + Client.clientId);
        }
        catch(IOException e)
        {
          System.err.println("Error Receiving ID from Server.");
        }

        try
        {
          inForName = new BufferedReader(new InputStreamReader(sForName.getInputStream()));
          while (true)
          {        
            clientNames = inForName.readLine();
            if (clientNames != null && clientNames != "")
            {
               clientNames = clientNames.substring(1, clientNames.length() - 1);
               System.out.println("Names Received : " + clientNames);        
               String[] names = clientNames.split(", ");
               Client.nameClients.clear();
               for (String element: names)
                  Client.nameClients.add(element);
               Client.nPane.setText("");
              int size = Client.nameClients.size();
              System.out.println("Size of list : " + size);
              for (int i = 0; i < size; i++)
              {          
                 String name = Client.nameClients.get(i);          
                 String colour = Character.toString(name.charAt(0));
                 name = name.substring(1, name.length()) + "\n";
                 appendToNamePane(name, ReceiveMessages.getColour(Integer.parseInt(colour)),    "Lucida Console");
              }
              System.out.println("Clients Online : " + Client.nameClients);          
            }
          int index = Client.nameClients.indexOf(Client.clientId + Client.clientName);
          **if (index == -1)
          {
             sForName.close();
             break;
          }**
        }
      }
      catch(IOException e)
      {
        System.err.println("Error Receiving Names of Clients from Server");
      }
    }

NEW EDITION : You can add a cap to maximum number of clients that can connect, once that reaches your while loop will not go to connection = server.accept(); and hence when they are done chatting (after some time) i.e. totalClients = 0, you can stop your sockets as well, to stop the program.

if (totalClients == 0)
{
  socket.close();
  serverSocket.close();
}

Regards

Upvotes: 0

Ernesto Campohermoso
Ernesto Campohermoso

Reputation: 7381

You need to provide a flag that must be globally accesible, so when some client wants to stop the server then change the variable ans stops the bucle. By example:

class YourServer {
  private static boolean execute = true;

  public static  synchronized void stop() {
    execute = false;
  }
  public void yourMethod() {
     while(execute) {
         // implement your server here
     }
  }
}

When a client send the command STOP you must be do

  YourServer.stop();

Upvotes: 2

Peter Lawrey
Peter Lawrey

Reputation: 533820

If you want a stop command to stop the server you can call System.exit() to force the program to store or just closing server is likely to be all you need.

Upvotes: 0

Related Questions