3

私は 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_MS30000L

何が起こるかというと、Settings.MAX_NUMBER_OF_PLAYERSクライアントを接続するとすべて問題forありませんが (条件により終了します)、そうしないと、SocketTimeoutException期待どおりにスローされず、サーバーが永久にハングします。

私が正しく理解していればserver.socket().setSoTimeout((int) Settings.AWAIT_PLAYERS_MS);、十分なはずですが、期待どおりの動作が得られません。

それで、誰でもここでエラーを見つけることができますか?

4

1 に答える 1

3

から変更するとタイムアウトが機能するようです

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

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

accept()つまり、SO タイムアウトを設定した同じオブジェクトを呼び出します。これを行った結果がどうなるかを正確に言うには、NIO ソケットについて十分に知りません。たぶん、他の誰かが光を当てることができます。

于 2013-06-16T13:49:00.550 に答える