Отправка необработанных данных с помощью write () в boost :: asio - PullRequest
8 голосов
/ 16 октября 2011

Я недавно решил использовать boost::asio для своих сокетов, но теперь я столкнулся с проблемой: кажется, что документации не хватает.

Я хочу написать функцию, которая будет отправлять сообщение, состоящее из следующей структуры:

  • 2 байта целого числа без знака (uint16_t) для кода операции все байты
  • все байты после этого (гибкое количество), являющиеся данными любого типа (приведенные к void*). Эти данные будут обрабатываться на основе кода операции

Например, если код операции равен 1, возможно, определен как OPCODE_LOGIN, то байты, следующие за кодом операции, могут содержать строку, содержащую информацию для входа и т. Д.

bool sendMessage(tcp::socket* sock, uint16_t opcode, void* data)
{
    void* fullData = malloc(sizeof(uint16_t) + sizeof(data));
    memcpy(fullData, (void*)opcode, sizeof(opcode));
    memcpy(&fullData + sizeof(uint16_t), data, sizeof(data));
    boost::asio::write(sock, boost::asio::buffer(fullData, sizeof(fullData)));
    // by the way, at this point, is it safe to delete fullData to prevent memory leaks?
    return true;

}

Однако это не компилируется. Я получаю загадочную ошибку компиляции относительно звонка, чтобы написать:

1>------ Build started: Project: client, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\boost\boost_1_47\boost\asio\impl\write.hpp(46): error C2228: left of '.write_some' must have class/struct/union
1>          type is 'boost::asio::basic_stream_socket<Protocol> '
1>          with
1>          [
1>              Protocol=boost::asio::ip::tcp
1>          ]
1>          did you intend to use '->' instead?
1>          c:\boost\boost_1_47\boost\asio\impl\write.hpp(59) : see reference to function template instantiation 'size_t boost::asio::write<SyncWriteStream,ConstBufferSequence,boost::asio::detail::transfer_all_t>(SyncWriteStream &,const ConstBufferSequence &,CompletionCondition,boost::system::error_code &)' being compiled
1>          with
1>          [
1>              SyncWriteStream=boost::asio::ip::tcp::socket *,
1>              ConstBufferSequence=boost::asio::mutable_buffers_1,
1>              CompletionCondition=boost::asio::detail::transfer_all_t
1>          ]
1>          c:\users\josh\documents\visual studio 2010\projects\client\client\main.cpp(53) : see reference to function template instantiation 'size_t boost::asio::write<boost::asio::ip::tcp::socket*,boost::asio::mutable_buffers_    1>(SyncWriteStream &,const ConstBufferSequence &)' being compiled
1>          with
1>          [
1>              SyncWriteStream=boost::asio::ip::tcp::socket *,
1>              ConstBufferSequence=boost::asio::mutable_buffers_1
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Как вы можете видеть, сообщение об ошибке указывает прямо в файл Boost write.hpp, а не на какой-либо мой собственный код. Я полагаю, что я каким-то образом неправильно вызываю write(), но через час Поиск и изучение ссылок и примеров (все из которых используют другой перегруженный write() или используют данные с определенными размерами / структурами), я не смог определить, что именно я делаю здесь неправильно.

Может кто-нибудь помочь мне отладить эту ошибку компиляции?

1 Ответ

14 голосов
/ 16 октября 2011

документация отсутствует

вопрос с наибольшим количеством голосов в о документации, начните там: -)

Может кто-нибудь помочь мне отладить эту ошибку компиляции?

Свободная функция write() ожидает ссылочный тип в качестве первого параметра. Не указатель, как в вашем примере

bool sendMessage(tcp::socket* sock, uint16_t opcode, void* data)
{
    void* fullData = malloc(sizeof(uint16_t) + sizeof(data));
    memcpy(fullData, (void*)opcode, sizeof(opcode));
    memcpy(&fullData + sizeof(uint16_t), data, sizeof(data));
    boost::asio::write(*sock, boost::asio::buffer(fullData, sizeof(fullData)));
    //                 ^^^^ correct type now
    // by the way, at this point, is it safe to delete fullData to prevent memory leaks?
    return true;
}

На данный момент безопасно ли удалять fullData для предотвращения утечек памяти?

Да, write() is блокирующий вызов. Это делается с вашим буфером, когда вызов возвращается. Однако я настоятельно рекомендую сделать это исключение из кода безопасным. Если вы хотите создать буфер с динамической продолжительностью хранения, изучите использование new и boost::scoped_array.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...