Boost asio收到损坏的消息

Boost asio receive corrupt message

本文关键字:消息 损坏 asio Boost      更新时间:2023-10-16

我成为了一名服务器&客户端异步应用程序。除了我收到的信息外,一切都很顺利。我正在把图像片段串起来。但当我收到它们时,字符串已损坏,我认为它与我发送的不一样。长度是一样的,几乎所有的字符。如果我将我发送的内容与收到的内容进行比较,我会与发送的内容有大约300个字符的不同。我正在发送50000个字符的字符串。你知道问题出在哪里吗?大部分代码都是注释,所以你会在几秒钟内理解它。此外,我缩小了它,让你更容易阅读。

我随此发送。

        // 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) 发送时,您正在将msg副本放入m_messageQueue。但是,当您调用async_write时,您的缓冲区是由取自msg的指针构建的,而不是m_messageQueue。所以最终你可以从错误的缓冲区发送。

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

3) 与sendBuffer 相同