gpt4 book ai didi

java - 获取 SelectedKeys 和切换操作时出现问题

转载 作者:行者123 更新时间:2023-12-01 15:23:23 26 4
gpt4 key购买 nike

我创建了这个异步客户端套接字,它连接到服务器并始终保持连接打开状态,并在与服务器断开连接时自动重新连接。

无论如何,我的问题是这样的:在初始化连接时,我将该操作注册为连接操作(SelectionKey.OP_Connect)。

现在,当我在选择器的选定键之间进行迭代时,我希望它输入控制语句 isconnectable 并更改控制语句中所示的操作。

不幸的是我没有得到任何选定的键。我哪里可能出错了?

        import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;



/*
* @author kewin
*/
public class clientEvent implements Runnable{
private static volatile boolean connected=false;
private SocketChannel channel;
private Selector selector;
private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
private QueueData Qdata;
private SelectionKey selectKey;



private void initiateConnection() {
try {
selector= Selector.open();//initializes the Selector Thread
channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress(InetAddress.getByName("127.0.0.1"),2000));
Thread.sleep(50);//Sleeps for a few Seconds to allow decent connection completion
channel.register(selector,SelectionKey.OP_CONNECT);//Registers the channel with the a selector and a selection key
if(channel.finishConnect())/*checks whether the connection is finished*/{
channel.register(selector,SelectionKey.OP_READ);//Registers the channel with the a selector and a selection key
connected=true;}
} catch(Exception ex){connected=false;}
}


private void ConnectAndMonitor(){
while(true){
try {
readBuffer.clear();
channel.read(readBuffer);
} catch (Exception ex) {
connected=false
try {
channel.close()
selector.close();
} catch (Exception e) {
}
if(!connected){
initiateConnection();
connected=true;
}
}
}
}


@Override
public void run() {
try{
new Thread(){@Override public void run(){ConnectAndMonitor()}}.start();

while(true){
if(!connected){
System.out.println("not connected");
Thread.sleep(500);
}
else{
selector.selectNow();
Set Keys=selector.keys();
Iterator iterator =Keys.iterator();
while(iterator.hasNext()){
SelectionKey key=(SelectionKey)iterator.next();

if(key.isConnectable()){
channel.register(selector,SelectionKey.OP_READ);
System.out.println("Connectable");
break;
}

if(key.isReadable()){
channel.register(selector,SelectionKey.OP_WRITE);
System.out.println("Readable");
break;
}

if(key.isWritable()){
channel.register(selector,SelectionKey.OP_CONNECT);
System.out.println("Writable");
break;
}
System.out.println("<<<<<<<<<>>>>>>>>>>>>");

}

Thread.sleep(1000);
}
}
}
catch(Exception ex){
}
}

public static void main(String[] args){
new Thread(new clientEvent()).start();
}
}

最佳答案

如果您在阻塞模式下进行连接,它将在方法调用期间阻塞并完成,因此如果您随后将其注册为 OP_CONNECT,isConnectable() 将永远不会为 true。

因此,如果您必须具有非阻塞连接,请注意您的代码已经做到了,首先将 channel 置于非阻塞模式,然后发出 connect(),注册 OP_CONNECT,然后当它触发时并且`finishConnect() 返回 true,取消注册 OP_CONNECT 并注册其他内容,或者因为您是客户端,所以更有可能开始发送请求。

编辑:您编辑的代码在以下方面不正确:

  1. 删除Thread.sleep()
  2. finishConnect() 调用移至 select 循环的 isConnected() 情况。
  3. OP_CONNECT/isConnectable() 触发时,取消注册 OP_CONNECT。
  4. 删除 if(!connected) 测试。

大部分内容我已经在上面说过了。目前,您 (a) 给连接时间来完成,(b) 完成它,(c) 在选择循环中等待它完成,(d) 永远不会取消注册 OP_CONNECT 即使您不再对此感兴趣,(e) 如果没有连接,则永远不会执行 select(),以及 (f) 尝试在 select() 循环中查找已完成的连接。这没有任何意义。

另一方面,如果您不介意在创建连接时等待连接完成内联,为什么要在非阻塞模式下进行呢?在阻塞模式下执行此操作,然后configureBlocking(false),然后注册OP_READ/OP_WRITE并忘记OP_CONNECTisConnectable()finishConnect() 总共。

关于java - 获取 SelectedKeys 和切换操作时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10532757/

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