Запись на Socket также может блокироваться, особенно если это TCP-сокет. ОС будет буферизовать только определенное количество непереданных (или переданных, но неподтвержденных) данных. Если вы пишете вещи быстрее, чем удаленное приложение может их прочитать, сокет в конечном итоге создаст резервную копию, и ваши write
вызовы будут заблокированы.
Ответы на следующие вопросы:
Так есть ли механизм для установки
тайм-аут для этого? Я не уверен что
Поведение это было бы ... может быть, выбросить
данные, если буферы заполнены? Или возможно
удалить старые данные в буфере?
Нет механизма для установки таймаута записи на java.net.Socket. Существует метод Socket.setSoTimeout()
, но он влияет на вызовы accept()
и read()
... а не на вызовы write()
. Очевидно, вы можете получить тайм-ауты на запись, если используете NIO, неблокирующий режим и селектор, но это не так полезно, как вы можете себе представить.
Правильно реализованный стек TCP не удаляет буферизованные данные, если соединение не закрыто. Однако, когда вы получаете тайм-аут записи, неясно, были ли данные, которые в настоящее время находятся в буферах уровня ОС, получены другим концом ... или нет. Другая проблема заключается в том, что вы не знаете, сколько данных из вашего последнего write
было фактически передано в буферы стека TCP уровня ОС. В отсутствие какого-либо протокола прикладного уровня для повторной синхронизации потока * единственная безопасная вещь, которую нужно сделать после тайм-аута на write
, - это отключить соединение.
В отличие от этого, если вы используете сокет UDP, вызовы write()
не будут блокироваться в течение значительного промежутка времени. Но недостатком является то, что если есть проблемы с сетью или удаленное приложение не работает, сообщения будут сброшены на пол без уведомления ни с одной стороны. Кроме того, вы можете обнаружить, что сообщения иногда доставляются удаленному приложению не по порядку. Вы, разработчик), должны решить эти проблемы.
* Теоретически это возможно сделать, но для большинства приложений нет смысла реализовывать дополнительный механизм повторной синхронизации поверх уже надежного (до некоторой степени) потока TCP / IP. И если бы это имело смысл, вам также пришлось бы иметь дело с возможностью того, что соединение закрылось ... так что было бы проще предположить , что оно закрыто.