简体   繁体   English

套接字接收数据时,Java套接字中是否有事件?

[英]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. 我编写了一个Swing Java程序,带有一个客户端和一个带有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. 为了实现这一点,我需要知道在C ++中是否存在诸如“ onClientRead”之类的事件,因为我还有其他一些按钮可以执行其他操作,因此无法将ReadLine()方法放在所有这些按钮中。 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. 我知道我可以在java.nio中使用套接字,但是如果java.io的套接字中有东西,那就更好了。 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). 如果没有要读取的数据,则从两端的Socket返回的InputStream都将阻塞(即,InputStream上的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. 如果您正在SwingEventThread中执行read()(即,当用户单击按钮时),则您的UI将显示为锁定。 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. 如果有可供读取的字节,InputStream上的available()方法将返回大于0的数字,因此您可以使用它。
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. 但是,听起来您应该编写GUI外部存在的一些其他代码,这些代码将从InputStream读取,并在读取数据时触发其自己的事件。 Your GUI can then listen for that event. 然后,您的GUI可以侦听该事件。 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. 此类是“ Runnable”的类,因为InputStream的读取方法会阻塞,因此需要在其他线程中运行。 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): 可以使用带有read的单独Thread(这是一种阻塞方法)来完成:

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. 这是一种“测试方法”,请尝试为此线程创建一个单独的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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