|
|
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
Считываю информацию из сокета. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Так вот in.ready(); в некоторых случаях работает нормально - когда true, то считывает информацию, когда false, то не считывает, а в некоторых показывает, что "тру", но зависает на in.readLine(); А почему так? И как правильно сделать, чтобы не подвиснуть на readLine, а пройти дальше? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 14:02:21 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
readLine() может читать больше данных, чем доступно в буфере или в inputStream без блокирования. Либо не использовать readLine(). Либо изучать NIO. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 14:16:19 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
BlazkowiczreadLine() может читать больше данных, чем доступно в буфере или в inputStream без блокирования. Либо не использовать readLine(). Либо изучать NIO. Я не понял как лучше сделать, если без NIO. Мне шлют информацию, я должен ее считать, а далее проверять, есть ли там информация, и, если нет, то проходить дальше и делать нужные мне действия - и так в цикле. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 14:26:19 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
Собственно, если бы не было зависания - то все бы верно работало, без проблем. Но как его избежать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 14:27:48 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
else12Я не понял как лучше сделать, если без NIO. Задавай конкретные вопросы. Что не понятно? else12Мне шлют информацию, я должен ее считать, а далее проверять, есть ли там информация, и, если нет, то проходить дальше Смотри. Сначала "считать", а потом "проверять, если есть". Странная постановка задачи. Может наоборот? Многое ещё зависит и от протокола передачи данных... else12и делать нужные мне действия - и так в цикле. ОК. Давай попробую разжевать. Итак. Данные по сети приходят не все сразу, а по частям. Если данные пришли, их можно читать. Если данные читать, но они не пришли, то потом блокируется до прихода данных. Это понятно? Данные, которые пришли, но ещё не прочитаны, могут находится в буфере. Буферов здесь несколько. Один в BufferedReader. Другие, возможны, в реализации работы с Socket на уровне JVM, ОС, железа. Метод ready() проверяет буфер в BufferedReader и метод InputStream.available(). Последний сигнализирует о наличии данных в скрытых буферах. Метод readLine() читает все данные до переноса строки (\n). Почему метод readLine() зависает? Потому что сервер прислал какие-то данные после переноса строки. Но не прислал сам перенос строки. Поэтому readLine() вызывает read(). Который блокирут поток, пока сервер чего-то не пришлет. Правильное решение зависит от того какой протокол обмена данными реализуется с сервером. Что делать, если пришла порция данных, но не пришел "разделитель"? Если сервер строго заканчивает все сообщения "разделителем", то стоит подебажить и посмотреть что же за данные приехали после "разделителя" и перед зависанием. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 14:43:58 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
BlazkowiczПравильное решение зависит от того какой протокол обмена данными реализуется с сервером. Что делать, если пришла порция данных, но не пришел "разделитель"? Если сервер строго заканчивает все сообщения "разделителем", то стоит подебажить и посмотреть что же за данные приехали после "разделителя" и перед зависанием. У меня сервер-сокет, по протоколу TCP мне приходят данные в виде xml-команд. По идее больше ничего приходить не должно. Я устанавливаю соединение, все проходит нормально. Вначале идет инициализация - в цикле я получаю команды, передаю ответы и т.д. Перед зависанием - из того, что я вижу - в буфер пришли именно данные в виде команд - я их принимаю (все верно - команды xml), посылаю ответ, получаю реакцию на ответ - пока идет диалог, все нормально. Но вот я получил последнюю команду инициализации (все это в цикле), а дальше цикл по идее должен работать так - если данные не пришли (а после инициализационных действий они не приходят какое-то время), пройти дальше, а, если пришли - принять их. Но вместо этого я зависаю на ожидании... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 15:15:33 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
BlazkowiczЕсли сервер строго заканчивает все сообщения "разделителем", то стоит подебажить и посмотреть что же за данные приехали после "разделителя" и перед зависанием. Вроде бы приходит разделитель, а после него ничего не приходит - все, что я считываю, я и смотрю и вывожу на экран. Но почему-то ready говорит, что в буфере что-то есть, а readLine зависает... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 15:18:30 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
else12У меня сервер-сокет, по протоколу TCP мне приходят данные в виде xml-команд. Ну, вот и ответ. Кто будет гарантировать что xml заканчивается переносом строки? Не один XML генератор не парится с тем чтобы присылать конец строки после конца документа. else12Но вместо этого я зависаю на ожидании... Посмотри в дебаге содержимое буфера в BufferedReader. Он пустой? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 15:28:20 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
else12Но почему-то ready говорит, что в буфере что-то есть, а readLine зависает... Блин. Ну, я же объяснил уже. В буфере нет конца строки. А readLine() читает всё до конца строки. Буфер не пустой. Можно читать. Поэтому читать надо посимвольно и проверять ready(), а не через readLine(). Либо читать до конца XML, а не через readLine(). В твоём случае readLine() это ещё и офигенный оверхед по памяти. Вычитать String-и построчно. Склеить потом в один XML (тоже String?) И потом это всё добро распарсить? При том что парсеры нормально могут напрямую читать InputStream. Нужно лишь прерывать его по окончании XML. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 15:32:37 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
BlazkowiczВычитать String-и построчно. Склеить потом в один XML (тоже String?) И потом это всё добро распарсить? При том что парсеры нормально могут напрямую читать InputStream. Нужно лишь прерывать его по окончании XML. Вы имеете в виду, что нужно проверить InputStream.available(), И, если тру, то передать парсеру? А прервать поток - это переоткрыть его или что имеется в виду? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 15:56:21 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
else12Вы имеете в виду, что нужно проверить InputStream.available(), BufferedReader.ready() проверет как свой буфер, так и InputStream.available(). Об этом я написал выше и об этом же написано в JavaDoc. Использовать Reader или InputStream это уже решать в зависимости от задачи. Я лишь говорю - не использовать readLine() . else12И, если тру, то передать парсеру? Нет. Метод может вернуть false из-за задержки сети. Это не значит что пакет окончен. else12А прервать поток - это переоткрыть его или что имеется в виду? Создать свой InputStream, который бы завершался согласно спецификации InputStream, когда в основном InputStream завершается пакет. А как именно завершается пакет, это нужно вам выбрать исходя из протокола обмена данными. Вы для себя решили что пакет заканчивается переносом строки. Но думает ли сервер точно так же? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 16:00:54 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
Blazkowiczelse12Вы имеете в виду, что нужно проверить InputStream.available(), BufferedReader.ready() проверет как свой буфер, так и InputStream.available(). Об этом я написал выше и об этом же написано в JavaDoc. Использовать Reader или InputStream это уже решать в зависимости от задачи. Я лишь говорю - не использовать readLine() . else12И, если тру, то передать парсеру? Нет. Метод может вернуть false из-за задержки сети. Это не значит что пакет окончен. else12А прервать поток - это переоткрыть его или что имеется в виду? Создать свой InputStream, который бы завершался согласно спецификации InputStream, когда в основном InputStream завершается пакет. А как именно завершается пакет, это нужно вам выбрать исходя из протокола обмена данными. Вы для себя решили что пакет заканчивается переносом строки. Но думает ли сервер точно так же? Что-то я запутался, как мне правильно сделать... У меня есть сокет-сервер, я делаю accept, потом создаю выходной и входной потоки. Я передаю входной поток парсеру или какой поток? Мне надо проверить, могу ли я передать поток парсеру - как это правильно сделать? После обработки потока - пусть стаксом - что мне надо сделать? От клиента я жду xml-команды или какой-то промежуток времени он может ничего не присылать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 16:07:18 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
else12Что-то я запутался, как мне правильно сделать... Для начала нужно разобраться как работает каждый элемент пазла Socket Stream Reader Parser И только после этого будет понятно как правильно сделать. Потому что я предлагаю несколько разных решений. else12Я передаю входной поток парсеру или какой поток? Нет. Входной поток может содержать много XML. А парсер может читать только 1 до конца InputStream. else12Мне надо проверить, могу ли я передать поток парсеру - как это правильно сделать? Не можешь. Нужно создать свой MyInputStream, который бы чтение делегировал оригинальному InputStream. Но при окончании пакета в оригинальном InputStream изображал бы из себя окончания всего InputStream. А на новый пакет, нужно создавать такой же новый экземпляр MyInputStream. else12После обработки потока - пусть стаксом - что мне надо сделать? Я не знаю. Что там говорит ТЗ на этот счет? else12От клиента я жду xml-команды или какой-то промежуток времени он может ничего не присылать... Да. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 16:57:07 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
BlazkowiczДля начала нужно разобраться как работает каждый элемент пазла Socket Stream Reader Parser Код схематично такой. Или что еще надо? Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.09.2013, 17:18:15 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
Blazkowiczelse12Что-то я запутался, как мне правильно сделать... Для начала нужно разобраться как работает каждый элемент пазла Socket Stream Reader Parser И только после этого будет понятно как правильно сделать. Потому что я предлагаю несколько разных решений. Я все-таки не врубаюсь как правильно написать код... По порядку - я объявляю сокет, делаю accept и после соединения хочу считывать данные в socket.getInputStream(); Пока все верно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2013, 16:33:44 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
else12 , Все верно. Другое дело, что когда вы работаете с BufferedReader.readLine(), то вы не знаете, сколько он вернет байт, так как вы не знаете, где будет конец строки. Что, есди сейчас в стриме доступно (available) 4 байта, но символа "конец строки" там нет? Тогда у вас BufferedReader заблокируется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2013, 16:38:16 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
cdtyjv else12 , Все верно. Другое дело, что когда вы работаете с BufferedReader.readLine(), то вы не знаете, сколько он вернет байт, так как вы не знаете, где будет конец строки. Что, есди сейчас в стриме доступно (available) 4 байта, но символа "конец строки" там нет? Тогда у вас BufferedReader заблокируется. Можно как-то этого избежать или зависнуть не напрочь, а с выходом из зависания по тайм-ауту? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2013, 16:46:35 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
else12Можно как-то этого избежать или зависнуть не напрочь, а с выходом из зависания по тайм-ауту?Два варианта: 1) Работать с input stream сокета, и ориентироваться на available(). Но как вы в этом случае будете дожидаться появления информации в сокете - хз. 2) Перейти на NIO, там есть ожидание с таймаутами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2013, 16:49:54 |
|
||
|
Считывание информации из сокета
|
|||
|---|---|---|---|
|
#18+
else12Можно как-то этого избежать или зависнуть не напрочь, а с выходом из зависания по тайм-ауту? Использовать разные потоки. Один только для чтения из сокета. Второй для обработки XML пакетов и прочей фигни, которая не должна зависать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.09.2013, 16:57:21 |
|
||
|
|

start [/forum/topic.php?fid=59&fpage=209&tid=2128562]: |
0ms |
get settings: |
12ms |
get forum list: |
35ms |
check forum access: |
8ms |
check topic access: |
8ms |
track hit: |
58ms |
get topic data: |
27ms |
get forum data: |
5ms |
get page messages: |
144ms |
get tp. blocked users: |
2ms |
| others: | 273ms |
| total: | 572ms |

| 0 / 0 |
