java socket / output stream пишет: блокируют ли они?

Если я только ПИСЬМО для сокета в streamе вывода, будет ли он когда-либо блокироваться? Только чтение может блокироваться, не так ли? Кто-то сказал, что записи могут блокироваться, но я вижу только функцию таймаута для метода чтения сокета – Socket.setSoTimeout() .

Для меня не имеет смысла, что запись может блокироваться.

Запись на Socket также может блокироваться, особенно если это TCP Socket. ОС будет буферизовать только определенное количество неперехваченных (или переданных, но не подтвержденных) данных. Если вы пишете материал быстрее, чем удаленное приложение может его прочитать, сокет будет в конечном итоге резервным копированием и ваши write будут блокироваться.

Отвечая на следующие вопросы:

Так есть механизм, чтобы установить тайм-аут для этого? Я не уверен, какое поведение у него было бы … может быть, выбросить данные, если буферы заполнены? Или, возможно, удалить старые данные в буфере?

Механизм установки тайм-аута записи на java.net.Socket отсутствует. Существует метод Socket.setSoTimeout() , но он затрагивает вызовы accept() и read() … и не write() . По-видимому, вы можете получить таймауты записи, если используете NIO, неблокирующий режим и селектор, но это не так полезно, как вы могли себе представить.

Правильно реализованный стек TCP не отбрасывает буферные данные, если соединение не закрыто. Однако, когда вы получаете тайм-аут записи, неясно, были ли данные, которые в настоящее время находятся в буферах уровня OS, были получены другим концом … или нет. Другая проблема заключается в том, что вы не знаете, сколько данных из вашей последней write было фактически перенесено на буферы TCP стека уровня OS. Отсутствует какой-либо протокол уровня приложения для повторной синхронизации streamа * , единственная безопасная вещь, которую нужно сделать после таймаута при write – это закрыть соединение.

В отличие от этого, если вы используете сокет UDP, вызовы write() не будут блокироваться в течение какого-либо значительного промежутка времени. Но недостатком является то, что если есть проблемы с сетью или удаленное приложение не поддерживает, сообщения будут отбрасываться на пол без уведомления об этом. Кроме того, вы можете обнаружить, что сообщения иногда доставляются в удаленное приложение не по порядку. Это будет решать вам (разработчику) решение этих проблем.

* Теоретически это возможно, но для большинства приложений нет смысла реализовывать дополнительный механизм повторной синхронизации поверх уже надежного (точка) streamа TCP / IP. И если бы это имело смысл, вам также нужно было бы иметь дело с возможностью закрытия соединения … так что было бы проще предположить, что он закрыт.

Единственный способ сделать это – использовать NIO и селектора.

См. Запись у инженера Sun / Oracle в этом отчете об ошибке: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4031100

Давайте будем гением компьютера.