2011-02-08 37 views
6

Tengo un servidor que recibe una cadena comprimida (comprimida con zlib) de un cliente, y estaba usando async_receive de la biblioteca boost::asio para recibir esta cadena, pero resulta que no hay garantía de que se recibirán todos los bytes, así que ahora tengo que cambiarlo a async_read. El problema al que me enfrento es que el tamaño de los bytes recibidos es variable, por lo que no estoy seguro de cómo usar async_read sin saber la cantidad de bytes que se recibirán. Con el async_receive solo tengo un boost::array<char, 1024>, sin embargo, este es un buffer que no necesariamente se llena por completo.boost :: asio async_read garantizan que se leen todos los bytes

Me pregunto si alguien puede sugerir una solución donde puedo usar async_read aunque no sé la cantidad de bytes que se recibirán por adelantado?

void tcp_connection::start(boost::shared_ptr<ResolverQueueHandler> queue_handler) 
{ 
    if (!_queue_handler.get()) 
     _queue_handler = queue_handler; 

    std::fill(buff.begin(), buff.end(), 0); 

    //socket_.async_receive(boost::asio::buffer(buff), boost::bind(&tcp_connection::handle_read, shared_from_this(), boost::asio::placeholders::error)); 
    boost::asio::async_read(socket_, boost::asio::buffer(buff), boost::bind(&tcp_connection::handle_read, shared_from_this(), boost::asio::placeholders::error)); 
} 

buff es una boost::array<char, 1024>

Respuesta

19

¿Cómo esperabas hacer esto usando cualquier otro método?

Hay algunos métodos generales para el envío de datos de tamaño variable en una mansión asíncrono:

  1. Por mensaje - lo que significa que usted tiene un encabezado que define la longitud del mensaje esperado seguido de un cuerpo que contiene datos de la longitud especificada.
  2. Por transmisión, lo que significa que tiene algún método de marcador (y esto es muy amplio) para saber cuándo ha recibido un paquete completo.
  3. Por conexión: cada paquete completo de datos se envía en una única conexión que se cierra una vez que se completan los datos.

Así se puede analizar sus datos, o una longitud envió etc ...

+4

+1 buen resumen de algunas soluciones posibles –

2

Uso async_read_until y crear su propia match condition, o cambiar su protocolo para enviar una cabecera que incluye el número de bytes que puede esperar en la cadena comprimida.

0

Un paquete IP solo se limita a un tamaño de MTU de 1500 bytes ~, y aún así se puede descargar archivos de gran gigabyte desde su sitio web favorito, y vea videos del tamaño de megabytes en YouTube.

Debe enviar un encabezado que indique el tamaño real de los datos brutos, y luego recibir los datos por piezas en trozos más pequeños hasta que termine de recibir todos los bytes.

Por ejemplo, cuando descarga un archivo grande a través de HTTP, hay un campo en el encabezado que indica el tamaño del archivo: Content-Length:.

Cuestiones relacionadas