powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Перезапуск потока в бесконечном цикле (клиента TCP)
13 сообщений из 13, страница 1 из 1
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39762950
iobox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!
Модем 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.
  
public void startApp () 
{  
//....
while (1 > 0)
{
  try
  {
    if (clientTCP == null)
    {
      clientTCP = new ClientThread();
      clientTCP.Exchange_Buffer = Exchange_Buffer;
      clientTCP.start();
    }
            
  }
  catch (Exception e)
  {
    System.out.println("Error thread");   
  }
            
  if (clientTCP != null)
  {          
     //???? 
  }
}
///...
  





Код: 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.
public void run(){                    //   (class ClientThread extends Thread)
        try 
        {

            sleep(10000);

            sc = (SocketConnection) Connector.open("socket://...;bearer_type=gprs;access_point=static.beeline.ru;username=beeline;password=beeline;timeout=5", Connector.READ_WRITE, true);

            inC = sc.openDataInputStream();
            outC = sc.openDataOutputStream();

            
            //  System.out.println ("remote " + sc.getAddress());
            //  System.out.println ("local " + sc.getLocalAddress());
         }    
         catch (Exception ex) {
             System.out.println ("Error create");
         }
         
         try
         {
             while (1 > 0)
             {    
                    readwriteTCP();
             }
         }
           catch (Exception ex3) {
            System.out.println ("Error readwrite");

           }
        
        
         try
           {
           inC.close();
           outC.close();
           sc.close();
           sc = null;  
           }
            catch (Exception ex2) {
         }

}
}




Пишется и читается так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
 public void readwriteTCP() throws InterruptedException, IOException   //(class ClientThread extends Thread)
            
    {
        Command_TCP = 0;
        
        if (inC.available() > 0) 
        {
           Command_TCP = inC.readInt();
        } 
        
        Send_Buffer = "beg:" + Exchange_Buffer + ":end";     
        
        if ((Command_TCP & 0x1) == 1)
        {
            outC.write(Send_Buffer.getBytes());
            outC.flush();
         }             

    }
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39762999
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Безумно странный код.
Зачем бесконечный цикл, мне вообще не понятно.

Складывается ощущение, что иногда не вызывается исключение при пропадании сессии с сервером.

Как я понимаю, обрыв соединения может гарантированно деагностироваться только при неудачной попытке обмена (+ таймаут)

Если соединение потерялось "на прием", ну нет данных от устройства и нет данных. А почему нет, толи потому что их нет, толи потому, что связь не работает - то не ведомо

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

IMHO & AFAIK
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763001
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ioboxдождаться завершения потока

https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html

???
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763203
Озверин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iobox, это учебный проект или реальная утилита?
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763249
iobox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо.

Проблема решена, вроде работает.

Использую System.currentTimeMillis() для определения таймаута между чтениями из DataInputStream.
Если превышен, закрываю DataInputStream (принудительно вызываю Exception и выход из бесконечного цикла), далее нормально завершаю поток и пересоздаю его же.

Для "жестких" зависаний мидлетов и т.п. , в данном модеме производителем предусмотрены 2 watchdog'а.

Это реальная утилита на основе примеров от производителя оборудования и форума Gemalto.
Java ME для Cinterion EHS5-E

Следующий этап - передавать данные с/в COM-порт модема, то есть обеспечить "прозрачный" режим.
Есть идеи как копировать потоки данных RS232 в TCP?

Критика приветствуется.
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763278
Озверин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iobox, если рабочая, то вместо собственных велосипедов всегда уместно использовать что-то сделанное ранее: можно netty, а можно что-нить реализованное с netty - reactor: https://github.com/reactor/reactor-netty


ioboxЕсть идеи как копировать потоки данных RS232 в TCP?
посмотреть документацию модема - он должен работать в таком режиме и перенаправлять(вроде как?), если поддерживает.
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763443
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вечный цикл то зачем? Что за порнография в "реальной утилите"

ioboxИспользую System.currentTimeMillis() для определения таймаута между чтениями из DataInputStream.

Тут же видна проблема с кодом.

Код: java
1.
2.
3.
4.
        if (inC.available() > 0) 
        {
           Command_TCP = inC.readInt();
        } 



inC.available() > 0 никак НЕ гарантирует, что вызов readInt() завершится удачно.

предположим, что в буффере оказался 1 (ОДИН) байт. Данные строчки кода явно будут работать не так, как Вы ожидаете.

Зачем вообще нужна проверка в вечном цикле inC.available() > 0, мне вообще не понятно. Банально inC.readInt() и все. Все ожидания будет разруливать система. IMHO

Если нужно независимое чтение/запись, то разнести на два потока. Один читает, другой пишет.
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763536
alex55555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevВечный цикл то зачем?
Он там вопросики исполняет. Закомментировал и думает, что потом про них что-то напишет. Типичный неумёха.
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763564
iobox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Про int и byte посмотрю, действительно косяк.

Про "вечный цикл" не согласен. Посмотрите примеры кода для Arduino, примеры от производителя оборудования IRZ тоже содержат его. В других задачах я стараюсь вообще избегать while.

inC.available() позволяет не заморачиваться со стеком ответов, иначе еще предстоит из кусков ответ собирать, как я понял. Я уже столкнулся с этой проблемой на стороне сервера.

В моем случае результат чтения Command_TCP - это команда от сервера (запросить состояние дискретных входов, установить такой-то дискретный выход модема в "1", либо выполнить перезагрузку и т.п.).
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763568
iobox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вместо вопросиков стало и работает:

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");
}
}
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763584
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ioboxinC.available() позволяет не заморачиваться со стеком ответов, иначе еще предстоит из кусков ответ собирать, как я понял. Я уже столкнулся с этой проблемой на стороне сервера.
Что такое "стек ответов" не понимаю
собирать из кусков и так и так придется. Но DataInputStream само и соберет. На Вас то это никак не сказывается

ioboxВ моем случае результат чтения Command_TCP - это команда от сервера (запросить состояние дискретных входов, установить такой-то дискретный выход модема в "1", либо выполнить перезагрузку и т.п.).

команда от сервера - звучит дико. Дабы под словами "клиент" и "сервер" обычно понимают прямо противоположное IMHO & AFAIK

ну так и читайте команду readInt и обрабатывайте ее. Зачем available проверять?

Нет команды - система стоит и ждет данных ("собирает из кусков ответ"). Появились данные, readInt завершился, Вы обрабатываете команду, посылаете ответ.

Установили проверку KeepAlive и TimeOut'а, если произошел timeout - возникло исключение, можно попытаться пересоединиться.

Пока какое-то дикое переусложнение кода, зачем - для меня совершенно не понятно. Мало того, Вы постоянно дергаете available() в цикле, т.е. дурацкой работой постоянно загружается ядро процессора. Что в свою очередь вполне может являться причиной 100500 разных "глюков"

IMHO

p.s. Вам конечно виднее, что бы что-то советовать нужно как минимум железо в руках "подержать" )))
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763595
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iobox
Код: java
1.
2.
        System.out.println("Try stop thread ");   
        clientTCP.join();



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
...
Рейтинг: 0 / 0
Перезапуск потока в бесконечном цикле (клиента TCP)
    #39763648
iobox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Необходимо передавать показания аналогового датчика с удаленного объекта (пусть будет температура для примера) с заданным таймаутом (пусть будет 1 секунда) в SCADA. Датчик подключен к модему.

Без разницы, кто в данном случае будет сервером, а кто - клиентом.
В случае Exception на сервере мне так же бы пришлось перезапускать thread сервера на модеме.

По поводу "join" я понял, что основной поток ожидает остановки дополнительного. А обнуление переменной "clientTCP" мне нужно для создания нового потока с этой же переменной, чтобы не плодить кучу при плохой связи и быть уверенным, что активен только 1.

Про available() задумался, спасибо.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Перезапуск потока в бесконечном цикле (клиента TCP)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]