Nicola Bena
Nicola Bena

Reputation: 98

Is there an event in Java Socket when socket receive data?

I write a Swing Java program, with one client and one server with Socket of java.io. When client push a button something is send to the server and then the server should send something to the client. To implement this, I need to know if there is and event like "onClientRead" in C++, because I have some other different buttons that do other things, so I cannot put the ReadLine() method in every of those. I know that I can use the the socket in java.nio, but if there is something in the socket of java.io it is better. Thanks.

Upvotes: 4

Views: 15120

Answers (2)

xkothe
xkothe

Reputation: 674

This can be done using a separate Thread with read (which is a blocking method):

Thread t = new Thread() {
  public void run() {
    InputStream is = clientSocket.getInputStream();
    byte[] buffer = new byte[1024];
    int read;

    while(true) {
      read = is.read(buffer);
      onClientRead(clientSocket, read);
    };
  }
};
t.start();

This is a "test way", try make a separete class for this Thread.

Upvotes: 2

InPursuit
InPursuit

Reputation: 3293

The InputStream returned from your Socket on both ends will block if there is no data to be read (i.e. the read() method on the InputStream will not return until data is read). If you are doing the read() in the SwingEventThread (i.e. when the user clicks a button) then your UI will appear to lock up. The available() method on InputStream will return a number greater than 0 if there are bytes available to be read so you could use that.
However, it sounds like you should write some additional code that exists outside of your GUI which reads from the InputStream and fires its own event when data is read. Your GUI can then listen for that event. Something like this:

public class InputStreamReader
  implements Runnable
{
   protected InputStream in;
   protected List<ChangeListener> listeners;

   public InputStreamReader( InputStream in )
   {
     this.in = in;
     this.listeners = new ArrayList<ChangeListener>();
   }

   public void addChangeListener( ChangeListener l )
   {
     this.listeners.add( l );
   }

   public void run()
   {
     byte[] bytes = new byte[256]; //make this whatever you need
     in.read( bytes );

     //need some more checking here to make sure 256 bytes was read, etc.
     //Maybe write a subclass of ChangeEvent
     ChangeEvent evt = new ChangeEvent( bytes );
     for( ChangeListener l : listeners )
     {
       l.stateChanged( evt );
     }
   }
}

This class is a "Runnable" since the InputStream read method blocks so it needs to be run in a different thread. To start this class:

InputStreamReader r = new InputStreamReader( in );
//add your listener here
Thread t = new Thread( r );
t.start();

Upvotes: 3

Related Questions