Very interesting problem with TCP sockets
Hi guys, I was trying to connect Qt TCP Socket with Boost Asio TCP socket. And what I found. Qt writes simple 12 bytes message to the Boost and in most situations Boost reads garbage. Even more Boost can crash. And my question is: who is so bad guy, Boost or Qt? You can find simple implementation of the problem in the attachment. Thanks. P.S. Problem is on Windows 7, on Linux or Mac OS I have no possibility to test...
Hi Igor,
2014-09-01 16:55 GMT+10:00 Igor Mironchik
And my question is: who is so bad guy, Boost or Qt?
I'm going to go out on a limb here and guess that the "bad guy" is neither Boost nor Qt, but rather your own code. Sure enough, having a look at your server code I can see at least two problems: void Socket::start( std::shared_ptr< Socket > socket ) { std::cout << "Socket::start" << std::endl; char buf[ msgSize ]; boost::asio::async_read( m_socket, boost::asio::buffer( buf, msgSize ), [ this, socket, &buf ] ( boost::system::error_code error, std::size_t ) { if( error ) m_server->disconnection( socket ); else { if( std::strncmp( buf, msg, msgSize ) != 0 ) { std::cout << "Message is WRONG" << std::endl; m_server->disconnection( socket ); } else if( m_socket.is_open() ) { std::cout << "Message is OK" << std::endl; start( socket ); } } } ); } Firstly, buf is located on the stack, meaning it will go out of scope as soon as Socket::start() returns. As you are using async_read() this will happen immediately. Secondly, you are ignoring the bytes_transferred parameter in your read handler. This is the size_t parameter after error_code. There is no guarantee that the buffer will be filled each time your read handler is called, so you need to check this value to see how many bytes were actually read into your buffer, otherwise you may encounter garbage bytes at the end. As boost and Qt are both heavily used and very mature libraries, you will make better progress initially if you take the frame of mind that any problems you encounter are caused by your own code (unless you are _really_ unfortunate!) Hope that helps. Alex
Thank you Alex,
I agree with you, and so bad guy is me :)
Is it absolutely the truth that async_read() can invoke handler if there is less data received then defined in buffer?
May be async_read() will invoke handler only when full buffer will filled?
What the Boost documentation say on it:
The read operation may not read all of the requested number of bytes. Consider using the async_read function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.
From: Alex MDC
Sent: Tuesday, September 02, 2014 6:42 AM
To: boost-users@lists.boost.org
Subject: Re: [Boost-users] Very interesting problem with TCP sockets
Hi Igor,
2014-09-01 16:55 GMT+10:00 Igor Mironchik
participants (2)
-
Alex MDC
-
Igor Mironchik