簡體   English   中英

注冊注冊寫操作后無法讀取java nio

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

使用Java nio進行網絡連接時出現問題。

我在線程中啟動服務器,並在選擇器中注冊讀取操作。 另一個線程連接到服務器。

  1. 客戶端向服務器寫入一個字節
  2. 服務器讀取數據並將字節返回給客戶端
  3. 客戶端獲得響應,然后再次向服務器寫入一個字節。
  4. 服務器循環步驟2。

但服務器無法成功執行第4步,因為我再也無法從選擇器中獲取任何讀取密鑰。 為什么?? 我已經注冊過了,客戶已經寫了數據。

下面是我的代碼:

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();
    }
}

您為OP_WRITE重新注冊了頻道,因此它的interestOps不再包括OP_READ 如果兩者都需要,請相應地進行更改。 “或”他們在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM