Erlang: отправка по закрытому соединению

Если клиент подключается к серверу через обычное TCP-соединение, а затем соединение клиента обрывается, сервер получит (при активном режиме) {tcp_closed,Socket}. Но бывают случаи, когда сервер не будет знать, что клиент отключился, например, сбой питания или сбой и тому подобное (думаю, я могу ошибаться). В этих случаях клиент отсутствует, но сервер все еще считает, что он подключен. Если сервер попытается отправить клиенту сообщение в этих случаях, будет ли он считать, что клиент получил сообщение, или стек tcp сортирует это на низком уровне, и сервер возвращает какую-то ошибку?

Я знаю, что это упрощенный вопрос, но у меня возникли проблемы с его тестированием, так как я не могу заставить клиента катастрофически выйти из строя, как мне нужно (даже kill -9 этого не делает). У кого-нибудь есть опыт в этом?


person Mediocre Gopher    schedule 07.04.2011    source источник
comment
TCP будет знать, что сообщение не было доставлено, но поймет ли Erlang его или нет — это другой вопрос. Вы пытались отключить кабель Ethernet клиента? Это довольно малоэффективно и легко проверяется.   -  person nmichaels    schedule 07.04.2011
comment
Я использую только свою машину для тестирования с помощью localhost, в данный момент у меня нет доступа к другой машине.   -  person Mediocre Gopher    schedule 07.04.2011
comment
Ах, не весело... Я думаю, вы могли бы использовать виртуальную машину, но это намного больше работы, чем спрашивать на SO.   -  person nmichaels    schedule 07.04.2011


Ответы (1)


Ответ зависит. Когда вы пытаетесь отправить данные, окно TCP ядра будет медленно заполняться, пока не перестанет принимать данные. Тогда ваша отправка будет заблокирована, потому что внутренний буфер ядра заполнен. TCP имеет несколько таймеров, которые срабатывают через некоторое время. Когда это произойдет, ядро ​​выдаст ошибку в запросе на отправку, среда выполнения Erlangs VM преобразует его в {error, Reason}, где Reason — это сообщение об ошибке posix() от базовой системы.

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

Чтобы проверить это, вы можете заблокировать связь с помощью правила брандмауэра на lo.

person I GIVE CRAP ANSWERS    schedule 09.04.2011