提升asio收到损坏的消息

时间:2015-02-25 15:55:11

标签: c++ asynchronous boost boost-asio

我成了服务器&客户端异步应用程序。除了我收到的信息外,一切都很完美。我正在将图像片段发送到字符串中。但当我收到它们时,字符串已损坏,我认为它与我发送的不一样。它的长度是相同的,几乎所有的字符。如果我将发送的内容与收到的内容进行比较,我会发送300个与发送内容不同的字符。我发送50.000个字符的字符串。知道可能是什么问题吗?大多数代码都是注释,因此您将在几秒钟内理解它。此外,我缩小了它,让你更容易阅读。

我发送这个。

        // 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 ) ) ;
            }
        }

我正在读这篇文章。

            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();
            }


        }

1 个答案:

答案 0 :(得分:1)

我在这段代码中看到了几个问题:

1)当您发送时,您将 msg的副本放入m_messageQueue。但是,当您致电async_write时,您的缓冲区是根据msg而不是m_messageQueue的指针构建的。所以最终你可以从不正确的缓冲区发送。

2)收到你在堆栈上创建receiveBuffer。当async_read_some立即返回(几乎总是)时,您的receiveBuffer将被销毁,因为您退出StartReceiving来电。

3)与sendBuffer

相同