допустимо ли асинхронно отправлять данные до того, как был вызван обработчик завершения предыдущего?

#c #sockets #boost #boost-asio #asyncsocket

#c #сокеты #повышение #boost-asio #asyncsocket

Вопрос:

Я отправляю данные асинхронно в сокет TCP. Допустимо ли отправлять следующий фрагмент данных до того, как предыдущий был отправлен обработчиком завершения?

Насколько я знаю, это недопустимо, когда отправка выполняется из разных потоков. В моем случае все отправки выполняются из одного потока.

Разные модули моего клиента отправляют данные в один и тот же сокет. Например. module1 отправил некоторые данные и продолжит работу при вызове соответствующего обработчика завершения. Перед этим io_service был вызван deadline_timer обработчик module2, который приводит к другому async_write вызову. Должен ли я ожидать каких-либо проблем здесь?

Комментарии:

1. Сокеты TCP не отправляют пакеты, они отправляют потоки данных. Я уточнил название вашего вопроса.

2. спасибо. В общем, я не могу согласиться, TCP-сокеты по-прежнему отправляют пакеты, как и любые другие сокеты. Интерфейс TCP предназначен для представления этого в виде потока, но это всего лишь абстракция, предоставляющая больше свободы для алгоритмов стека TCP.

Ответ №1:

Допустимо ли отправлять следующий фрагмент данных до того, как предыдущий был отправлен обработчиком завершения?

Нет, недопустимо чередовать операции записи. Это очень ясно в документации

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

выделение добавлено мной.

Насколько я знаю, это недопустимо, когда отправка выполняется из разных потоков. В моем случае все отправки выполняются из одного потока.

Ваша проблема не имеет ничего общего с потоками.

Комментарии:

1. как насчет async_send? Это не упоминается в документации. boost.org/doc/libs/1_37_0/doc/html/boost_asio/reference /…

Ответ №2:

Да, вы можете это сделать, если базовая память (буфер) не будет изменена до тех пор, пока не будет вызван обработчик записи. Вызов async_write означает, что вы передаете право собственности на буфер Asio. При вызове обработчика записи вам возвращается право собственности на буфер.

Комментарии:

1. Я не думаю, что это точно, как вы гарантируете, что записи не чередуются?

2. @SamMiller: они выполняются из нескольких потоков. Я не ожидаю, что это произойдет, когда записи и io_service::run() выполняются в одном потоке, поскольку задачи помещаются в очередь и выполняются в порядке FIFO (по крайней мере, я так думаю).