asio::ip::tcp iostream wrong byte count read for last packet
I just started out with Boost and was writing a little binary file transfer app and ran into a little problem, so I would appreciate if someone could kindly point out what I am doing wrong here. My problem is in getting the correct byte count read in the final packet received. My last frame always returns the size of the buffer, not the number of bytes read into the buffer. Isn't iostream::gcount(() meant for this? If not, what is the correct 'Boost' way of doing this? int spool_binary_data() { boost::asio::ip::tcp::endpoint dataServerEndpoint(boost::asio::ip::tcp::v4(), PMMS_TRANSFER_PORT_NUMBER); boost::asio::ip::tcp::acceptor acceptor(dataServer, dataServerEndpoint); boost::asio::ip::tcp::iostream dataServerStream; acceptor.accept(*dataServerStream.rdbuf()); char buffer[2048]; std::streamsize nbytes = sizeof(buffer); FILE * pFile = fopen ("binary.out","w"); // count = getavailable(this->native_socket) ?? // stream->rdbuf()->available() ?? while ( dataServerStream.read((char*)&buffer, nbytes) ) { int bytes_read = dataServerStream.gcount(); // always 2048 std::cout << "bytes read " << bytes_read << std::endl; fwrite(buffer,1,bytes_read,pFile); } dataServerStream.close(); fclose(pFile); }
On 9/08/2014 04:58, Steve Coleman wrote:
My problem is in getting the correct byte count read in the final packet received. My last frame always returns the size of the buffer, not the number of bytes read into the buffer. Isn't iostream::gcount(() meant for this? If not, what is the correct 'Boost' way of doing this?
"read" returns the number of bytes actually read. Use that. (If you later switch to doing an async read, then it is one of the parameters that can be passed to the callback function.) Depending on what you're reading, you may also want to use one of the read* free functions to guarantee reading exactly or at least a specified number of bytes, or up to a specified delimiter.
On 08/10/14 18:50, Gavin Lambert wrote:
On 9/08/2014 04:58, Steve Coleman wrote:
My problem is in getting the correct byte count read in the final packet received. My last frame always returns the size of the buffer, not the number of bytes read into the buffer. Isn't iostream::gcount(() meant for this? If not, what is the correct 'Boost' way of doing this?
"read" returns the number of bytes actually read. Use that.
I must be missing something here from your explanation. If I try to receive a return from this iostream.read() I get a syntax error. e.g. int bytes_read; boost::asio::ip::tcp::iostream dataServerStream; while ( bytes_read = dataServerStream.read((char*)&buffer, nbytes) ) pmms_server.cpp:379:21: error: invalid user-defined conversion from 'std::basic_istream<char>::__istream_type {aka std::basic_istream<char>}' to 'int' [-fpermissive] Is there a different object.read() function you are talking about? Or a specific data type to declare for the return value type?
(If you later switch to doing an async read, then it is one of the parameters that can be passed to the callback function.)
Depending on what you're reading, you may also want to use one of the read* free functions to guarantee reading exactly or at least a specified number of bytes, or up to a specified delimiter.
btw - I want a synchronous read of a binary data stream.
On 12/08/2014 02:00, Steve Coleman wrote:
On 08/10/14 18:50, Gavin Lambert wrote:
"read" returns the number of bytes actually read. Use that.
I must be missing something here from your explanation. If I try to receive a return from this iostream.read() I get a syntax error. [...] Is there a different object.read() function you are talking about? Or a specific data type to declare for the return value type?
My apologies; I was thinking of .read_some() on the socket itself, or the read() free function. I rarely-to-never use iostreams.
btw - I want a synchronous read of a binary data stream.
Then I would suggest not using an iostream, and instead using one of the above. Input streams in particular gloss over quite a bit and in my opinion it's a terrible idea to use them for binary data, for much the same reason you wouldn't use scanf.
participants (2)
-
Gavin Lambert
-
Steve Coleman