2016-05-25 5 views
0

У меня есть клиент Java TLS, который может отправлять на сервер серию запросов, за которыми следует ответ на сервер.Повторное использование сеанса Java TLS после закрытого подключения

Однако существует множество разных серверов. Некоторые из них - серверы с несколькими сообщениями, которые поддерживают соединение после первого запроса, так что последующие запросы могут быть отправлены по первому соединению. Другие - это серверы с одним сообщением, которые закрывают соединение после каждого сообщения, и поэтому для последующих сообщений требуется новое соединение. Для клиента не существует априорного способа узнать, к какому типу сервера он относится, и не исправлять серверы.

Очень желательно, чтобы одно сообщение служило для возобновления сеанса без полного рукопожатия.

Мой первоначальный клиентский код просто попытался отправить последующие запросы по тому же соединению. Если это не удалось, он просто открыл новое соединение с сервером. Таким образом, он может обрабатывать как серверы с одним, так и несколькими сообщениями.

Однако отказ при отправке второго сообщения в однопользовательские сообщения, похоже, убивает возобновление сеанса.

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

Но должен быть лучший способ. Тестирование на isInputShutdown или isConnected не помогает, что неудивительно, поскольку возникают проблемы с синхронизацией. Ошибка соединения для сервера с одним сообщением фактически происходит во время чтения ответа после записи запроса, предположительно из-за буферизации.

Любые идеи очень ценятся?

ответ

2

Ваше первоначальное решение верно в случае открытого текста: вы получите IOException: connection reset by peer при отправке второго сообщения, и вы можете просто восстановить его, повторно подключив.

Однако в случае TLS он не будет работать, так как вы не получите IOException: connection reset by peer, но SocketException, из-за фатальной TLS unexpected_message предупреждения. RFC 2246 #7.2 состояние:

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

[курсив мой], так как не удалось сессия теперь считается небезопасным, и

unexpected_message

было получено несоответствующий сообщение. Это предупреждение всегда фатальное и никогда не должно наблюдаться при общении между надлежащими реализациями .

Ваше второе решение кажется мне подходящим.

NB:

  • isInputShutdown() никогда не может быть правдой, так как вы не можете назвать shutdownInput() на SSLSocket.
  • isConnected() никогда не будет ложным после подключения сокета.
  • Оба говорят вам о состоянии вашего сокета, а не о соединении, поэтому даже попытки их были бесполезны. И это не имеет никакого отношения к «вопросам времени».
+0

Спасибо за сообщение. Я не вижу необходимости аннулировать сеансы, но так оно и есть. – Tuntable

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