[英]Boost asio receive corrupt message
I am made a Server & Client Asynchronous Application. 我做了一个服务器和客户端异步应用程序。 All works perfectly except the message I receive.
除我收到的消息外,所有其他方法均正常运行。 I am sending image pieces into strings.
我正在将图像片段发送到字符串中。 But when I receive them back, the string is corrupted, I that it's not the same as I send.
但是,当我收到它们时,该字符串已损坏,这与发送的字符串不同。 The length it's the same, and almost all characters.
长度相同,几乎所有字符。 If I compare what I send with what I received I have like 300 characters different from what I sent.
如果将发送的内容与接收的内容进行比较,我会发现与发送的字符有300个不同的字符。 I am sending strings of 50.000 characters.
我正在发送50.000个字符的字符串。 Any idea what may be the problem?
知道可能是什么问题吗? The most of the code are comments, so you will understand it in seconds.
大部分代码是注释,因此您将在几秒钟内理解它。 Also, I shrinked it and made it easier for you to read.
另外,我缩小了它的大小,以使您更容易阅读。
I am sending with this. 我正在发送。
// Send a message
void StartSendMessage ( MessagePtr msg )
{
// As long as the queue is not empty, the 'sending agent' is still alive
bool writeInProgress =! m_messageQueue.empty() ;
// Queue the message
m_messageQueue.push ( msg ) ;
if ( msg -> BodyLength() != 0 )
{
std:: cout << "Sending :" << msg -> BodyLength() << std:: endl ;
}
// If the 'sending agent' is inactive, start it
if ( !writeInProgress )
{
// Send message asynchronously. We leave the message on the queue
// since it needs to be available during the async read
async_write ( m_socket , boost::asio::buffer ( msg -> HeaderData() , msg -> SendLength () ) ,
boost::bind ( &ASyncConnectionMT::HandleSentMessage , this , boost::asio::placeholders::error , boost::asio::placeholders::bytes_transferred ) ) ;
}
}
// Message was sent
void HandleSentMessage ( const boost::system::error_code& ec , size_t size )
{
// Check the error code
if ( ec )
{
// Transfer error
std:: cout << "Error sending message: " << ec.message() << std:: endl ;
DoStop() ;
return ;
}
// Remove the sent message from queue
m_messageQueue.pop() ;
// If the que is not empty, send next message asynchronously.
// We leave the message on the que since it needs to be available during the async send
if ( !m_messageQueue.empty() )
{
MessagePtr msg = m_messageQueue.front() ;
std:: cout << "Message send lenght "<< msg->SendLength() ;
async_write ( m_socket , boost::asio::buffer ( msg -> HeaderData() , msg -> SendLength () ) ,
boost::bind ( &ASyncConnectionMT:: HandleSentMessage , this , boost::asio::placeholders::error , boost::asio::placeholders::bytes_transferred ) ) ;
}
}
I am reading with this. 我正在阅读。
void StartReceiving()
{
// Create receive buffer
BufferPtr receiveBuffer ( new Buffer ) ;
// Start async read, must pass 'this' as shared_ptr, else the
// 'this' object will be destroyed after leaving this function
m_socket.async_read_some ( boost::asio::buffer ( *receiveBuffer ) , boost::bind ( &ASyncConnectionMT::HandleReceivedd , shared_from_this() , receiveBuffer ,
boost::asio::placeholders::error , boost::asio::placeholders::bytes_transferred ) );
}
// Handle received data
void HandleReceivedd ( BufferPtr receiveBuffer , const boost::system::error_code& ec , size_t size)
{
if ( !ec )
{
BufferPtr sendBuffer ( new Buffer ) ;
std:: cout << m_socket.remote_endpoint() << ": Message received: " << std:: string (receiveBuffer -> data() , size ) << std:: endl << std:: endl;
std:: cout << "Message lenght received " << size << std:: endl;
// Start receiving next bit
StartReceiving() ;
}
else if ( ec == boost::asio::error::eof)
{
// Client disconnected. Close the socket.
std:: cout << m_socket.remote_endpoint() << ": Connection closed ( handle received )" << std:: endl;
m_socket.close();
}
}
I see several problems in this chunk of code: 我在这段代码中看到了几个问题:
1) When you send, you are putting copy of msg
into m_messageQueue
. 1)发送时,您要将
msg
副本放入m_messageQueue
。 But, when you call async_write
, your buffer is constructed from pointer taken from msg
, not m_messageQueue
. 但是,当您调用
async_write
,缓冲区是从msg
而不是m_messageQueue
获取的指针m_messageQueue
。 So eventually you can send from incorrent buffer. 因此最终您可以从不适当的缓冲区发送。
2) On receive you creating receiveBuffer
on stack. 2)在接收时,您在堆栈上创建了
receiveBuffer
。 When async_read_some
immediatelly returns (almost always), your receiveBuffer
will be destroyed because you exit from StartReceiving
call. 当
async_read_some
立即返回(几乎总是)时,由于您退出StartReceiving
调用,所以receiveBuffer
将被破坏。
3) Same with sendBuffer
3)与
sendBuffer
相同
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.