Выполнение асинхронных операций записи через сокет TCP с помощью Boost Asio - PullRequest
0 голосов
/ 10 марта 2012

Я пишу клиент-серверное приложение на C ++ с помощью Boost Asio.У меня есть работающий сервер, и рабочий процесс на сервере - это то, что я хорошо понимаю.

Мое клиентское приложение корректно обрабатывает соединение, как показано в примерах Asio, после чего оно обменивается рукопожатием с сервером.Однако после этого пользователи должны иметь возможность отправлять запросы на сервер, когда и как они хотят, и именно здесь у меня возникает проблема с пониманием парадигмы.

Первоначальный рабочий процесс выглядит примерно так:

OnConnected() { SendHandshake() }
SendHandshake() { async.write_some(handshake...), async_read_some(&OnRead) }
OnRead() { ReadServerHandshake() *** }

И пользователи будут отправлять сообщения, используя Запись (msg):

Write (msg) { async_write_some(msg,&OnWrite), async_Read_some(&OnRead) }
OnWrite() {} 

РЕДАКТИРОВАТЬ: Перефразируя вопрос, чтобы быть более ясным, вот сценарий:

После завершения первоначального рукопожатия Клиент используется только для отправки запросов на сервер, на который он получит ответ.Так, например, пользователь отправляет запись.Клиент ожидает завершения операции чтения, читает ответ и что-то делает с ним.Следующая запись пользователя появится, скажем, через 5 минут.Не прекратит ли в это время работу io_service, поскольку между последним чтением ответа и следующей записью нет ожидающих асинхронных операций?

Ответы [ 2 ]

0 голосов
/ 10 марта 2012

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

0 голосов
/ 10 марта 2012

В информативной заметке вы можете предоставить ей io_service :: work , чтобы остановить io_service бездействия.Это гарантирует, что io_service::run никогда не вернется, пока рабочий объект не будет уничтожен.Чтобы управлять временем жизни рабочего объекта, вы можете использовать указатель shared_ptr и сбросить его после завершения работы, или вы можете использовать boost::optional, как указано здесь .

OfКонечно, вам все еще нужно разобраться со случаем, когда либо сервер закрывает TCP-соединение, либо соединение по какой-либо причине умирает.Чтобы справиться с этим случаем, одним из решений было бы иметь выдающийся async_read на сокете к серверу.Обработчик чтения должен вызываться с error_code, когда / если что-то не так с соединением.Если у вас есть непрочитанное чтение по соединению, вам не нужно использовать рабочий объект.

...