Как сокет может быть как подключен, так и закрыт? - PullRequest
27 голосов
/ 13 сентября 2010

Я использую Java-клиент для сокетов. В случае, когда сервер все еще подключен к моему клиенту, но не отправляет ответ на мое сообщение - я в конечном итоге получаю исключение тайм-аута чтения.

В этом случае я хочу проверить, нужно ли мне повторно подключать мой сокет или просто оставить его для повторного использования.

Я использую это условие:

if (!socket.isConnected() || socket.isClosed() || !socket.isBound()) {
    try {
        socket.close();
    } catch (IOException e1) {
    }
    // Wait on a new connection
    socket = connectSocket(.....);
}

Но я всегда, кажется, воссоединяюсь. Когда я регистрирую значения логических свойств, я вижу это:

подключено: верно закрыто: верно ограничено: верно

Как его можно подключить и закрыть?

ТИА

1 Ответ

71 голосов
/ 13 сентября 2010

В этой теме есть несколько полезных обсуждений на эту тему.Оказывается, что Socket.isConnected возвращает значение true, если оно (когда-либо) было успешно подключено.

Из вышеуказанного потока:

Когда вы используете Socket(), который вы, кажется, упустили, Socket.isConnected() говорит вам, был ли вызван Socket.connect() или нет.Аналогично для isClosed() и close().

Путаница с этими методами возникает из-за того, что состояние сокета , находящегося под управлением приложения, смешивается с состоянием общего соединение , которое находится под контролем протокола.isConnected() и isClosed() рассказывают, что вы сделали с сокетом.Нет никаких API, кроме чтения и записи, для определения состояния соединения.

В документах говорится:

Возвращает true, если сокет успешно подключен ксервер

и не так, как можно было бы ожидать " возвращает true, если сокет подключен к серверу ".

Поведение может бытьподтверждается, глядя на источник Socket:

public boolean isConnected() {
    // Before 1.3 Sockets were always connected during creation
    return connected || oldImpl;
}

Вы также можете запустить этот небольшой тестовый фрагмент:

Socket s = new Socket();

System.out.println("isConnected: " + s.isConnected() +
                  " isBound: "     + s.isBound() +
                  " isClosed: "    + s.isClosed());

s.connect(new InetSocketAddress("google.com", 80));

System.out.println("isConnected: " + s.isConnected() +
                   " isBound: "    + s.isBound() +
                   " isClosed: "   + s.isClosed());

s.close();

System.out.println("isConnected: " + s.isConnected() +
                   " isBound: "    + s.isBound() +
                   " isClosed: "   + s.isClosed());

Который печатает:

isConnected: false isBound: false isClosed: false
isConnected: true isBound: true isClosed: false
isConnected: true isBound: true isClosed: true

Я долженскажем, что документация по этому вопросу довольно неясна, и что имя метода немного вводит в заблуждение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...