0

I'm using Boost::asio to test tcp communication. I write a c++ server code and use telnet as client to connect my server node, which are run in 2 terminals respectively.

My question is:

when connected, server can use async_write to send data to the client, but when the server use async_read to read data from the client, the server node crushed.

I think this problem may come from the buffer, but I don't know how to solve it.

Here are my codes:

    std::vector<char> session::readResponse(const int move_id)
    {
        
        int data_size;
        switch (move_id)
        {
            // receive data from info1
            case 1: 
                data_size = 20;
                break;
            // receive data from info2
            case 2: 
                data_size = 19;
                break;
            default:
                data_size = 0;
                break;
        }

        auto self(shared_from_this());
        bool data_available = false;
        std::vector<char> char_vector(data_size);

        try
        {
            boost::mutex::scoped_lock scoped_locker(*mutex_);
            boost::asio::async_read( 
                socket_, 
                boost::asio::buffer(char_vector, data_size),
                [&](const boost::system::error_code &error, std::size_t bytes_transferred)
                {
                    if (error)
                    {
                        data_available = false;
                        std::cerr << ">>> readCallback Error " << error << std::endl;
                    }
                    timeout_->cancel();
                    data_available = true;
                });
            
            timeout_->expires_from_now(boost::posix_time::seconds(10));
            timeout_->async_wait(  
                [&](const boost::system::error_code &error)
                {
                    if (!error)
                    {
                        data_available = false;
                        socket_.cancel();
                        std::cerr << ">>> Read timeout." << std::endl;
                    }
                });
        }
        catch(const std::exception& e)
        {
            std::cerr << ">>> Read exception. " << e.what() << '\n';
        }
        
        if (data_available)
        {
            return char_vector;
        }
        else
        {
            throw ">>> reading timeout";
        }

    }
void gManualSendCommand(Server& srv)
{
    while( true ) 
        {
            if(srv.getSession() == NULL)
            {
            }
            else
            {
                std::cout << "Enter robot command id: ";
                std::string id;
                std::getline(std::cin, id);
                srv.getSession()->writeCommand(std::stoi(id));
                srv.getSession()->readResponse(std::stoi(id));
                std::cout << "\n";
            }
            
        }
    
}

enter image description here

These codes are modified from my last project (serial port communication), and last time I did not meet this problem.

Any suggestion will be highly appreciated, thanks.

UPDATE(0811-1):

I found that my readResponse function won't actuate the timer to wait 10s, hence, the function throws ">>> reading timeout".

UPDATE(0811-2): After some tests, the timer is actually actuated. However, only io callbacks get blocked by this timer, so the function quickly jumps to the if condition and return.

  • recently, I dig a post ten years ago because I also confused on throw const char*, https://stackoverflow.com/questions/5887655/throwing-catching-scoping-stlstring-c-str-exceptions/73302931#73302931 it'd best that not throw const char*, because a stack variable aString.c_str() also return a const char*, please try the code:throw string object or throw runtime_error(string). but if you really sure that throw "some const static msg", actually it's OK to coding like this, it might be some problem in other places. – chenzero Aug 10 '22 at 10:13
  • @chenzero thanks for your comment, as I updated in my post. The function always throws `">>> reading timeout"`, so coding like const msg maybe OK here (my perspective). I think the error comes from the dead_line timer. – RyanChen.YLC Aug 11 '22 at 02:21
  • no mentioned it. Did you try to run server in debugger mode ? in debugger mode, when server encounters some pointer problem, it will halt at the line in source code. Debugger tools include: gdb, or IDEs, e.g: Eclipse CDT, using a IDE is more convenient in development – chenzero Aug 11 '22 at 08:12
  • @chenzero Yes, I tried debugger mode to see what happened when the code was running. And issue solved after I found the problem which I updated in my post (UPDATE 0811-2). – RyanChen.YLC Aug 16 '22 at 02:13

0 Answers0