OP_CONNECT底层实现跟OP_WRITE是一回事,注册OP_CONNECT之后如果不unregister掉OP_CONNECT,select会立即返回0,然后你的程序回进入死循环拉满CPU
这个链接解释得比较清楚
https://stackoverflow.com/questions/9939989/java-nio-selector-select-returns-0-although-channels-are-ready
所以我们要在connect之后调用interestOps重新设置触发事件
channel.configureBlocking(false);
if (!channel.connect(...))
{
channel.register(sel, SelectionKey.OP_CONNECT, ...); // ... is the attachment, or absent
}
// else channel is connected, maybe register for OP_READ ...
// select() loop runs ...
// Process the ready keys ...
if (key.isConnectable())
{
if (channel.finishConnect())
{
key.interestOps(0); // or SelectionKey.OP_READ or OP_WRITE, whatever is appropriate
}
}
你很难在JAVA的文档里面找到相关解释,因为这是各个平台的自定义行为,或许在另一个OS里面OP_CONNECT的底层实现跟OP_WRITE不一样,那么就不会存在这个问题
网友评论