简体   繁体   English

如何在Java(TelNet)中实现接收套接字的事件?

[英]How to implement an event for receiving a socket in Java (TelNet)?

I'm doing an application in NetBeans (Java) to open a socket (Client) and exchange information with it. 我正在使用NetBeans(Java)中的应用程序来打开套接字(客户端)并与其交换信息。

The way I'm doing this is as follows: 我这样做的方式如下:

final String HOST = "10.1.1.98";//"localhost";

final int PORT=1236;

Socket sc;

DataOutputStream message;

public void initClient()
{
    try
{
        sc = new Socket( HOST , PORT );
        message = new DataOutputStream(sc.getOutputStream());

    }
    catch(Exception e )
    {
        System.out.println("Error: "+e.getMessage());
    }
}

I must know if the server sends information constantly. 我必须知道服务器是否不断发送信息。 One way would be to use a timer that constantly run the following piece of code: 一种方法是使用计时器,该计时器不断运行以下代码:

message = new DataOutputStream(sc.getOutputStream());

But it isn't efficient. 但这不是有效的。

I want to create an event to be in charge of acquiring data from the server, for example in C# I used EventHandler: 我想创建一个事件来负责从服务器获取数据,例如在C#中,我使用了EventHandler:

ip = new TcpIp(ipAddress, port);

ip.DataRead += new EventHandler<TramaEventArgs>(ip_DataRead);

....

void ip_DataRead(object sender, TramaEventArgs e) 
{

}

How I can do this in Java? 如何用Java做到这一点?

The 'correct' way to do non-blocking IO in Java is to use the NIO API, look in particular at java.nio.channels.AsynchronousSocketChannel that allows you to write code like this: 在Java中执行非阻塞IO的“正确”方法是使用NIO API,尤其要看一下java.nio.channels.AsynchronousSocketChannel ,它允许您编写如下代码:

InetSocketAddress serverAddress = new InetSocketAddress(InetAddress.getByName("10.1.1.98"), 1236);

AsynchronousSocketChannel clientSocketChannel = AsynchronousSocketChannel.open();
clientSocketChannel.connect(hostAddress).get();

ByteBuffer buffer = getBuffer();
clientSocketChannel.read(buffer, Void, new ReadHandler(buffer));

Where the handler looks like this: 处理程序如下所示:

public class ReadHandler implements CompletionHandler<Integer, Void>
{
  private ByteBuffer buffer;

  public ReadHandler(ByteBuffer buffer)
  {
    this.buffer = buffer;
  }

  public void completed(Integer read, Void attachment) 
  {
    if (read < 0)
    {
      return;
    }

    //TODO: read buffer according to the number of bytes read and process accordingly.
  }

  public void failed(Throwable exc, Void attachment)  
  {
    //TODO: handle exception.
  }
}

The important things to note here are: 这里要注意的重要事项是:

  • it's possible you'll be reading incomplete messages and so you need to handle that. 您可能正在阅读不完整的消息,因此您需要进行处理。
  • you should do as little processing as possible in the ReadHandler , instead passing each complete message off (maybe to an ExecutorService or some internal queue depending on your requirements). 您应该在ReadHandler进行尽可能少的处理,而不是传递每个完整的消息(取决于您的要求,可能传递给ExecutorService或一些内部队列)。

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

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