Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 288
  • Last Modified:

Threads...

Hi, I am developing a simple multi-threaded server.

I have one button to start listening on a given port(START), and another one to stop listening(STOP).

I can't seem to get them to work properly, and i have reverted to killing the thread on STOP and creating a new one every time START is pushed.

I know there is a way to use wait() and notify(), but when i try, the gui freezes up

Please let me how to get this to work better.
0
kmule81
Asked:
kmule81
  • 4
  • 4
  • 3
  • +2
1 Solution
 
CoenMeerbeekCommented:
Could you give a us some more information? Some code of your project? Thnx
0
 
TimYatesCommented:
class PortListener implements Runnable
{
  private volatile Thread runner = null ;
  private int port ;
  private ServerSocket ss ;

  public PortListener( int port )
  {
    this.port = port ;
  }

  public void start()
  {
    if( runner == null )
    {
      runner = new Thread( this ) ;
      ss = new ServerSocket( port ) ;
      runner.start() ;
    }
  }

  public void run()
  {
    while( runner != null )
    {
      // put your listen code here
    }
  }
 
  public void stop()
  {
    ss.close() ;
    runner = null ;
  }
}

...

PortListener pl = new PortListener() ;
pl.start() ;

...

pl.stop() ;

...

pl.start() ;
0
 
TimYatesCommented:
Or something similar...
0
Technology Partners: 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!

 
kmule81Author Commented:
This is very similar to what i have now.  The only difference is that you declared the 'runner' to be volatile.

So, I shouldn't be telling a thread to wait and then later telling it to resume (notify)?

For some reason, i thought that was preferred
0
 
kmule81Author Commented:
Also, with that code, my GUI will freeze up every once in a while (after repeatedly starting and stopping the thread), which i cant understand.

This is what i have...

       ...(in constructor)
       stopButton.addActionListener (new ActionListener()
            {
                public void actionPerformed(ActionEvent e){
              if(threadRunning) {
               stopButton.setEnabled(false);
               startButton.setEnabled(true);
                         stopServer();
              }
                }
            });

        startButton.addActionListener (new ActionListener()
            {
                public void actionPerformed(ActionEvent e){
              if(!threadRunning) {
               startButton.setEnabled(false);
               stopButton.setEnabled(true);
                         startServer();
              }
                }
            });
       .....


    public void startServer(){

        if(runner == null) {
         threadRunning = true;
            runner = new Thread(this);
            runner.start();
        } else {
         runner = null;
         startServer();
        }
    }

    public void stopServer(){
        if(runner != null) {
            threadRunning = false;
         try { ss.close();    } catch(Exception e)System.out.println(e);}
        }
    }
   public void run() {
        port=Integer.parseInt(portInput.getText());
        display("Server Started on Port: " + port + "\n");

        try {
            ss = new ServerSocket(port);
            while(true) {
                display("Listening again ** port: " + port + "\n");
                Socket s = ss.accept();
                new Thread(new FileRequest(s,this)).start();
                display("Got a file request... \n");
            }

        }  catch (Exception e) {System.out.println(e);}
    }

    public synchronized void display(String text) {
        a.append(text);
    }
0
 
karlikaCommented:
The version you have is the best you can get from java.
It is simply impossible to pause a java-socket.

The GUI usually freezes when you produce a deadlock or infinite loop in the event-thread. I personally bundle all event-handling in an inner class.

This makes debugging much more confortable.

Marko
0
 
kmule81Author Commented:
Marko,

Do you mean that instead of calling the stop and start functions, i should just do my actions right there?

Could you show me an example of what you mean?
0
 
karlikaCommented:
The stopServer and startServer methods are actually called by the event-thread because they are results of clicking on the corresponding buttons. So if you produce a deadlock or tell this thread to wait() the event-thread is locked and will not take any actions (like clicking on the buttons) - the GUI freezes.

For easier debugging I put any Listeners in an inner class.

e.g.:

public class Server{

  private Button startButton;
  private Button stopButton;

  public class Listener implements ActionListener{
    public void actionPerformed(ActionEvent ae){
      if(ae.getSource()==startButton)startServer();
      if(ae.getSource()==stopButton)stopServer();
    }
    private void startServer(){
      ....
    }
    private void stopServer(){
      ....
    }
  }
 
  Listener listener = new Listener();

  public Server(){
    //initialize
    startButton = new Button("Start");
    startButton.addActionListener(listener);
    stopButton = new Button("Stop");
    stopButton.addActionListener(listener);
  }
}


But it doesn't make any difference in how your code is handeld. It's just a cosmetic operation to make it easier to find possible deadlocks in the event-thread.

Marko
0
 
Mayank SAssociate Director - Product EngineeringCommented:
You need a ServerSocket object in the main method which will act as a listener to the port and whenever it accepts a new connection, it will start a new thread (meaning that it'll instantiate an object of a class which extends Thread or implements Runnable. The run () method of this class should contain all the functionality of the server (whatever it is supposed to do for every client) and wherever you wish to terminate the thread, just put a return statement. You don't even need to call wait () or notify () anywhere. It'll be automatically handled. You must have an infinte while loop in the run () method which will go as long as the client is connected and the moment the client disconnects, the client system will either send an appropriate packet (I don't know your protocol) or else the client might get disconnected due to a power failure, following which there'll be a SocketException which can be caught - that is where you should terminate th thread.

import java.net.* ;
import java.io.* ;

class ServerThread extends Thread
{
  Socket s ;
  InputStream is ;
  OutputStream os ;

  ServerThread ( Socket ss ) // constructor ()
  {
    s = ss ;
    is = s.getInputStream () ; // for reading from the client
    os = s.getOutputStream () ; // for sending to the client

    start () ;

  } // end of constructor ()

  public void run ()
  {
    try
    {
      while ( true )
      {
        // entire functionality of the server

        // suppose you wish to kill the thread here
           return ;

      } // end while

    } // end of try block

    catch ( SocketException se ) // client disconnected due to power-failure or something
    {
      return ; // kill this thread

    } // end of catch block

  } // end of run ()

} // class definition over

class MainApp
{
  public static void main ( String args[] )
  {
    ServerSocket ss = new ServerSocket ( 2025 ) ; // assuming 2025 to be the port number
   
    while ( true ) // or whatever condition - like the clicking of the Stop button - the code will be a little different
    {
      Socket s = ss.accept () ;
      new ServerThread ( s ) ;
     
    } // end while
   
  } // end of main ()
   
} // class definition over

If you need more help, please ask.

Mayank.
0
 
karlikaCommented:
This is what we had before, but the thread will run into eternity, because ss.accept() blocks until a connection is made, or an Exception is raised.

Marko
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Nopes! It doesn't - the threads (along with the main  thread)will be executing parallelly.

Mayank.
0
 
karlikaCommented:
Sorry, you are right. It's not exactly the same. You are using the main-thread to get the connections (it is blocked until the connect or an Exception).
After a connect you start a new Thread to handle the servertasks.

Kmule's code starts a GUI; the event-thread (by clicking the startButton) starts a receiverThread, with the ServerSocket listening. If a connection is received, the line:
" new Thread(new FileRequest(s,this)).start();"
starts a new thread to run the servertask.

I'm pretty sure, all of those threads will run parallelly.

Marko
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Kmule81,

You don't seem to be content with the answers. If so, please specify what more do you want so that we can help you out.

Mayank.
0
 
kmule81Author Commented:
Thank you both for all your help.

I am sorry for the delay, I was away for the week.

mayankeagle- thanks for another way of looking at the problem, but i went with the original one.

Kenny
0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 4
  • 4
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now