#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 (по крайней мере, я так думаю).