2010-09-13 4 views
24

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

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

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

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

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

подсоединена: верно закрыто: верно оценка: истинно

Как это может быть связано и закрыт?

ТИА

+0

Вызов метода не является атомарным ... возможно, другой поток закрывает сокет между вызовами 'isConnected()' и 'isClosed()'? Возможно, сначала синхронизируется с объектом сокета? – Powerlord

+0

Это легко проверить, если вы просто изменили порядок проверок на 'isConnected()' и 'isClosed()'. –

ответ

66

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

Из приведенного выше резьбы:

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

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

Документы говорят:

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

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

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

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 

Я должен сказать, что документация на данный момент неясна и что имя метода немного бит isleading.

+11

+1 Браво! Отличный ответ! –

+2

Спасибо. Теперь это ясно для меня. – sproketboy

+0

Сломанная ссылка, но из цитат, по-видимому, она была снята с голосового болюса из ответов либо здесь, либо на форумах Sun/Oracle Java, многие из которых были мной. – EJP

Смежные вопросы