LINUX.ORG.RU

Вопрос по созданию устойчивого соединения


0

1

Всем привет, подскажите какой есть аналог SO_KEEPALIVE, в том смысле что этот параметр выполняет проверку при отсутствии трафика в течении 2 часов, а нужно допустим 15 секунд. Просто если изменять поведения параметра SO_KEEPALIVE, то это отразится на всю систему, а это нежелательно.


Какое поведение-то конкретно нужно? Лучше всего приведи участок (псевдо)кода.

Krieger_Od ★★
()
Последнее исправление: Krieger_Od (всего исправлений: 1)

Во-первых нафига, если все равно слать нечего, во-вторых кипалайв не для этого, man tcp heartbeat.

arturpub ★★
()
Ответ на: комментарий от Harald

Ну я в любом случае реализуй подтверждение приема некоторого фрейма данных, например <MSG><Id><length>Текст Сообщения<\msg> После получения закрывающего тега принимающая сторона шлет ответное сообщение с id увеличенным на единицу, или просто то же айди , и тогда сообщение удаляется из очереди, а если подтверждение не приходит в течении 5 секунд сообщение отсылается еще раз, и опять не приходит то помечается как не принятое и если подряд не доходят например 3 крайних сообщения то это как разрыв соединения трактуется. Ну пинговать это конечно хорошо, но я вот решил спросить есть ли вариант на уровне протокола?)

Onito
() автор топика
Ответ на: комментарий от Onito

а если подтверждение не приходит в течении 5 секунд сообщение отсылается еще раз

через потоковое соедниение? Бессмысленное занятие

Harald ★★★★★
()
Ответ на: комментарий от arturpub

Ну я например шлю что-то и мне нужно знать принял или нет клиент сообщение, а так 90 секунд он будет ждать до тайм-аута, а блокироваться в вызове чтения ответа не всегда возможно, на столько долго, и приходиться костыль делать

Onito
() автор топика
Ответ на: комментарий от Onito

если подтверждение не приходит в течении 5 секунд сообщение отсылается еще раз

Это не сработает, та сторона будет ждать первый пакет, остальные если и дойдут, то будут ждать ретрансляции первого пакета на уровне tcp. Потом придут сразу три.

arturpub ★★
()
Ответ на: комментарий от Onito

Если костылем ты называешь селект, то я тебя обрадую — сеть это всегда асинхронка, кроме тупейших сервисов-перекачек.

arturpub ★★
()

Ну и пингуй каждые 15 секунд.

bhfq ★★★★★
()
Ответ на: комментарий от Harald

Тут бы можно дополнить, если превышено время ожидания, дропаем соединение, переподключаемся, перепосылаем.

Если неудачны 3 или сколько надо попыток - считаем, что на некоторое время все умерло.

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

grondek
()
Ответ на: комментарий от Harald

Ну я и написал что жду ответ некоторое время и если ответа нет то дропаю соединение

Onito
() автор топика
Ответ на: комментарий от arturpub

Почему не сработает? По твоему если пришло сообщение дважды это нельзя обработать? Да и если прийдет fin в 3 пакете это тоже нормально, типо был временный разрыв сети и сообщение как уже писали можно восстановить, и использовать какой-нибудь дамп сессии чтобы восстановить состояние на момент разрыва

Onito
() автор топика
Ответ на: комментарий от arturpub

Почему не сработает? По твоему если пришло сообщение дважды это нельзя обработать? Да и если прийдет fin в 3 пакете это тоже нормально, типо был временный разрыв сети и сообщение как уже писали можно восстановить, и использовать какой-нибудь дамп сессии чтобы восстановить состояние на момент разрыва

Onito
() автор топика
Ответ на: комментарий от arturpub

Почему не сработает? По твоему если пришло сообщение дважды это нельзя обработать? Да и если прийдет fin в 3 пакете это тоже нормально, типо был временный разрыв сети и сообщение как уже писали можно восстановить, и использовать какой-нибудь дамп сессии чтобы восстановить состояние на момент разрыва

Onito
() автор топика
Ответ на: комментарий от arturpub

Причем тут селект? Ну поставлю я тайм-аут на селект, скажем 15 секунд, допустим сообщения не приходили, я отсылаю пустой байт, в ответ принимаю допустим тоже пустой байт, и потом возвращаясь в селект, и тут все прекрасно, но допустим такое: до тайм-аута так и не доходит, и появляются данные скажем в стандартной потоке ввода которые селект чекает, и вот мы выходим из него и отсылаем эти данные, и опять висим в селекте, потом приходит подтверждение о приеме сообщения, мы выходим из селекта и получив подтверждение удаляем сообщение из очереди (например), но если мы не получаем подтверждение то по тайм-ауту мы его пингуем и тут только два исхода: мы получаем rst так как сервер перезагрузился или умер совсем, или мы получаем ответ что все дошло. Это разве не правильное поведение?

Onito
() автор топика
Ответ на: комментарий от arturpub

Да про отсылать через 5 секунд это я бред сказал не подумав, tcp ведь сохраняет очередность, хотя отклбчив алгоритм нагла второй пакет будет отослан без подтверждения первого и это может ускорить работу при высокой потере пакетов в сети, разве нет?

Onito
() автор топика
Ответ на: комментарий от Krieger_Od

Ну нулями заполненый байт что не так то?)

Onito
() автор топика
Ответ на: комментарий от Krieger_Od

Ну с точки зрения ip есть пакеты, мое рассуждения разве не корректно?

Onito
() автор топика
Ответ на: комментарий от Onito

Почему не сработает

Потому что нет смысла. Все три я прочитал минуту назад, хватило бы и одного, но если у меня инет кончится, то и пяти не хватит.

Если ты хочешь постоянное соединение «с сессией», то все, что нужно, это клиенту выкидывать из очереди только подтвержденные пакеты, серверу подтверждать все, но обрабатывать только ранее неподтвержденные (следить тупо по номеру), а при разрыве клиент перепосылает всю очередь ожидания заново. Ну и ключ сессии перед всем, как ты уже понял, плюс кикать рваные сессии по большому таймауту, например сутки/неделя.

arturpub ★★
()
Ответ на: комментарий от Onito

Это разве не правильное поведение?

ничо не понял в общем-то, но наверное правильное. Селект при том, что это единственный способ зависнуть не на одном блокирующем чтении, а на нескольких, если ты печешься о залипаниях на чтении сокета.

Upd. И да, пинги пустым байтом это бред. Ты не победишь пустым байтом объективные проблемы tcp. Либо сессия с большим таймаутом поверх, либо не парься вообще, порвалось значит порвалось. Суть хартбита в том, чтобы разделить ситуации «нет данных» и «проблема передачи», а не в том, чтобы гарантировать доставку.

arturpub ★★
()
Последнее исправление: arturpub (всего исправлений: 2)
Ответ на: комментарий от arturpub

Ну если про алгоритм нагла я правильно сказал можно перепосылать пакеты, только там нужно уже с тайм-аутом смотреть,тогда будет просто быстрее, по поводу большого тайм-аута ты пишешь, это какраз кипалив разве нет?

Onito
() автор топика
Ответ на: комментарий от Onito

Я писал про таймаут на сессию, она живет сутки без соединения, возможно переживает ребуты. Какой тут кипалайв?

arturpub ★★
()
Ответ на: комментарий от arturpub

ну ок, я тебя понял, в общем сойдёмся на том что надо нумеровать сообщения, отсылать подтверждения о их получении и далее как ты писал в одном сообщении выше :). По поводу Heartbeat: можно использовать алгоритм с википедии:Кроме того, по всем неиспользуемым (дополнительным) адресам периодически передаются специальные блоки Heartbeat и поддерживается счетчик числа блоков Heartbeat, переданных без возврата соответствующего Heartbeat Ack. Когда значение счетчика достигает заданного порога (параметр конфигурации), соответствующий адрес объявляется неактивным. Блоки Heartbeat передаются по неактивным адресам до тех пор, пока не будет получено сообщение Ack, говорящее о восстановлении активности адреса. Частота передачи блоков Heartbeat определяется значение RTO и дополнительной задержкой, которая позволяет передавать блоки Heartbeat без помех для пользовательского трафика. Тоесть в tcp это так: например каждые 5 секунд отсылаю определённый запрос, на который получаю определённый ответ, если на момент отправки 4 запроса есть 3 без ответа то это разрыв.

Onito
() автор топика

Шли пинг/понги на уровне протокола. /тред

nanoolinux ★★★★
()
Ответ на: комментарий от Onito

Как хошь, но ты делаешь детскую сетевую ошибку — переизобретаешь tcp поверх tcp, когда нужен просто tcp. Никто лучше tcp-стека не знает, что такое «tcp-соединение» и когда оно «порвалось». Эти 20 секунд ничем не лучше стандартных таймаутов и других механизмов, а в каком-нибудь нестабильном узком керриере вроде edge/3g/etc ты еще и поднасрешь себе качелями синтетических син-рст. Как все случится — одному б-гу известно, и знание, что «наверное может быть что-то возможно не так» не влияет на исход дела, кроме особых случаев (вроде рассылки супероперативной информации, когда ее отсутствие тоже информация). Поэтому нужно не загоняться и просто мутить асинхронку с сессионным протоколом, чтобы все занимались своими делами, не тратя время попусту.

В общем, да.

arturpub ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.