简体   繁体   中英

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.

The InputStream returned from your Socket on both ends will block if there is no data to be read (ie the read() method on the InputStream will not return until data is read). If you are doing the read() in the SwingEventThread (ie 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();

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM