2011-10-16 10 views
8

Recientemente he decidido utilizar boost::asio para mis sockets, pero ahora me encuentro con un problema: parece que falta documentación.Envío de datos brutos con write() en boost :: asio

Lo que quiero hacer es escribir una función que va a enviar un mensaje que consiste en la siguiente estructura:

  • 2 bytes de un entero sin signo (uint16_t) para un código de operación todos los bytes de
  • todos los bytes después que (una cantidad flexible) sea cualquier tipo de datos (emitidos a void*). Estos datos se va a operar basado en el código de operación

Por ejemplo, si el código de operación es 1, tal vez definida como OPCODE_LOGIN, entonces los bytes siguientes el código de operación podría contener una cadena que contiene información de acceso, etc.

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; 

}

Esto no compila, sin embargo. Me sale un error de compilación críptica sobre la convocatoria para escribir:

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 ========== 

Como se puede ver, el mensaje de error apunte directamente al archivo de Boost write.hpp, y no a cualquiera de mi propio código .. Creo que estoy llamando write() incorrectamente de alguna manera, pero después de una hora sólida de buscar en Google e investigar referencias y ejemplos (todos los cuales utilizan otro write() sobrecargado o están utilizando datos con tamaños/estructuras específicamente definidos), no he podido determinar exactamente qué Estoy haciendo mal aquí.

¿Alguien me puede ayudar a solucionar este error de compilación?

Respuesta

14

documentación que parece faltar

El highest voted question en se trata de documentación, a empezar por ahí :-)

Puede alguien ayudarme a depurar este error de compilación?

La write() función libre expects un tipo de referencia como primer parámetro. No es un puntero que usted tiene en su ejemplo

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; 
} 

en este punto, es seguro eliminar fullData para evitar pérdidas de memoria?

Sí, write() is a la llamada de bloqueo. Se hace con tu buffer cuando la llamada retorna. Recomiendo encarecidamente que este código de excepción sea seguro; sin embargo, analice el uso de new y boost::scoped_array si desea crear su búfer con la duración de almacenamiento dinámico.

+0

Eso funcionó muy bien, gracias! :) Y vi la "pregunta más votada" muchas veces en Google, y seguí sus consejos, pero no fue de mucha utilidad ... los ejemplos usaron diferentes versiones sobrecargadas de write(), la referencia de clase construida sobre muchos impulsores secuencias con las que no estoy familiarizado, etc. – Josh1billion

Cuestiones relacionadas