Linux: отправить целое сообщение или ничего из этого на TCP-сокет - PullRequest
3 голосов
/ 08 марта 2012

Я отправляю различные пользовательские структуры сообщений по неблокирующему TCP-сокету.Я хочу отправить всю структуру за один вызов send () или вернуть ошибку без отправки байтов, если в буфере отправки есть место только для части сообщения (т. Е. Send () возвращает EWOULDBLOCK).Если места недостаточно, я отброшу всю структуру и сообщу о переполнении, но после этого я хочу восстановить, то есть получатель только когда-либо получит последовательность действительных завершенных структур.Есть ли способ либо проверить свободное место в буфере отправки, либо сказать, что вызов send () делает, как описано?Основанные на дейтаграмме сокеты не являются опцией, должны быть основаны на соединении TCP.Спасибо.

Ответы [ 2 ]

1 голос
/ 08 марта 2012

Linux предоставляет SIOCOUTQ ioctl () для запроса количества данных в выходном буфере TCP:

http://www.kernel.org/doc/man-pages/online/pages/man7/tcp.7.html

Вы можете использовать это, плюс значение SO_SNDBUF, чтобы определить, достаточно ли в исходящем буфере места для какого-либо конкретного сообщения.Строго говоря, ответ на ваш вопрос «да».

Но с этим подходом есть две проблемы.Во-первых, это специфично для Linux.Во-вторых, что вы планируете делать, когда недостаточно места для отправки всего вашего сообщения?Цикл и снова позвоните select?Но это просто скажет вам, что сокет снова готов к записи, что приведет к циклу занятости.

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

1 голос
/ 08 марта 2012

TCP не поддерживает транзакции; это то, что вы должны обработать на слое 7 (приложение).

...