gpt4 book ai didi

java - SelectionKey 不可写

转载 作者:行者123 更新时间:2023-11-30 06:14:39 25 4
gpt4 key购买 nike

我很好奇为什么代码总是告诉我“ key 不可写”?我的代码有什么问题吗?每次套接字读到一些内容时,我都会将键设置为对 OP_WRITE 感兴趣,并测试它是否可写。但是总是说不可写。我完全是Java套接字编程的新手。

顺便说一句,我没有关闭客户端。

public final class DateServer {

private DateServer() {
throw new IllegalStateException("Instantiation not allowed");
}

public static void main(final String[] args) throws Exception {
try (final Selector selector = Selector.open(); ServerSocketChannel serverSocket = ServerSocketChannel.open();) {
InetSocketAddress hostAddress = new InetSocketAddress("127.0.0.1", 9999);
serverSocket.bind(hostAddress);

serverSocket.configureBlocking(false);
serverSocket.register(selector, serverSocket.validOps(), null);

while (true) {
int numSelectedKeys = selector.select();
if (numSelectedKeys > 0) {
handleSelectionKeys(selector.selectedKeys(), serverSocket);
}
}
}
}

private static void handleSelectionKeys(Set<SelectionKey> selectionKeys, ServerSocketChannel serverSocket) throws IOException {

Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();
while (selectionKeyIterator.hasNext()) {
SelectionKey key = selectionKeyIterator.next();

if (key.isAcceptable()) {
acceptClientSocket(key, serverSocket);
} else if (key.isReadable()) {
readRequest(key);
}

selectionKeyIterator.remove();
}
}

private static void acceptClientSocket(SelectionKey key, ServerSocketChannel serverSocket) throws IOException {

SocketChannel client = serverSocket.accept();
client.configureBlocking(false);
client.register(key.selector(), SelectionKey.OP_READ);

System.out.println("Accepted connection from client");
}

private static void readRequest(SelectionKey key) throws IOException {

SocketChannel client = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);

int bytesRead = client.read(buffer);

if (bytesRead == -1) {
client.close();
} else {
System.out.println(String.format("Request data: %s", new String(buffer.array())));
int interestOps = 0;
interestOps |= SelectionKey.OP_WRITE;
key.interestOps(interestOps);

if (key.isWritable()){
System.out.println("key is writable");
} else {
System.out.println("key is not writable");
}

interestOps = 0;
interestOps |= SelectionKey.OP_READ;
key.interestOps(interestOps);
}

}
}

最佳答案

interestOps 仅告诉选择器下次选择什么。设置 OP_WRITE 并不会神奇地使选择键具有预测 future 的能力。您必须再次调用 select() 才能使 OP_WRITE 真正根据此代码进行设置。

但是您不需要选择器的“权限”即可写入 channel 。您只需写入,只有当写入计数为零时,您才需要担心 OP_WRITE,正如此处有关该主题的众多答案。

关于java - SelectionKey 不可写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49492279/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com