TCP клиент-сервер SIGPIPE - PullRequest
       26

TCP клиент-сервер SIGPIPE

3 голосов
/ 04 марта 2011

Я разрабатываю и тестирую клиент-серверную программу на основе TCP-сокетов (интернет-домен). В настоящее время я тестирую его на локальном компьютере и не могу понять следующее о SIGPIPE.

*. SIGPIPE появляется довольно случайно. Это может быть детерминированным?

Первые тесты включали одну маленькую (25 символов) операцию отправки с клиента и соответствующий прием на сервере. Тот же код на той же машине работает успешно или нет (SIGPIPE) полностью вне моего контроля. Частота отказов составляет около 45% случаев (довольно высокий). Итак, могу ли я настроить машину любым способом, чтобы минимизировать это.

**. Второй этап тестирования заключался в отправке 40000 небольших (25 символов) сообщений от клиента на сервер (1 МБ общих данных), а затем сервер отвечал общим объемом фактически полученных данных. Клиент отправляет данные в узком цикле, и на сервере происходит ОДИН приемный вызов. Он работает только для максимум 1200 байтов от общего количества отправленных данных, и опять же, есть эти недетерминированные SIGPIPE, примерно в 70% раз (очень плохо).

Может кто-нибудь предложить какое-то улучшение моего дизайна (возможно, это будет на сервере). Требование заключается в том, что клиент должен иметь возможность отправлять от среднего до очень большого количества данных (опять же около 25 символов в каждом сообщении) после того, как соединение с одним сокетом было установлено на сервер. У меня такое ощущение, что множественные посылки против одного приема всегда будут с потерями и очень неэффективными. Должны ли мы объединять сообщения и отправлять только одну операцию send (). Это единственный путь?

Ответы [ 2 ]

7 голосов
/ 04 марта 2011

SIGPIPE отправляется при попытке записи в неподключенный канал / сокет.Установка обработчика для сигнала заставит send () возвращать ошибку.

signal(SIGPIPE, SIG_IGN);

Кроме того, вы можете отключить SIGPIPE для сокета:

int n = 1;
setsockopt(thesocket, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof(n));

Кроме того, объем данныхУпоминаешь не очень высокие.Вероятно, где-то есть ошибка, из-за которой ваше соединение неожиданно закрывается, давая SIGPIPE.

1 голос
/ 27 января 2015

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

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

В редких случаях, когда вы не можете избежать этого, вы можете замаскировать сигнал при отправке.Если вы установите флаг MSG_NOSIGNAL на send() / sendto(), это предотвратит повышение SIGPIPE.Если вы запустите эту ошибку, send() вернет -1, а errno будет установлено на EPIPE.Чисто и просто.Подробнее см. man send.

...