简体   繁体   English

Boost Asio收到损坏的消息

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM