|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
Здравствуйте! Модем GSM работает как клиент TCP. В основном потоке запускаю поток-клиент (class ClientThread extends Thread), основной поток работает в бесконечном цикле. В нормальном режиме работы все хорошо работает, читаем с сервера, пишем (тоже в бесконечном цикле). А вот при тестировании обрывов и недоступности сервера начинаются подвисания потока-клиента. Складывается ощущение, что иногда не вызывается исключение при пропадании сессии с сервером. Как правильно завершить и дождаться завершения потока, а потом запустить его снова? На Java первый проект. Код: 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.
Код: 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.
Пишется и читается так: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2019, 16:20 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
Безумно странный код. Зачем бесконечный цикл, мне вообще не понятно. Складывается ощущение, что иногда не вызывается исключение при пропадании сессии с сервером. Как я понимаю, обрыв соединения может гарантированно деагностироваться только при неудачной попытке обмена (+ таймаут) Если соединение потерялось "на прием", ну нет данных от устройства и нет данных. А почему нет, толи потому что их нет, толи потому, что связь не работает - то не ведомо Вроде Keep-Alive должно в этом помогать (хорошо бы проверить, что Keep-Alive вообще включен), но как мне кажется, это тоже ничего не гарантирует. IMHO & AFAIK ... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2019, 17:23 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
ioboxдождаться завершения потока https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html ??? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.01.2019, 17:26 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
iobox, это учебный проект или реальная утилита? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 08:22 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
Спасибо. Проблема решена, вроде работает. Использую System.currentTimeMillis() для определения таймаута между чтениями из DataInputStream. Если превышен, закрываю DataInputStream (принудительно вызываю Exception и выход из бесконечного цикла), далее нормально завершаю поток и пересоздаю его же. Для "жестких" зависаний мидлетов и т.п. , в данном модеме производителем предусмотрены 2 watchdog'а. Это реальная утилита на основе примеров от производителя оборудования и форума Gemalto. Java ME для Cinterion EHS5-E Следующий этап - передавать данные с/в COM-порт модема, то есть обеспечить "прозрачный" режим. Есть идеи как копировать потоки данных RS232 в TCP? Критика приветствуется. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 10:07 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
iobox, если рабочая, то вместо собственных велосипедов всегда уместно использовать что-то сделанное ранее: можно netty, а можно что-нить реализованное с netty - reactor: https://github.com/reactor/reactor-netty ioboxЕсть идеи как копировать потоки данных RS232 в TCP? посмотреть документацию модема - он должен работать в таком режиме и перенаправлять(вроде как?), если поддерживает. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 10:48 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
Вечный цикл то зачем? Что за порнография в "реальной утилите" ioboxИспользую System.currentTimeMillis() для определения таймаута между чтениями из DataInputStream. Тут же видна проблема с кодом. Код: java 1. 2. 3. 4.
inC.available() > 0 никак НЕ гарантирует, что вызов readInt() завершится удачно. предположим, что в буффере оказался 1 (ОДИН) байт. Данные строчки кода явно будут работать не так, как Вы ожидаете. Зачем вообще нужна проверка в вечном цикле inC.available() > 0, мне вообще не понятно. Банально inC.readInt() и все. Все ожидания будет разруливать система. IMHO Если нужно независимое чтение/запись, то разнести на два потока. Один читает, другой пишет. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 13:51 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
Leonid KudryavtsevВечный цикл то зачем? Он там вопросики исполняет. Закомментировал и думает, что потом про них что-то напишет. Типичный неумёха. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 14:56 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
Про int и byte посмотрю, действительно косяк. Про "вечный цикл" не согласен. Посмотрите примеры кода для Arduino, примеры от производителя оборудования IRZ тоже содержат его. В других задачах я стараюсь вообще избегать while. inC.available() позволяет не заморачиваться со стеком ответов, иначе еще предстоит из кусков ответ собирать, как я понял. Я уже столкнулся с этой проблемой на стороне сервера. В моем случае результат чтения Command_TCP - это команда от сервера (запросить состояние дискретных входов, установить такой-то дискретный выход модема в "1", либо выполнить перезагрузку и т.п.). ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 15:13 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
Вместо вопросиков стало и работает: if (clientTCP != null) { if ((clientTCP.Ended == 11)) { System.out.println("Try stop thread "); clientTCP.join(); System.out.println("Try clear thread "); clientTCP = null; System.out.println("Thread cleared"); } } ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 15:16 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
ioboxinC.available() позволяет не заморачиваться со стеком ответов, иначе еще предстоит из кусков ответ собирать, как я понял. Я уже столкнулся с этой проблемой на стороне сервера. Что такое "стек ответов" не понимаю собирать из кусков и так и так придется. Но DataInputStream само и соберет. На Вас то это никак не сказывается ioboxВ моем случае результат чтения Command_TCP - это команда от сервера (запросить состояние дискретных входов, установить такой-то дискретный выход модема в "1", либо выполнить перезагрузку и т.п.). команда от сервера - звучит дико. Дабы под словами "клиент" и "сервер" обычно понимают прямо противоположное IMHO & AFAIK ну так и читайте команду readInt и обрабатывайте ее. Зачем available проверять? Нет команды - система стоит и ждет данных ("собирает из кусков ответ"). Появились данные, readInt завершился, Вы обрабатываете команду, посылаете ответ. Установили проверку KeepAlive и TimeOut'а, если произошел timeout - возникло исключение, можно попытаться пересоединиться. Пока какое-то дикое переусложнение кода, зачем - для меня совершенно не понятно. Мало того, Вы постоянно дергаете available() в цикле, т.е. дурацкой работой постоянно загружается ядро процессора. Что в свою очередь вполне может являться причиной 100500 разных "глюков" IMHO p.s. Вам конечно виднее, что бы что-то советовать нужно как минимум железо в руках "подержать" ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 15:29 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
iobox Код: java 1. 2.
1. может у меня не все в порядке с английским, но действие метода join() назвать "Try stop thread" как-то очень круто 2. есть подозрение, что Вы вообще плохо представляете, что Вы пытаетесь делать. 2.1. проверка на clientTCP != null избыточна. Т.к. нет строчки, где бы clientTCP присваивался null. Оно всегда НЕ null 2.2. я бы join() вынес сразу после start(). Запустили поток - ждем его завершения. 2.3. про то, что join() != "stop", я уже сказал 2.4. catch( Exception e ) на внешнем уровне бесмысленнен, в 99.9999999% туда никогда ничего не прилетит вообще, пока лично мне не очень ясно: 3.1 Зачем вообще нужен отдельный thread для работы. Можно обойтись и без него 3.2. Зачем проверка на inC.available() IMHO ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 15:39 |
|
Перезапуск потока в бесконечном цикле (клиента TCP)
|
|||
---|---|---|---|
#18+
Необходимо передавать показания аналогового датчика с удаленного объекта (пусть будет температура для примера) с заданным таймаутом (пусть будет 1 секунда) в SCADA. Датчик подключен к модему. Без разницы, кто в данном случае будет сервером, а кто - клиентом. В случае Exception на сервере мне так же бы пришлось перезапускать thread сервера на модеме. По поводу "join" я понял, что основной поток ожидает остановки дополнительного. А обнуление переменной "clientTCP" мне нужно для создания нового потока с этой же переменной, чтобы не плодить кучу при плохой связи и быть уверенным, что активен только 1. Про available() задумался, спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.01.2019, 16:25 |
|
|
start [/forum/topic.php?fid=59&fpage=33&tid=2121526]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
55ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
others: | 337ms |
total: | 480ms |
0 / 0 |