[Moscow.pm] Perl Sockets: определить флаги tcp

Геннадий Евгеньевич g3nd0s на gmail.com
Чт Июл 4 05:19:02 PDT 2013


У меня частный случай, который решил отдельный pid снимающий дамп,
getsockopt и книжка Стивенса как советовали мне не помогли

4 июля 2013 г., 12:02 пользователь Anton Yuzhaninov <citrin на citrin.ru>написал:

> On 06/28/13 16:26, Геннадий Евгеньевич wrote:
>
>> Есть приложение типа cliet-server, между ними бегают туда-сюда пакеты по
>> протоколу SMPP, в ходе работы возникает ситуация, когда серверная сторона
>> шлет
>> tcp с флагами FIN+ACK, но т.к. я работаю с SMPP/perlsockets на уровень
>> выше, я
>> об этом не знаю, и пока сокет не закроется, моя клиентская часть по
>> прежнему
>> продолжает слать SMPP пакеты, что является не правильно.
>>
>
> 1. А почему собственно не правильно? В tcp есть возможность закрыть
> соединение на-половину (half-close). Т. е. просто отправка сервером fin+ack
> означает, что сервер не будет больше передавать данные, но при этом может
> их принимать.
>
> В нормально спроектированных протоколах, закрытие соединения при штатной
> работе происходит не в произвольные моменты времени, а когда это положен по
> протоколу - например в SMTP после команды QUIT. Поэтому в нормальном
> протоколе нет необходимости узнавать отдельно, что сервер закрыл коннекцию
> (послал FIN) - он это делает тогда, когда клиент этого ожидает (например
> сам об этом попросил).
>
> В случае какого то сбоя (падения канала, процесса на удаленной стороне и
> т. п.) следующий wirte() вернёт ошибку, и надо будет закрыть соединение и
> попытаться переключиться.
>
> 2. Вопреки распространенному заблуждения про TCP, если syscall write()
> отработал без ошибки, это еще не означает что все данные получены
> приложением на удаленной стороне. Единственно что это означает, что ядро ОС
> приняло данные от приложение (поместил их в свой буфер) и дальше будет
> пытаться их отправить до тех пор, пока на истечет retransmit timeout или от
> удаленной стороны не придет RST. Причин по которым данные могут потеряться
> после того, как write отработал без ошибки может было множество: где то
> посередине между хостами сломался канал на длительное время, удаленный
> сервер внезапно перезагрузился или завис, процесс на удаленном сервер умер
> по сигналу...
>
> И заблуждение это настолько распространенное, что так думают не только
> рядовые кодеры, но и некоторые разработчики протоколов (например в базовом
> стандарте XMPP таких подтверждений не предусмотрено, и они появились в
> одном из XEP, и поддерживаются AFAIK не везде).
>
> Т. е. если нужна гарантированная доставка сообщений, то должно быть
> подтверждение на уровне прикладного протокола.
>
> Пример того как это сделано в SMTP - клиент ждет после точки ответа 250 от
> сервера. Если 250 не было, клиент считает что сообщение не отправлено и
> через некоторое время пытается отправить повторно. В свою очередь сервер
> отвечает 250 только после того как записал сообщение в очередь.
>
> Если таких подтверждений в прикладном нет (или сервер реализует протокол
> неправильно), то сообщения иногда будут теряться, все что возможно сделать
> это без переделки протокола - это немножко снизить вероятность потери.
>
> Если вы не хотите слать данные после отправки сервером FIN, потому что
> сообщение в этом случае будет потеряно и способа об этом узнать, то это уже
> достаточно плохо.
>
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>



-- 
--
С уважением Геннадий Евгеньевич
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20130704/40ef64f2/attachment-0001.html>


Подробная информация о списке рассылки Moscow-pm