boost::asio::async_read liest, buffer.size() ist aber 0



  • Hi,

    ich versuche mit boost::asio vom socket zu lesen und verwende async read + deadline time. wenn ich boost::asio::async_read wie folgt aufrufe, ist der buffer immer 0. warum denn das?

    std::vector<char> TcpClient::read(boost::posix_time::time_duration timeout, unsigned int packet_length) {
    	// Set a deadline for the asynchronous operation. Since this function uses
    	// a composed operation (async_read_until), the deadline applies to the
    	// entire operation, rather than individual reads from the socket.
    	deadline_.expires_from_now(timeout);
    
    	// Set up the variable that receives the result of the asynchronous
    	// operation. The error code is set to would_block to signal that the
    	// operation is incomplete. Asio guarantees that its asynchronous
    	// operations will never fail with would_block, so any other value in
    	// ec indicates completion.
    	boost::system::error_code ec = boost::asio::error::would_block;
    	boost::system::error_code error;
    
    	std::vector<char> data;
    	boost::asio::async_read(socket_,boost::asio::buffer(data, packet_length),boost::asio::transfer_at_least(5), var(ec) = boost::lambda::_1); 
    
    	// Block until the asynchronous operation has completed.
    	do io_service_.run_one(); while (ec == boost::asio::error::would_block);
    
    	if (ec)
    		throw boost::system::system_error(ec);
    
    	std::cout << data.size() << std::endl;
    
    	return data;
    }
    


  • Boost.Asio vergrössrt hier den Buffer nicht automatisch. Du musst buffer schon noch gemäss der gewünschten Grösse anpassen.

    std::vector<char> data(packet_length);
    

    ➡

    boost::asio::async_read(socket_,boost::asio::buffer(data), ...
    

    Die Kondition kannst du dir dann aber sparen, da sowiso genau nur 5 Bytes gelesen werden (packet_length). Ansonsten musst du den Buffer grösser machen, dann werden mindestes 5 Bytes gelesen, können aber auch mehr sein, maximal aber soviele wie der Buffer gross ist.



  • hi,

    ok, ich dachte der boost::asio::buffer allokiert mir den speicher. da habe ich mich wohl verlesen...

    ich uebergebe nun die packet_length mit dem boost::asio::transfer_at_least, das sollte nun so passen.

    deadline_.expires_from_now(timeout);
    
    	// Set up the variable that receives the result of the asynchronous
    	// operation. The error code is set to would_block to signal that the
    	// operation is incomplete. Asio guarantees that its asynchronous
    	// operations will never fail with would_block, so any other value in
    	// ec indicates completion.
    	boost::system::error_code ec = boost::asio::error::would_block;
    	boost::system::error_code error;
    
    	std::vector<char> data(packet_length);
    	boost::asio::async_read(socket_, 
                                boost::asio::buffer(data, packet_length),
    							boost::asio::transfer_at_least(packet_length),						
                                var(ec) = boost::lambda::_1);
    
    	// Block until the asynchronous operation has completed.
    	do io_service_.run_one(); while (ec == boost::asio::error::would_block);
    
    	if (ec)
    		throw boost::system::system_error(ec);
    


  • Ja, ich denke das passt so..

    Allerdings ist, wie gesagt, die Kondition transfer_at_least(packet_length) ziemlich sinnlos, da der Buffer sowieso nur eine Grösse von packet_length hat - mehr als die Grösse des Buffers wird nicht gelesen. Wohin sollen den die Daten auch gespeichert werden?

    Ausserdem kannst du die Überladung boost::asio::buffer(data) anstelle von boost::asio::buffer(data, packet_length) benutzen. Es ist weniger zu schreiben, weniger fehleranfällig und vermutlich genau das was du ausdrücken willst.


Anmelden zum Antworten