Асинхронная запись в сокет и пользовательские значения (вопрос boost :: asio) - PullRequest
2 голосов
/ 22 января 2010

Я довольно новый, чтобы повысить. Мне нужен был кроссплатформенный низкоуровневый сетевой API C ++, поэтому я выбрал asio. Теперь я успешно подключился и записал в сокет, но так как я использую асинхронное чтение / запись, мне нужен способ отслеживать запросы (чтобы иметь какие-то идентификаторы, если хотите). Я просмотрел документацию / ссылку и не нашел способа передать пользовательские данные своему обработчику. Единственный вариант, о котором я могу подумать, - это создать специальный класс, который действует как обратный вызов и отслеживает его идентификатор, а затем передает его к сокету в качестве обратного вызова. Есть ли способ лучше? Или это лучший способ сделать это?

1 Ответ

3 голосов
/ 22 января 2010

Функции async_xxx основаны на типе обработчика завершения. Обработчик не обязательно должен быть простым «обратным вызовом», и это может быть все, что предоставляет правильную сигнатуру оператора ().

Таким образом, вы должны быть в состоянии сделать что-то вроде этого:

// Warning: Not tested
struct MyReadHandler
{
    MyReadHandler(Whatever ContextInformation) : m_Context(ContextInformation){}

    void 
    operator()(const boost::system::error_code& error, std::size_t bytes_transferred)
    {
        // Use m_Context
        // ...            
    }

    Whatever m_Context;
};

boost::asio::async_read(socket, buffer, MyReadHander(the_context));

В качестве альтернативы, вы также можете использовать свой обработчик как простую функцию и связать его на сайте вызовов, как описано в asio tutorial . Пример выше будет тогда:

void 
HandleRead(
    const boost::system::error_code& error, 
    std::size_t bytes_transferred
    Whatever context
)
{
    //...
} 

boost::asio::async_read(socket, buffer, boost::bind(&HandleRead,
   boost::asio::placeholders::error_code,
   boost::asio::placeholders::bytes_transferred,
   the_context
));
...