|
|
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Андрей Панфилов, по факту сишная реализация сокета все что нужно для реализации хотелок у себя имеет: http://stefan.buettcher.org/cs/conn_closed.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:03:37 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Blazkowiczschwa-1 вернется только в случае, если другая сторона закрыла соединение пока мы висели на read (и все оповещения об этом успешно дошли). Ок. А может мне кто на пальцах объяснить что такое Connection reset и как на это принято реагировать в TCP? Другая сторона нам отправила RST в ответ на нашу операцию записи. Т.е. посчитали что наше соединение не существует - оно могло быть закрыто несколько секунд назад, процесс могли просто убить или уже вообще узел за это время успел рибутнуться и он вообще ничего не знает об этом соединении. А что в этом случае делать это уже зависит от приложения - либо открывать новое соединение и как-то продолжить работу, либо игра окончена. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:05:28 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Blazkowicz, Не очень понятно для чего вызываются проверки isInput[Output]Shutdown() в примере? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:18:41 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
DoSOfRedRiverСразу оговорюсь, что могу в чём-то ошибаться. Ключевые моменты лучше проверить. В любом случае спасибо за коментарий. DoSOfRedRiverДействительно, available возвращает количество байт, доступных для чтения. То-есть, если данные на вашу машину ещё не пришли, либо пришли не полностью, то available() вернёт 0. Не понимаю зачем повторять то что я написал. Я это просто к тому что такое поведение нарушает контракт описаный в JavaDoc. Без каких либо видимых причин. DoSOfRedRiverА какой, собсна, read() вы используете? Из кода что я привел выше, это очевидно. DoSOfRedRiverУ меня всё нормально работало, для read() . У меня реализация должна быть независима от протокола. С протолом HTTP всё нормально работает. С другим кастомным - нет. DoSOfRedRiverСоветую вам использовать более удобное и эффективное чтение в массив read(byte [] arg), которое возвращает количество считанных байт. Ваш КО. DoSOfRedRiverИ да, авториспользовать available для хоть какой-то эмуляции неблокируемости тоже не выйдет Вышло по примеру Андрея Панфилова. Но осталась проблема с идентификацией завершения сессии. DoSOfRedRiverПо поводу Connetion reset вот что пишут. Сдаётся мне, проблемы конкретно у вас. Полезный коментарий. DoSOfRedRiverДумается, вытекает из третьего. Всё должно нормально работать. Мало ли что кому должно. Я описываю что конкретно и как работает на примере произвольного протокола поверх TCP. На HTTP работает. Там пакеты достаточно четко разделены. DoSOfRedRiverИзбегайте логгирования в местах, где ошибки предсказуемы и некритичны. Это из чего следует? DoSOfRedRiverМожете глянуть на то, как обрабатываются ошибки в Netty, там даже лисенеры специальные есть. Netty я потом посмотрю. Пока только хардкор. Только велосипеды. DoSOfRedRiverСелекторы достаточно эффективная и удобная вещь, почему вы их избегаете? Потому что я хочу получить подтверждение или опровержение того на сколько блокирующие сокеты в Java "сломаны". DoSOfRedRiverВообще, классический IO давно устарел, он неудобен и непрактичен, потому писать лучше сразу с использованием NIO\NIO.2 В теории я знаю очень много и про IO и про NIO и про множество других страшных слов в Java мире. На практике всплывают нюансы. В NIO.2 что хорошего появилось для сокетов чтобы реализовать желаемый TCP прокси? DoSOfRedRiverПриведу здесь пример. Как по мне, в нём отражена вся суть работы IO, кроме, разве что, многопоточного взаимодействия. Хрен там что отражено из моих вопросов выше. На конкретном протоколе у меня проблем нет. У меня проблемы на абстракции, которая должна работать на любых протоколах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:26:53 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
schwaДругая сторона нам отправила RST в ответ на нашу операцию записи. У меня на чтение. Это и оказалось большим сюрпризом. schwaТ.е. посчитали что наше соединение не существует - оно могло быть закрыто несколько секунд назад, процесс могли просто убить или уже вообще узел за это время успел рибутнуться и он вообще ничего не знает об этом соединении. Процесс открыт. Сокет открыт. Никто не бутается - все на месте. schwaА что в этом случае делать это уже зависит от приложения - либо открывать новое соединение и как-то продолжить работу, либо игра окончена. Это уже будет привязка к протоколу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:29:14 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
schwaНе очень понятно для чего вызываются проверки isInput[Output]Shutdown() в примере? Та, просто осталось. Я там вообще все флаги блокирующего сокета перебрал. Ни один из них не меняет состояния ни до, ни после Connection Reset исключения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:30:56 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Андрей ПанфиловsendUrgentData данные не передает а шлет флаг, правда минут что поведение зависит от ОС. Спасибо. Попробую. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:31:19 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Переписал NIO на 1 поток вместо 2х, по аналогии с этим кодом 14920507 . Всё нахрен сломалось, теперь и NIO вариант без селектора не работает :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:34:21 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
DoSOfRedRiverПо поводу NIO: Селекторы достаточно эффективная и удобная вещь, почему вы их избегаете? Вообще, классический IO давно устарел, он неудобен и непрактичен, потому писать лучше сразу с использованием NIO\NIO.2Я бы не был так категоричен. Ничего не устарело, и не устареет. Это просто два разных подхода, которые в определенных местах пересекаются, а в определенных местах нет, тем самым дополняя друг друга. NIO с селекторами удобен, если нужен неблокирующий режим (как у автора), или если нужно обслуживать очень много соединений, когда подход "одно соединение - один поток" не справляется. Платой за использование NIO является бОльшая сложность его использования. Хотя в случае автора, когда нужно прост опрокидывать данные из одного сокета в другой, эта "добавленная сложность" будет не сильно выше, ибо не надо запариваться с размерами сообщений и выискивать их границы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 22:59:59 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Получилось на блокирующем NIO (SocketChannel.configureBlocking(true)) вот в таком виде. ВНИМАНИЕ. КОД НЕ РЕКОМЕДУЕТСЯ К ИСПОЛЬЗОВАНИЮ. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. Дополнительные Thread.sleep() не нужны. Так как чтение блокирующее лишних циклов не возникает. Правда меня это теперь немного озадачивает. Ведь pump в одну сторону может заблокироваться и следующий уже не будет вызван. Почему вообще работает не понятно. Может один из сокетов таки сделать неблокирующим на всякий случай? В любом случае потом перепишу на selector. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 23:41:40 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
И ещё один косяк, что выход из цикла осуществляется по исключению. Этого забороть не удалось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2013, 23:43:56 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
cdtyjv, Я даже не могу придумать ни одного примера, в котором использование классического IO дало бы мне преимущество перед NIO. авторНичего не устарело, и не устареет. Точно так же можно сравнивать AWT и JavaFX. Я не хочу сказать, что эти технологии мертвы, и не нужны никому. Просто придумали уже вещи удобней и красивей. Blazkowicz, авторВышло по примеру Андрея Панфилова. Дак в примере выходит по соединению на поток, не? Тогда вообще не понимаю, какие могут быть проблемы. авторНо осталась проблема с идентификацией завершения сессии. По-моему самым эффективным способ будет посылать heartbeat, который проверяет жив ли клиент. Да и других вариантов не могу найти, потому как клиент может просто шутдаунуться. авторПотому что я хочу получить подтверждение или опровержение того на сколько блокирующие сокеты в Java "сломаны". Сломаны? Как они могут быть "сломаны"? Вроде куча народу юзает блокинг-ио, никто не жаловался особо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 00:14:41 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
DoSOfRedRiverДак в примере выходит по соединению на поток, не? Тогда вообще не понимаю, какие могут быть проблемы.Два блокирующих сокета на поток. Потому у автора и проблемы. DoSOfRedRiverПо-моему самым эффективным способ будет посылать heartbeat, который проверяет жив ли клиент. Да и других вариантов не могу найти, потому как клиент может просто шутдаунуться.Так и есть. Состояние, когда клиент подох, а сервер этого не увидел (или наоборот) - называется half-open socket. И хартбиты позволяют успешно детектировать эту ситуацию. Но автору нужно сделать прокси, вклиниться между клиентом и сервером, и просто форвардить данные из одной стороны в другую. Так что хартбиты тут не помогут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 08:17:40 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Blazkowiczметод InputStream.available() бесполезен и даже сломан для сокетов. Он всегда был бесполезен для клиентского кода. Из разумных его применений я вижу только его использование в различных Buffered* обертках. Там обертка может увидеть, что данных много, и реалоцировать буфер. BlazkowiczЧитаем JavaDoc Returns:an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking or 0 when it reaches the end of the input stream. На сокетах available будет изначально возвращать 0, если узел с другой стороны ничего не отправляет. Но это ещё не значит что поток завершен. Вы javadoc неправильно понимаете. Javadoc и не обещает, что 0 - это только конец потока. У вас возвращается "number of bytes that can be read without blocking". Ну нет там байтов, чтобы читать. И ноль - вполне корректное значение для первой половины (даже когда конец потока еще не достигнут). Причем "0 в случае конце файла" - это всего лишь уточнение. Оно вполне следует из первой половины контракта. По той же самой причине - "из потока можно прочитать не более 0 байт без блокирования". Разница с read есть, но для данного места оно вполне оправдана. Файловые потоки тоже могут возвращать 0 раньше достижения конца файла. BlazkowiczWTF#2 Дальше хуже. read(), который должен вернуть -1 по окончании чтения тоже никогда -1 не возвращает. В общем случае никакого начала и конца у InputStream для сокетов нет. А использовать available для хоть какой-то эмуляции неблокируемости тоже не выйдет. Начало есть. Если сделать Socket.shutdownOutput на стороне клиента, то у сервера и конец потока будет. А если не делать, то и конца не будет. Что логично - по одному соединению можно обмениваться многими соединениями. И даже тот же браузер может не закрывать сокет (поэтому -1 и не будет), а использовать его для послдеюущих запросов. BlazkowiczНачал тестировать на боевом приложении, WTF#3 Клиент отправляет пакет данных. Он прочитан, перенаправлен на другой сервер. После этого мой серверный сокет снова пытается сделать read(). В теории он должен либо заблокироваться, либо вернуть -1. На практике чтение выкидывает исключение Connection reset! Но это пол беды. Помимо этого клиентская сторона закрывает свой сокет и на запись. Т.е. отклик сервера записать проигнорировав reset уже нельзя. Код смотреть надо. Вы там никакой из сокетных потоков или оберток над ними вручную не закрываете? Закрытие любого из них будет приводить к закрытию сокета. Или на сервере вместо shutdown сокету делается close. Для надежной доставки данных нельзя "просто закрыть потоки и сокет". Сначала нужно сделать shutdown (один или два, в зависимости от того, что делаете). И только потом закрывать сокет. В случае исключений shutdown делать уже не имеет смысла. BlazkowiczWTF#4 - не смотря на connection reset и невозможность дальнейшей работы с клиентом со стороны сервера, никакие флаги у сокета не меняются. Всякие connected, closed и пр. находятся в том же состоянии что и в начале работы. Т.е. спросит клиента с сервера живо ли тот ещё никакой возможности не видно. Это плохая документация. "isConnected" вооще обозначает, что "соединение хоть когда-то было установлено (смотрите документацию)", а не "сейчас соединение установлено". При использовании большей части конструкторов isConnected всегда будет true. С isClosed ситуация чем-то похожая. Этот флаг всего лишь обозначает, что "сокет был закрыт вызовом метода close или закрытием одного из сокетных потоков". Он не обозначает, что клиент на другой стороне закрыл соединение и т.п. Да, завершение соединения с другой стороны/ошибки/сброс соединения сокет не закрывают. Его все равно нужно закрыть вручную. BlazkowiczWTF#5 - я вообще смотрю на разные проекты и вижу что постоянные исключения в TCP на Java это вообще штатные ситуации. Имеет ли смысл избегать логирования stacktrace для повышения производительности? Ведь если разворачивать stacktrace на каждый пук при многочисленых соединениях и отсоединениях клиентов, то провал в производительности обеспечен. Да, достаточно штатная. Логировать ли - зависит от приложения и нагрузки. Во многих случаях протокол имеет явные начало/конец (с соответствующими shutdown и т.п.), поэтому исключения при допустимой нагрузке логировать стоит (мало ли что там). А вот если вы какой-нибудь streaming server пишете, где клиент в какой-то момент просто исчезает (приложение закрыли), там можно и не логировать ничего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 10:11:40 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
BlazkowiczschwaДругая сторона нам отправила RST в ответ на нашу операцию записи. У меня на чтение. Это и оказалось большим сюрпризом. schwaТ.е. посчитали что наше соединение не существует - оно могло быть закрыто несколько секунд назад, процесс могли просто убить или уже вообще узел за это время успел рибутнуться и он вообще ничего не знает об этом соединении. Процесс открыт. Сокет открыт. Никто не бутается - все на месте. Операция записи завершается, когда переданные данные были скопированы в буфер отправки. На следующей операции записи/чтения будет получен connection reset, если за это время произошел обрыв соединения и эта сторона соединения об этом узнала. Без закрытия соединения на другой стороне RST получить никак нельзя. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 10:14:54 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
В спойлере пример. Проверял на www.apache.org порт 80. Никаких исключений. Никаких проблем с сокетами. Радостно общается с браузером потоков в 10 и при этом с HTTP keep-alive (видно по логам и сообщениям о закрытии сокетов). Соединения могут закрываться и при неактивности (т.е. конец файла определяется с обеих сторон), тоже видно по сообщениям. Если делать совсем правильно, читалку и писалку тоже нужно разделить на два потока (на три потока, в примере две записи). Читалка складывает данные в буфер. Если данных в буфере слишком много, закрывает сокет со второй стороны и свой сокет (генерируя попутно кучу исключений в духе SocketClosedException, ConnectionReset и т.п.). Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 10:42:52 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
DoSOfRedRiverЯ даже не могу придумать ни одного примера, в котором использование классического IO дало бы мне преимущество перед NIO. Google -> IO faster than NIO. DoSOfRedRiverТочно так же можно сравнивать AWT и JavaFX. Я не хочу сказать, что эти технологии мертвы, и не нужны никому. Просто придумали уже вещи удобней и красивей. Аналогия не уместна. DoSOfRedRiverДак в примере выходит по соединению на поток, не? Тогда вообще не понимаю, какие могут быть проблемы. Проблемы я объяснил в первом посте и по вашей просьбе привел текст кода, который эти проблемы вскрывает. DoSOfRedRiverПо-моему самым эффективным способ будет посылать heartbeat, который проверяет жив ли клиент. Да и других вариантов не могу найти, потому как клиент может просто шутдаунуться. Конкретику, пожалуйста. sendUrgentData() или какой ещё heartbeat? DoSOfRedRiverСломаны? Как они могут быть "сломаны"? Вроде куча народу юзает блокинг-ио, никто не жаловался особо. IO работает когда протокол заранее оговорен. У меня нет протокола. Мне нужно прокачивать любые данные любых протоколов поверх TCP. Конечно, если протокол защищен он атаки man-in-the-middle, то работать никакой вариант не будет. Но на IO у меня не получается даже обычный протокол прокачать без защиты. Почему? - описал в первом посте и привел код. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 11:05:30 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
cdtyjvДва блокирующих сокета на поток. Потому у автора и проблемы. У меня и по сокету на поток проблемы и два сокета на поток тоже проблемы. cdtyjvТак и есть. Состояние, когда клиент подох, а сервер этого не увидел (или наоборот) - называется half-open socket. И хартбиты позволяют успешно детектировать эту ситуацию. Но автору нужно сделать прокси, вклиниться между клиентом и сервером, и просто форвардить данные из одной стороны в другую. Так что хартбиты тут не помогут. А на sendUrgentData()? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 11:07:10 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
BlazkowiczУ меня и по сокету на поток проблемы и два сокета на поток тоже проблемы.А вы код "сокет-на-поток" выкладывали? А то я уже запутался, где что. BlazkowiczА на sendUrgentData()?В общем случае sendUrgentData() не работает. Что бы спокойно ее использовать, необходимо быть уверенным, что принимающая сторона знает, как с этой самой urgent data быть. В противном случае вы по сути будете отсылать на другую стороны какие-то левые байты, который запорят протокол, и приведут к непредсказуемым последствиям. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 11:12:03 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
maxkarВы javadoc неправильно понимаете. Javadoc и не обещает, что 0 - это только конец потока. У вас возвращается "number of bytes that can be read without blocking". Ну нет там байтов, чтобы читать. И ноль - вполне корректное значение для первой половины (даже когда конец потока еще не достигнут). Причем "0 в случае конце файла" - это всего лишь уточнение. Оно вполне следует из первой половины контракта. По той же самой причине - "из потока можно прочитать не более 0 байт без блокирования". Разница с read есть, но для данного места оно вполне оправдана. Файловые потоки тоже могут возвращать 0 раньше достижения конца файла. Спасибо! Теперь понял основную ошибку. maxkarНачало есть. Если сделать Socket.shutdownOutput на стороне клиента, то у сервера и конец потока будет. А если не делать, то и конца не будет. Что логично - по одному соединению можно обмениваться многими соединениями. И даже тот же браузер может не закрывать сокет (поэтому -1 и не будет), а использовать его для послдеюущих запросов. У меня 3rd party клиент. Он шлет reset вместо всего остального. maxkarКод смотреть надо. 14920906 maxkarВы там никакой из сокетных потоков или оберток над ними вручную не закрываете? Закрытие любого из них будет приводить к закрытию сокета. Или на сервере вместо shutdown сокету делается close. Для надежной доставки данных нельзя "просто закрыть потоки и сокет". Сначала нужно сделать shutdown (один или два, в зависимости от того, что делаете). И только потом закрывать сокет. В случае исключений shutdown делать уже не имеет смысла. Проблема ни в shutdown/close. Проблема в том что когда сервер делает read с клиентского сокета, вылетает Connection Reset и предотвратить это можно только через available(). maxkarЭто плохая документация. "isConnected" вооще обозначает, что "соединение хоть когда-то было установлено (смотрите документацию)", а не "сейчас соединение установлено". При использовании большей части конструкторов isConnected всегда будет true. С isClosed ситуация чем-то похожая. Этот флаг всего лишь обозначает, что "сокет был закрыт вызовом метода close или закрытием одного из сокетных потоков". Он не обозначает, что клиент на другой стороне закрыл соединение и т.п. Да, завершение соединения с другой стороны/ошибки/сброс соединения сокет не закрывают. Его все равно нужно закрыть вручную. Клиент послал Reset и у клиентского сокета на сервере никакие флаги вообще не поменялись. Это и смущает. maxkarДа, достаточно штатная. Логировать ли - зависит от приложения и нагрузки. Во многих случаях протокол имеет явные начало/конец (с соответствующими shutdown и т.п.), поэтому исключения при допустимой нагрузке логировать стоит (мало ли что там). А вот если вы какой-нибудь streaming server пишете, где клиент в какой-то момент просто исчезает (приложение закрыли), там можно и не логировать ничего. Мне нужно решение не привязаное к конкретным протоколам. Если я использую available(), то я не могу выйти из цикла. И клиентский и серверный сокет живут себе даже после окончания сессии обмена данными. Если я не использую available(), то я выхватываю исключение на методе read() и дальнейшая работа с этим сокетом не возможна. Может надо было ещё и со стороны сервера reset() вызвать чтобы обновить сокет? Не очевидно как-то. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 11:13:38 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
schwaОперация записи завершается, когда переданные данные были скопированы в буфер отправки. На следующей операции записи/чтения будет получен connection reset, если за это время произошел обрыв соединения и эта сторона соединения об этом узнала. Вот такой вот хитрый протокол попался. Если делать read больше нужного - отгребаешь RST. Если предотвратить RST через available(), то не происходит выхода из цикла. Ещё удивительно то что абсолютно аналогичный код на NIO API отрабатыват. Там нет available, но там и лишний read не приводит к RST. schwaБез закрытия соединения на другой стороне RST получить никак нельзя. Спасибо. Не знал. А почему бы просто не закрыть клиенту соединение тогда? Или это такой способ для одной стороны сообщить другой, что она планово закрылась? Помогите понять суть RST. Ткните носом в нужный мануал, что ли. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 11:17:51 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
maxkarВ спойлере пример. Проверял на www.apache.org порт 80. Никаких исключений. Никаких проблем с сокетами. Радостно общается с браузером потоков в 10 и при этом с HTTP keep-alive (видно по логам и сообщениям о закрытии сокетов). Соединения могут закрываться и при неактивности (т.е. конец файла определяется с обеих сторон), тоже видно по сообщениям. На HTTP у меня тоже всё работало без проблем. На другом TCP протоколе метод read из вашего примера выкинет Exception до окончания сессии обмена данными. При этом сокет ещё и закрывается, так что в него нельзя записать отклик. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 11:22:27 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
cdtyjvА вы код "сокет-на-поток" выкладывали? А то я уже запутался, где что. Вот мой первоначальный код. 14920906 Запускается два потока. Один работает с клиентским сокетом. Второй с серверным. (третий сидит на ServerSocket.accept(), но это не важно) cdtyjvА на sendUrgentData()?В общем случае sendUrgentData() не работает. Что бы спокойно ее использовать, необходимо быть уверенным, что принимающая сторона знает, как с этой самой urgent data быть. В противном случае вы по сути будете отсылать на другую стороны какие-то левые байты, который запорят протокол, и приведут к непредсказуемым последствиям.[/quot] Понял. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 11:25:31 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Всем большое спасибо за обсуждение. Возник ещё вопрос по NIO. Вот в этом примере 14921347 , по логике один из двух pump может заблокироваться, так как данные в эту сторону уже не идут. И второй pump не вызовется. Ведь поток заблокирован. Но на практике этого не происходит. Кто-нибудь может объяснить почему? Или мне просто повезло с протоколом? Вечером залогирую более детально. Но методы вызываются строго по очереди. Возможно в каких-то случаях они качают 0 байт, но при этом лишний вызов на TCP не происходит (смотрел снифером) Возможно я не понимаю Blocking NIO. Надо, наверное, ещё свои собственные клиент-сервер написать для теста хитрых протоколов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 11:30:15 |
|
||
|
IO/NIO WTF
|
|||
|---|---|---|---|
|
#18+
Blazkowicz… Вот в этом примере 14921347 , по логике один из двух pump может заблокироваться, так как данные в эту сторону уже не идут. И второй pump не вызовется. Ведь поток заблокирован. Но на практике этого не происходит. … И в catch не попадает при этом? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2013, 12:06:12 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38416401&tid=2128468]: |
0ms |
get settings: |
16ms |
get forum list: |
25ms |
check forum access: |
6ms |
check topic access: |
6ms |
track hit: |
76ms |
get topic data: |
25ms |
get forum data: |
6ms |
get page messages: |
119ms |
get tp. blocked users: |
2ms |
| others: | 293ms |
| total: | 574ms |

| 0 / 0 |
