简体   繁体   中英

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. I am sending strings of 50.000 characters. 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 . But, when you call async_write , your buffer is constructed from pointer taken from msg , not m_messageQueue . So eventually you can send from incorrent buffer.

2) On receive you creating receiveBuffer on stack. When async_read_some immediatelly returns (almost always), your receiveBuffer will be destroyed because you exit from StartReceiving call.

3) Same with sendBuffer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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