简体   繁体   中英

Receiving the wrong data with boost::asio socket

I'm trying to use boost::asio for my new little hobby project but I'm having trouble getting the server to read the right data. Sending it works fine, I've checked with wireshark and the bytes [0 0 0 4] followed by [5 0 0 0] are sent. But on the server side I receive [16 -19 105 0] which makes me rather confused.

Here's how I send it, working perfectly when viewed through wireshark:

boost::asio::io_service io;
tcp::resolver resolver(io);
tcp::resolver::query query("localhost", boost::lexical_cast<string>("40001"));
tcp::resolver::iterator endpoints = resolver.resolve(query);
tcp::socket socket(io);
boost::asio::connect(socket, endpoints);
header h(5);
header::storage data = h.store();
boost::asio::write(socket, boost::asio::buffer(&data[0], header::header_size()));

This is a stripped down version of my server class. handle_read_header is called with the correct number of bytes, but headerbuffer contains weird values, [16 -19 105 0].

class tcp_connection : public boost::enable_shared_from_this<tcp_connection>
{
public:
    tcp_connection(boost::asio::io_service& io)
        : _socket(io)
    {
        memset(&headerbuffer[0], 0, headerbuffer.size());
    }

    void start() {
        _socket.async_read_some(boost::asio::buffer(&headerbuffer[0], header::header_size()), boost::bind(&tcp_connection::handle_read_header, this,
                                                                                               boost::asio::placeholders::error,
                                                                                               boost::asio::placeholders::bytes_transferred));
    }
    void handle_read_header(const boost::system::error_code& error, std::size_t numBytes) {
        if(!error) {
            BOOST_LOG_SEV(logger, loglvl::debug) <<"handle_read_header, " <<numBytes <<"/" <<header::header_size() <<" bytes";
            if (numBytes == header::header_size()) {
                std::stringstream ss;
                for(u32 a = 0; a < numBytes; ++a) {
                    ss <<(int)headerbuffer[a] <<" ";
                }
                BOOST_LOG_SEV(logger, loglvl::debug) <<"header data: " <<ss.str();
                mCurrentHeader.load(headerbuffer);
                mRemaining = mCurrentHeader.size();
                BOOST_LOG_SEV(logger, loglvl::debug) <<"got header with size " <<mCurrentHeader.size();
            }
        } else {
            BOOST_LOG_SEV(logger, loglvl::debug) <<"error " <<error;
        }
    }
private:
    header mCurrentHeader;
    std::array<char, 128> headerbuffer;
    boost::asio::ip::tcp::socket _socket;
};

(Almost) complete code can be found at http://paste2.org/U97HHaH3

It turned out to be a sneaky, but at the same time obvious, error. tcp_connection::ptr is a shared_ptr. In tcp_server.h I call start() on it, but then nothing referes to it, which makes the shared_ptr, reasonably, assume it can be deleted. So the function is running, but the member variables have been cleared.

No idea why it worked some of the times, but I assume that's in the land of undefined behaviour.

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