检查OP_ACCEPT-ed选择键是否有等待连接打开

时间:2015-10-24 13:42:25

标签: java sockets nio

考虑到我使用选择器来处理用户连接:

初​​始化:

while (this.channel.isOpen()) {
    selector.select();
    for (SelectionKey key : this.selector.selectedKeys()) {
        if (key.isAcceptable()) this.acceptNewConnection(key);
        else if (key.isReadable()) this.readFromConnection(key); 
    }
}

主循环:

private void acceptNewConnection(SelectionKey key) throws IOException {
    final SocketChannel channel = SelectionKeyHelpers.getServerSocketChannel(key).accept();
    final String address = SocketHelpers.getConnectorAddres(channel.socket());

    channel.configureBlocking(false);
    channel.register(this.selector, SelectionKey.OP_READ, address);
}

接受连接:

OP_READ

Eveything工作得很好......接受第一个连接并添加新的选择键(使用selectedKeys())。

问题在于,当某些数据准备好读取时,OP_OPEN会返回带有两个选择键的集合:一个用于读取,另一个用isAcceptable,尽管没有连接访问(在这种情况下) null也返回true)。因此,从SelectionKey获取套接字(在acceptNewConncetion中)返回OP_OPEN

那么..当没有新的连接可用时,有没有办法从selectedKeys()中用null排除选择键?

检查套接字通道== final SocketChannel channel = SelectionKeyHelpers.getServerSocketChannel(key).accept(); if (channel == null) { // key is selected but there is nothing to accept return; } 是否足够或有更合适的方式? f.e:

var saveUsers = function (callback) {         
    var users = [{
            name: 'xyz',
            email: 'xyz@abc.com'

        }, {
            name: 'User New',
        }],
        savedUser = [];
    console.log('Saving Users --');
    __.map(users, function (record) {
        var recordType = new User(record);
        recordType.save(function (err, result) {
            if (err) console.log(err);
            if (!err) {
                console.log('Inserted user - ' + result.name);
                savedUser.push(result._id);
            }
        });
    });
    callback(savedUser);
};


saveUsers(function (savedUsers) {
    console.log(savedUsers);
    console.log('Saving Poets --');

    var poets = [{
        name: 'First Poet',
        userId: savedUsers[0]
    }, {
        name: 'Second Poet',
        userId: savedUsers[0]
    }, {
        name: 'Third Poet',
        userId: savedUsers[0]
    }];
    __.map(poets, function (record) {
        var recordType = new Poet(record);
        recordType.save(function (err, result) {
            if (err) console.log(err);
            if (!err) {
                console.log(result);
                console.log('Inserted poet - ' + result.name);
            }
        });
    });
});


var saveArtist = function(){
    console.log();
    console.log('Saving Artist --');

    var artists = [{
        name: 'First artist',
        userId: savedUsers[0]
    }, {
        name: 'Second artist',
        userId: savedUsers[0]
    }, {
        name: 'Third artist',
        userId: savedUsers[0]
    }];
    __.map(artists, function (record) {
        var recordType = new Artist(record);
        recordType.save(function (err, result) {
            if (err) console.log(err);
            if (!err) {
                console.log(result);
                console.log('Inserted artist - ' + result.name);
            }
        });
    });
}

1 个答案:

答案 0 :(得分:1)

  1. 没有OP_OPEN这样的东西。
  2. 这里的问题是代码中的错误。您需要从所选密钥集中删除每个已处理的密钥。选择器永远不会这样做。