2011-02-08 19 views
6

Ho un server che riceve una stringa compressa (compresso con zlib) da un client e stavo usando async_receive dalla libreria boost::asio per ricevere questa stringa, risulta comunque che non è garantito che tutti i byte saranno ricevuti, quindi ora devo cambiarlo in async_read. Il problema che devo affrontare è che la dimensione dei byte ricevuti è variabile, quindi non sono sicuro di come usare async_read senza conoscere il numero di byte da ricevere. Con il async_receive ho solo un boost::array<char, 1024>, tuttavia questo è un buffer che non è necessariamente riempito completamente.boost :: asio async_read garantisce che tutti i byte siano letti

Mi chiedevo se qualcuno può suggerire una soluzione in cui posso usare async_read anche se non conosco il numero di byte da ricevere in anticipo?

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 è un boost::array<char, 1024>

risposta

19

Come ti aspettavi di farlo utilizzando un altro metodo?

Ci sono alcuni metodi generali per l'invio dei dati di dimensioni variabili in un maniero asincrona:

  1. Per messaggio - il che significa che si ha un colpo di testa che definisce la lunghezza del messaggio atteso seguito da un corpo che contiene dati della lunghezza specificata.
  2. Per flusso - significa che si dispone di un metodo di indicatore (e questo è molto ampio) per sapere quando si è ottenuto un pacchetto completo.
  3. Per connessione: ogni pacchetto completo di dati viene inviato in una singola connessione che viene chiusa una volta che i dati sono completi.

così può vostri dati essere analizzato, o di una lunghezza inviato ecc ...

+4

+1 bel riassunto di alcune soluzioni possibili –

2

Usa async_read_until e creare il proprio match condition, o modificare il protocollo per inviare un colpo di testa compreso il numero di byte da aspettarsi nella stringa compressa.

0

un singolo pacchetto IP è limitata ad una dimensione MTU di ~ 1500 byte, e ancora è possibile scaricare i file gigabyte-large dal tuo sito Web preferito e guarda video di dimensioni megabyte su YouTube.

È necessario inviare un'intestazione che indica la dimensione effettiva dei dati non elaborati e quindi ricevere i dati per pezzi su blocchi più piccoli fino a quando non si ricevono tutti i byte.

Ad esempio, quando si scarica un file di grandi dimensioni su HTTP, v'è un campo sul titolo che indica la dimensione del file: Content-Length:.