简体   繁体   English

注册注册写操作后无法读取java nio

[英]java nio cannot read after register a write operation

I got a problem when using Java nio to do networking. 使用Java nio进行网络连接时出现问题。

I start a server in a thread and register read operationsin the selector. 我在线程中启动服务器,并在选择器中注册读取操作。 and another thread connect to the server. 另一个线程连接到服务器。

  1. client write a byte to the server 客户端向服务器写入一个字节
  2. server reads the datas and back a byte to the client 服务器读取数据并将字节返回给客户端
  3. client get the response and write a byte to the server again. 客户端获得响应,然后再次向服务器写入一个字节。
  4. server loop step 2. 服务器循环步骤2。

but server cannot do the step 4 successfully because I can't get any read Key from selector any more. 但服务器无法成功执行第4步,因为我再也无法从选择器中获取任何读取密钥。 why ?? 为什么?? I have registered it before, and client has written data. 我已经注册过了,客户已经写了数据。

there is my code below : 下面是我的代码:

package test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;


public class JavaNIO {

    public static void main(String[] args) throws Exception {
        final Selector selector = Selector.open();
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        serverChannel.socket().bind(new InetSocketAddress(5555));
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        new Thread() {
            public void run() {
                while(true) {
                    try {
                        long count = selector.select();
                        if(count == 0) continue;
                        Iterator<SelectionKey> itKey = selector.selectedKeys().iterator();
                        while(itKey.hasNext()) {
                            SelectionKey key = itKey.next();
                            itKey.remove();
                            if(key.isAcceptable()) {
                                ServerSocketChannel channel = (ServerSocketChannel)key.channel();
                                SocketChannel socket = channel.accept();
                                socket.configureBlocking(false);
                                socket.register(selector, SelectionKey.OP_READ);

                            }
                            if(key.isReadable()) {
                                ByteBuffer buffer=  ByteBuffer.allocate(1);
                                SocketChannel channel = (SocketChannel)key.channel();
                                while(true) {
                                    buffer.flip();
                                    int len = channel.read(buffer);
                                    if(len == 0) break;
                                    buffer.clear();
                                }
                                channel.read(buffer);
                                channel.register(selector, SelectionKey.OP_WRITE, null);
                            }
                            if(key.isWritable()) {
                                SocketChannel channel = (SocketChannel) key.channel();
                                channel.write(ByteBuffer.wrap("ce".getBytes()));
                                key.cancel();
                            }
                        }
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread() {
            public void run() {
                try {
                    Socket socket = new Socket("localhost", 5555);
                    byte[] reads = new byte[1024];
                    for(int i = 0; i < 1000; i++) {
                        socket.getOutputStream().write(new byte[]{1});
                        socket.getInputStream().read(reads);
                        System.out.println(new String(reads));
                    }
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}

You re-registered the channel for OP_WRITE , so its interestOps ceased to include OP_READ . 您为OP_WRITE重新注册了频道,因此它的interestOps不再包括OP_READ If you want both, change accordingly. 如果两者都需要,请相应地进行更改。 'Or' them together. “或”他们在一起。

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

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