Solved

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

Posted on 2003-11-09
4
902 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

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
In this post we will learn different types of Android Layout and some basics of an Android App.
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Suggested Courses

624 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