Easyelectronics.ru

Электроника для всех
Текущее время: 19 июл 2018, 22:37

Часовой пояс: UTC + 5 часов



    • JLCPCB - Платы прототипов всего за 2$ c бесплатной доставкой (при первом заказе)
    • 10 PCBs за $2 для 2 слоев, $15 для 4 слойной, $74 для 6 слойной платы.
    • Крупнейший китайский производитель прототипных плат. 290000+ клиентов & 8000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин радиодеталей.

Начать новую тему Ответить на тему  [ Сообщений: 19 ] 
Автор Сообщение
 Заголовок сообщения: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 17:06 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
Создал сокет как TCP Client. Читаю с сервера, пишу на сервер, все нормально. Но если вытащили кабель или сервер захлопнулся - какие мои действия? Закрыть старый сокет и пытаться открыть новый все время в таске?
Как то не логично. Если связь упала то получается я ломлюсь в закрытую дверь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 17:23 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 751
А стек TCP/IP "кто"? По идее стек должен закрыть сокет, если соединение ушло по таймауту и ошибке. А ты да, должен потом периодически стек опрашивать о возможности установить новое соединение. Если "кабель выдернут", стек должен сразу ошибку об этом возвращать. Интервалы попытки установки повторного соединения ты должен выбирать сам, исходя из требований задачи.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 17:24 
Старожил

Зарегистрирован: 28 янв 2012, 21:27
Сообщения: 292
Откуда: Питер
При падении TCP линка, TCP клиенты обычно делают 2 вещи:
1) Выводят статус "нет связи"
2) Через настраиваемые (юзером) промежутки времени пытаются восстановить связь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 17:27 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
NStorm писал(а):
А стек TCP/IP "кто"? По идее стек должен закрыть сокет, если соединение ушло по таймауту и ошибке. А ты да, должен потом периодически стек опрашивать о возможности установить новое соединение. Если "кабель выдернут", стек должен сразу ошибку об этом возвращать. Интервалы попытки установки повторного соединения ты должен выбирать сам, исходя из требований задачи.

я понял. спасибо. я установил SO_KEEPALIVE опцию в сокете. но я не пойму какой флаг или переменную проверять периодически.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 17:28 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
BBS писал(а):
При падении TCP линка, TCP клиенты обычно делают 2 вещи:
1) Выводят статус "нет связи"
2) Через настраиваемые (юзером) промежутки времени пытаются восстановить связь.

а как я знаю что нет связи?
ну алгоритмика теперь понятна, периодически проверять статус. у меня включена SO_KEEPALIVE опция. не знаю как ей пользоваться.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 17:40 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 мар 2012, 16:18
Сообщения: 146
jenya77 писал(а):
BBS писал(а):
При падении TCP линка, TCP клиенты обычно делают 2 вещи:
1) Выводят статус "нет связи"
2) Через настраиваемые (юзером) промежутки времени пытаются восстановить связь.

а как я знаю что нет связи?
ну алгоритмика теперь понятна, периодически проверять статус. у меня включена SO_KEEPALIVE опция. не знаю как ей пользоваться.

У тебя все под Windows написано ?
Вызывай getsockopt() и по возвращаемой ошибке определяй что у тебя отвалилось.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 17:57 
Старожил

Зарегистрирован: 31 янв 2013, 03:01
Сообщения: 216
SO_KEEPALIVE не предназначен для быстрого детекта обрыва канала.

Keepalive time is the duration between two keepalive transmissions in idle condition. TCP keepalive period is required to be configurable and by default is set to no less than 2 hours.

обычно реализуют переодический обмен пакетами с сервером (типа ping) на логическом уровне.
либо делают полноценный ping через icmp самого сервера или какого нибудь yandex.ru


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 17:57 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
zat писал(а):
jenya77 писал(а):
BBS писал(а):
При падении TCP линка, TCP клиенты обычно делают 2 вещи:
1) Выводят статус "нет связи"
2) Через настраиваемые (юзером) промежутки времени пытаются восстановить связь.

а как я знаю что нет связи?
ну алгоритмика теперь понятна, периодически проверять статус. у меня включена SO_KEEPALIVE опция. не знаю как ей пользоваться.

У тебя все под Windows написано ?
Вызывай getsockopt() и по возвращаемой ошибке определяй что у тебя отвалилось.

у меня vxWorks под эмбедед. пробовал делать так
Код:
int error_code;
int error_code_size = sizeof(error_code);
getsockopt(socket_descr, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
printf("error_code = %d\n",error_code);

вынимаю кабель - error_code = 0


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 18:04 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
Demax писал(а):
SO_KEEPALIVE не предназначен для быстрого детекта обрыва канала.

Keepalive time is the duration between two keepalive transmissions in idle condition. TCP keepalive period is required to be configurable and by default is set to no less than 2 hours.

обычно реализуют переодический обмен пакетами с сервером (типа ping) на логическом уровне.
либо делают полноценный ping через icmp самого сервера или какого нибудь yandex.ru

пинг? пинг это интересно. я даже не подумал об этом. я в начале делаю пинг, этакий обход проблемы со свичем - ping (''10.0.0.80'', 4) - а что если нет пинга функция вернет -1?

кстати я сконфигурировал кипэлайв на секундный интервал
Код:
#if KEEPALIVE_ON
    /* Set the option active */
    optval = 1;
    optlen = sizeof(optval);
    if(setsockopt(sFd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0)
    {
        close(sFd);
        return (ERROR);
    }
    printf("SO_KEEPALIVE set on socket\n");
   
    /* Interval (in seconds) between keepalives */
    optval = 1; //every one sec
    setsockopt(sFd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen);
    /* Maximum number of keepalives before dropping the connection */
    optval = 10;
    setsockopt(sFd, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen);
    /* Send first keepalive probe when the connections been idle this time (in seconds) */
    optval = 5;
    setsockopt(sFd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen);
    #endif


с пингом трюк не проходит. даже если сервер закрыт есть пинг.


Последний раз редактировалось jenya77 31 окт 2017, 18:28, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 18:09 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 751
Поэтому же и спрашивал - какой стек/ось. Везде свои реализации, от платформы плюс еще зависит как там события от сетевого интерфейса обрабатываются. По идее recv() и send() вернут ошибку, если верить мануалу vxWorks: http://www.vxdev.com/docs/vx55man/vxwor ... .html#recv

Цитата:
кстати я сконфигурировал кипэлайв на секундный интервал

Но т..к KA 10 пакетов будет, плюс 5 секунд отсутствие иных данных до передачи KA, итого минимум 15 секунд может понадобится, прежде чем соединение будет признано прерванным.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 18:26 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
NStorm писал(а):
Поэтому же и спрашивал - какой стек/ось. Везде свои реализации, от платформы плюс еще зависит как там события от сетевого интерфейса обрабатываются. По идее recv() и send() вернут ошибку, если верить мануалу vxWorks: http://www.vxdev.com/docs/vx55man/vxwor ... .html#recv

Цитата:
кстати я сконфигурировал кипэлайв на секундный интервал

Но т..к KA 10 пакетов будет, плюс 5 секунд отсутствие иных данных до передачи KA, итого минимум 15 секунд может понадобится, прежде чем соединение будет признано прерванным.

я тоже надеялся на recv(), но он возвращает -1 если не получили ничего с сервера, даже если есть соединение. а делать тестировочные send() мы не можем, сервер должен получать от нас только ответы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 20:10 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 мар 2012, 16:18
Сообщения: 146
jenya77 писал(а):
вынимаю кабель - error_code = 0

Т.е. если я правильно понимаю, при попытке опроса:
return getsockopt(...);
Если выдернуть кабель, то выдается 0 ?
Какая хоть операционка. Разные же реализации могут быть.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 31 окт 2017, 20:14 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
vxWorks. Unix. Да, странно но выдернув кабель не получаю ошибку.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 03 ноя 2017, 16:14 
Заглядывает иногда

Зарегистрирован: 15 окт 2017, 22:24
Сообщения: 180
Если нет ошибки сразу - по идее будет таймаут через некоторое время и сокет должен отвалиться по таймауту, особенно когда вы попробуете что-нибудь послать - в этом месте протокол заметит что нет ACK от ремоты и если за несколько попыток его не будет, TCP сдастся. Это если TCP. TCP вообще не реалтаймный и именно протокольные таймауты могут быть до 1-2 минут, потому что бывают всякие модемные и gprsные линки, где 20 секунд затык в потоке данных - обычное дело. Для более реалтаймных применений UDP логичнее - там данные или пришли или нет, но правильный порядок прихода датаграм и обработка потерь уже на вашей совести. Там уже можно сделать таймауты и проч как удобно вам. В TCP ряд параметров такого плана может настраиваться, но это очень зависит от операционки (и что в vxworks для этого есть - я не знаю).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 03 ноя 2017, 16:43 
Старожил

Зарегистрирован: 26 ноя 2012, 10:28
Сообщения: 2510
Откуда: КЧР, поселок Нижний Архыз
Я себе простой таймаут сделал.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 03 ноя 2017, 17:40 
Старожил
Аватара пользователя

Зарегистрирован: 23 сен 2012, 20:35
Сообщения: 1768
jenya77 писал(а):
Создал сокет как TCP Client. Читаю с сервера, пишу на сервер, все нормально. Но если вытащили кабель или сервер захлопнулся - какие мои действия? Закрыть старый сокет и пытаться открыть новый все время в таске?
Как то не логично. Если связь упала то получается я ломлюсь в закрытую дверь.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 03 ноя 2017, 17:44 
Старожил
Аватара пользователя

Зарегистрирован: 23 сен 2012, 20:35
Сообщения: 1768
jenya77 писал(а):
я тоже надеялся на recv(), но он возвращает -1 если не получили ничего с сервера, даже если есть соединение. а делать тестировочные send() мы не можем, сервер должен получать от нас только ответы.

Можно попробовать отправлять OOB (out of bound) данные. Они не считаются частью основного потока, потому сервер их, скорее всего, не увидит, но проверить успешность отправки вполне получится. Но это надо проверять, некоторые стеки могут неправильно обрабатывать такие потоки. Помнится, старую винду можно было было уронить до синего экрана просто отправив OOB пакет на правильный порт.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 04 ноя 2017, 21:03 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 202
На форуме vxWorks мне сказали что достаточно если включена KEEPALIVE опция.
я не могу инициализировать посылку. таймаут тоже не поможет, данные могут прийти и через час.
пока проверяю так
Код:
int IsSocketAlive(int mode, int socket_descr)
{
   int result;
   
   switch (mode)
   {
       case 0:
          if (errno > 0 && errno < 150)
          {
             printf("errno = %d\n", errno);
              result = errno;
          }
      break;
       case 1:
       {
          int error_code;
          int error_code_size = sizeof(error_code);
          getsockopt(socket_descr, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
          printf("error_code = %d\n",error_code);
          result = error_code;  //60
       }
       break;
       case 2:
       {
          int status;
          int data;
          status = recv(socket_descr, &data, 1, MSG_PEEK | MSG_DONTWAIT);
          printf("status = %d\n",status);
          result = status;  //-1
       }
       break;
   }

   return result;
}

все опции дают полный мониторинг.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Работа с сокетами.
СообщениеДобавлено: 06 ноя 2017, 13:18 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1125
Откуда: Германия
Эмм. Если ембеддед, то зачем изобретать велосипед, если он уже изобретен до нас. Называется PHY. Он отслеживает, есть ли соединение. Либо отдельный пин на это, либо опрос его регистров.
Настроить прерывание на пин, либо создать евент на изменение регистра. И в обработчике этого события либо открывать сокет, либо закрывать. Это если кабель вытащили.
Если сервер захлопнулся, и не пришло событие из стека, то по таймауту бездействия. Обычно 30 секунд стоит везде. В зависимости от задачи таймаут можно подгонять под свои нужды.

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 19 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB