简体   繁体   English

如何测试非阻塞通道的 SocketChannel.read() 是否已完成?

[英]How can I test if a SocketChannel.read() for a non-blocking channel has finished?

I'm using a function to read bytes from non-blocking SocketChannel (socket from accept()) and from blocking SocketChannel (client side).我正在使用一个函数从非阻塞 SocketChannel(来自 accept() 的套接字)和阻塞 SocketChannel(客户端)读取字节。 I'm implementing a server using selector to handle multiple clients, and I'm using loopback address to use my laptop only.我正在使用选择器来实现一个服务器来处理多个客户端,并且我正在使用环回地址来仅使用我的笔记本电脑。 I wrote this我写了这个

while((r = socketChannel.read(ackBuf)) != -1) {
        System.out.println(name3d+" r: "+r);
    }

and I expected that when the end of the content in the channel was reached, read() would returned -1 but is not what succedes.并且我预计当到达频道中内容的末尾时, read() 将返回 -1 但不是成功的。 read(), in non-blocking configuration, return 0 also if nothing is ready to read at the moment but it will be soon (if I understand well) so if I change the code to read(),在非阻塞配置中,如果目前没有准备好读取,也返回 0 但很快(如果我理解得很好)所以如果我将代码更改为

while((r = socketChannel.read(ackBuf)) > 0) {
        System.out.println(name3d+" r: "+r);
    }

I will not read nothing also if something will be ready a moment later.如果稍后准备好某些东西,我也不会阅读任何内容。 How can I distinguish if I got 0 because is not ready or because it is ended?我如何区分我得到 0 是因为没有准备好还是因为它已经结束? In the following snippet I can test for a second time the read after a sleep but I'm sure is not the reliable way to do what I want.在下面的片段中,我可以在睡眠后再次测试读取,但我确定这不是做我想做的事情的可靠方法。

int times = 0;
while((r = socketChannel.read(ackBuf)) != -1 && times<2) {
    if (r == 0)
        try {
            Thread.sleep(500);
            times++;
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    System.out.println(name3d+" r: "+r);
}

" if I got 0 because is not ready or because it is ended?" “如果我得到 0 是因为没有准备好还是因为它已经结束?” Do you mean the message or the totality of the communication?你是指信息还是交流的全部内容?

For the message, you should use a communication protocol (like json or http) for the communication, I think you should get a SocketException... You would if you using blocking and the person on the other end closed the connection... (I've written to a lot of people on SO about how SocketException is your friend)对于消息,您应该使用通信协议(如 json 或 http)进行通信,我认为您应该得到一个 SocketException ......如果您使用阻塞并且另一端的人关闭了连接,您会......(我已经写信给很多人关于 SocketException 如何成为你的朋友)

--- edit --- - - 编辑 - -

Looking over the documention for Channel, it looks like you should get an IOException of some kind (SocketException is a subclass of IOException) if/when the channcel is closed查看 Channel 的文档,如果/当通道关闭时,您似乎应该得到某种类型的 IOException(SocketException 是 IOException 的子类)

The Non-blocking SocketChannel is used a bit different.非阻塞 SocketChannel 的使用有点不同。

  1. You first wait for the selection key to tell you that there is data, and您首先等待选择键告诉您有数据,然后
  2. then you read that data from the channel.然后你从通道中读取数据。

See this code draft:请参阅此代码草案:

  Selector selector = Selector.open();
  SocketChannel sc = SocketChannel.open();
  sc.configureBlocking(false);
  sc.connect(addr);
  sc.register(selector, SelectionKey.OP_READ);
  while (true) {
    // select() can block!
    if (selector.select() == 0) {
      continue;
    }
    Iterator iterator = selector.selectedKeys().iterator();
    while (iterator.hasNext()) {
     SelectionKey key = (SelectionKey) iterator.next();
     iterator.remove();
     if (key.isReadable()) {
       SocketChannel sc = (SocketChannel) key.channel();
       ByteBuffer bb = ByteBuffer.allocate(1024);
       sc.read(bb);
       System.out.println("Message received!");
     }
}

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

相关问题 SocketChannel.read()在非阻塞通道上阻塞 - SocketChannel.read() blocks on a non-blocking channel Java NIO:如何知道SocketChannel read()何时完成非阻塞I / O. - Java NIO: How to know when SocketChannel read() is complete with non-blocking I/O 非阻塞NIO SocketChannel导致IOException读取超时? - Non-Blocking NIO SocketChannel causes IOException timeout on read? 如何在非阻塞模式下通过SocketChannel读取和写入序列化对象? - How to read and write serialized object through SocketChannel in non-blocking mode? SocketChannel.read()无限期阻塞 - SocketChannel.read() blocks indefinitely NIO:如果缓冲区中没有可用数据,如何避免socketChannel.read(buffer) - NIO: How to avoid socketChannel.read(buffer) if no data available in buffer Java:用于查找是否已将写入非阻塞TCP SocketChannel的所有字节发送到接收方的API? - Java: API to find if all the bytes written to Non-Blocking TCP SocketChannel has been sent to receiver? 异步和同步模式下SocketChannel.read()的区别? - The difference of SocketChannel.read() in async and sync mode? 带有多线程的Java NIO SocketChannel.read() - Java NIO SocketChannel.read() with multithread 当socketChannel.read(BUFFER)将返回0时 - when socketChannel.read(BUFFER) will return 0
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM