Solved

Java socket server: how to stop the server in a client-friendy way

Posted on 2003-11-09
4
897 Views
Last Modified: 2011-09-20
Hi there,

I got 3 classes, two are Threads ("MySocketServer" and "MySocketServerThread"), the other is my GUI ("MyGUI").
The GUI has 2 buttons "Start Server" and "Stop Server".
When I click "Start Server", a new MySocketServer-Thread is launched that does the following:
Create a vector with 5 "MySocketServerThread"-Threads that go to wait()-mode till they're waken up by "MySocketServer" (.accept()-method) the moment a client tries to connect.

This works finde, the gui isn't blocked because the server has thread of it's own and up to 5 sockets can be opened. (see code below).
My problem is the "Stop Server"-Button. Once I click that, I want
1. The "MySocketServer" to stop accepting new connections -> I've done that with a simple ServerSocket.close() method call.
2. a very clean disconnect, so that all 5 clients get a "goodbye"-message.

Here is my code:
MySocketServer:
public class SauSocketServer implements Runnable
{
  public static Vector serverThreads = new Vector();
  private ServerSocket serverSocket;

  private static int serverPort = 1701;
  public static int numberOfThreads = 5;
  public static int timeout = 0;
  public boolean runServer = false;
  private Thread runner;
  private boolean acceptCients = true;

  public MySocketServer(int port)
  {
    this.serverPort = port;
    this.runner = new Thread(this);
  }

  public void run()
  {
    /* create pool of new serverThreads and start them */
    for (int i = 0; i < this.numberOfThreads; ++i)
    {
      MySocketServerThread serverThread = new MySocketServerThread();
      new Thread(serverThread, "serverThread#" + i).start();
      serverThreads.addElement(serverThread);
    }

    /* create serverSocket and wait for new connections */
    try
    {
      this.serverSocket = new ServerSocket(this.serverPort);

      while (this.acceptCients)
      {
      Socket socket = this.serverSocket.accept();
      /* once a client tries to connect to the socket, assign one of the
       * threads running, described by the vector serverThreads
       */
      MySocketServerThread serverThread;

      boolean foundFreeThread = false;
      for (int i = 0; i < this.numberOfThreads; ++i)
      {
        serverThread = (MySocketServerThread) this.serverThreads.elementAt(i);
        if (!serverThread.running)
        {
          serverThread.wakeUp(socket);
          foundFreeThread = true;
          break;
        }
      }
      if (!foundFreeThread) System.out.println("DID NOT FIND FREE THREAD FOR CLIENT");
      }
    }
    catch (IOException e)
    {
      System.out.println("1. b) SocketServer returned IOException");
    }
  }

  public void startServer() throws Exception
  {
    if (!this.runner.isAlive())
    {
      this.runner.start();
    }
  }
/* here's my attempt for the stopServer-Method ... this produced very bad results */
  public void stopServer()
  {
    System.out.println("1. a) Telling SocketServer to stop accepting new clients");
    if (this.runner.isAlive())
    {
      this.acceptCients = false;
      try
      {
      this.serverSocket.close(); // using this instead of a timeout to archive faster results
      }
      catch (IOException e)
      {
      System.out.println(e);
      }

      System.out.println("1. c) Told SocketServer to stop accepting new clients");

      MySocketServerThread serverThread;

      for (int i = 0; i < this.numberOfThreads; ++i)
      {
      serverThread = (MySocketServerThread) this.serverThreads.elementAt(i);

      if (serverThread.running)
      {
        System.out.println("2. a) serverThread " + i + " is running. Telling to stop handling client");
        serverThread.keepHandlingClient = false;
      }
      else
      {
        System.out.println("serverThread " + i + " is idle.");
      }

      while (serverThread.running)
      {
        // wait for serverThread to stop running
      }
      System.out.println("3. serverThread " + i + " has stopped running and is in wait() mode now");
      serverThread.keepAlive = false;
      }
    }
  }
}

MySocketServer:

public final class MySocketServerThread implements Runnable
{
  public boolean running = false;
  public boolean keepAlive = true;
  public boolean keepHandlingClient = true;
  public Socket socket;
  public BufferedReader in;

  public MySocketServerThread()
  {
    socket = null;
  }

  public synchronized void wakeUp(Socket s)
  {
    this.socket = s;
    this.notify(); // wakes up the thread
  }

  public synchronized void run()
  {
    while (this.keepAlive)
    {
      if (this.socket == null)
      {
      try
      {
        this.wait();
      }
      catch (InterruptedException e)
      {
        continue;
      }
      }
      this.running = true;
      try
      {
      this.handleClient();
      }
      catch (Exception e)
      {
      this.running = false;
      // error handling
      }
      try
      {
      this.socket.close();
      }
      catch (IOException e)
      {
      System.out.println(e);
      }

      this.running = false;
    }
  }

  private void handleClient() throws IOException
  {
    in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
    BufferedOutputStream outStream = new BufferedOutputStream(this.socket.getOutputStream());
    PrintStream outPrint = new PrintStream(outStream);

    int line = 0;

    boolean keepListening = true;

    this.socket.setSoTimeout(MySocketServer.timeout);

    while (this.keepHandlingClient)
    {
      line = in.readLine();
      if (line == null)
      {
      this.keepHandlingClient = false;
      }
     
      outPrint.println("You said: " + line);
      outPrint.flush();
    }
    System.out.println("This is ServerThread Nr ?. My client-listening-loop has just been broken!");
  }
}

The main problem is the BufferedReader in which is blocking the while-loop so I can't simply say this.keepHandlingClient = false to stop listening on the socket.

Any ideas?
0
Comment
Question by:sandman666
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 

Author Comment

by:sandman666
ID: 9711007
of course int line = 0; is not right. Replace that with String line; I've been experimenting a lot with the code before I posted it here so sorry.
0
 
LVL 5

Accepted Solution

by:
lwinkenb earned 250 total points
ID: 9711368
In your MySocketServerThread add a function like so:

public void closeConnection() throws IOException{
  // Send the client a goodbye message here if you want:
  socket.close();
  // clean up any resources in the thread that you need to
}

Then in your server class, instead of calling:

serverThread.keepHandlingClient = false;

call:

serverThread.closeConnection();
0
 

Author Comment

by:sandman666
ID: 9718377
hey that works nicely! Didn't think it was that easy.

Thanks alot!
0
 
LVL 5

Expert Comment

by:lwinkenb
ID: 9719926
=)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
In this post we will learn different types of Android Layout and some basics of an Android App.
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question