Erlang: отправка по закрытому соединению - PullRequest
1 голос
/ 07 апреля 2011

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

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

1 Ответ

3 голосов
/ 09 апреля 2011

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

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

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

...