使用ServerSocketChannel设置阻塞I / O操作的超时不能按预期工作

时间:2013-06-16 13:01:58

标签: java socketchannel

我正在使用Java编写一个小型群组会话服务器,我目前正在攻击网络代码,但似乎我无法在阻止I / O操作时设置正确的超时:我有可能被一些Java咬了奇怪(或简单地说,我误解了javadoc)。

因此,这是来自ConversationServer类的相关代码(为简单起见,所有安全检查和日志记录都被删除):

class ConversationServer {

    // ...

    public int setup() throws IOException {
        ServerSocketChannel server = ServerSocketChannel.open();
        server.bind(new InetSocketAddress(port), Settings.MAX_NUMBER_OF_PLAYERS + 1);

        server.socket().setSoTimeout((int) Settings.AWAIT_PLAYERS_MS);

        int numberOfPlayers;

        for (numberOfPlayers = 0; numberOfPlayers < Settings.MAX_NUMBER_OF_PLAYERS; ++numberOfPlayers) {
            SocketChannel clientSocket;

            try {
                clientSocket = server.accept();
            } catch (SocketTimeoutException timeout) {
                break;
            }

            clients.add(messageStreamFactory.create(clientSocket));
        }

        return numberOfPlayers;
    }

    // ...

}

预期的行为是最多连接Settings.MAX_NUMBER_OF_PLAYERS个客户端,或者在Settings.AWAIT_PLAYER_MS毫秒(目前为30000L)之后终止设置。

如果我连接Settings.MAX_NUMBER_OF_PLAYERS个客户端,那么一切都很好(因for条件而退出),但如果我不这样做,那么SocketTimeoutException我期待server.socket().setSoTimeout((int) Settings.AWAIT_PLAYERS_MS);从不抛出,服务器永远挂起。

如果我理解正确,{{1}}应该足够了,但它没有给出预期的行为。

那么,有人能在这里发现错误吗?

1 个答案:

答案 0 :(得分:3)

如果从

更改,看起来超时有效
server.socket().setSoTimeout((int) Settings.AWAIT_PLAYERS_MS);
server.accept();

server.socket().setSoTimeout((int) Settings.AWAIT_PLAYERS_MS);
server.socket().accept();

即。在您设置SO超时的同一对象上调用accept()。我对NIO套接字知之甚少,无法准确说出这样做的结果。也许别人可以解释一下。