Asio写入成功,但没有发送信息

asio write succeeding but no information sent

本文关键字:信息 成功 Asio      更新时间:2023-10-16

我在创建发送请求的客户端程序时遇到了问题。请求使用保持活动的TCP HTTP连接。当连接关闭时(由于超时或达到最大值),如果没有可用的连接,我尝试启动一个新的连接,并重新发送请求。连接工作良好,然而,当我尝试发送写,什么都没有发送(根据Wireshark),但我的写错误代码是成功的。接收服务器也不接收任何信息。下面是我的代码的主要部分:

void request_handler::send_1(std::vector<std::string> *bid_vector, std::string request_path, boost::mutex *bids_mutex)
{
    try
    {
        boost::asio::streambuf request;
        std::ostream request_stream(&request);
        std::string reply_information;
        request_stream << "GET /tests HTTP/1.1rn";
        request_stream << "Host: 10.1.10.160rn";
        request_stream << "Accept: */*rn";
        request_stream << "Connection: keep-alivernrn";
        server1_mutex_.lock();
        if(server1_available_map_.size() == 0)
        {
            server1_mutex_.unlock();
            persistent_connection *new_connection = new persistent_connection("10.1.10.160","80");
            if(new_connection->send(request, reply_information))
            {
                server1_mutex_.lock();
                    server1_available_map_[new_connection->get_id()] = new_connection;
                server1_mutex_.unlock();
            }
        }
        else
        {
                persistent_connection *current_connection = (*(server1_available_map_.begin())).second;
                server1_available_map_.erase(current_connection->get_id());
            server1_mutex_.unlock();
            int retry_counter = 20;
            while(!current_connection->query_rtb(request, reply_information) && --retry_counter != 0)
            {
                delete current_connection;
                server1_mutex_.lock();
                if(server1_available_map_.size() == 0)
                {
                    server1_mutex_.unlock();
                    current_connection = new persistent_connection("10.1.10.160","80");
                }
                else
                {
                        current_connection = (*(server1_available_map_.begin())).second;
                        server1_available_map_.erase(current_connection->get_id());
                    server1_mutex_.unlock();
                }
            }
            //Could not connect to 20 connections
            if(retry_counter == 0)
            {
                Log::fatal("Could not connect in 20 tries");
                delete current_connection;
                return;
            }
            server1_mutex_.lock();
                server1_available_map_[current_connection->get_id()] = current_connection;
            server1_mutex_.unlock();
        }    
        bids_mutex->lock();
            bid_vector->push_back(reply_information);
        bids_mutex->unlock();    
    }
    catch(boost::thread_interrupted& e)
    {
        std::cout << "before cancel 1" << std::endl;
        return;
    }
    catch(...)
    {
        std::cout << "blah blah blah" << std::endl;
    }
}

和我的persistent_connection类

persistent_connection::persistent_connection(std::string ip, std::string port):
    io_service_(), socket_(io_service_), host_ip_(ip)
{
    boost::uuids::uuid uuid = boost::uuids::random_generator()();
    id_ = boost::lexical_cast<std::string>(uuid);
    boost::asio::ip::tcp::resolver resolver(io_service_);
    boost::asio::ip::tcp::resolver::query query(host_ip_,port);
    boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
    boost::asio::ip::tcp::endpoint endpoint = *iterator;
    socket_.async_connect(endpoint, boost::bind(&persistent_connection::handler_connect, this, boost::asio::placeholders::error, iterator));
    io_service_.run();
}
void persistent_connection::handler_connect(const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
{
    if(ec)
    {
        std::cout << "Couldn't connect" << ec << std::endl;
        return;
    }
    else
    {
        boost::asio::socket_base::keep_alive keep_option(true);
        socket_.set_option(keep_option);
        std::cout << "Connect handler" << std::endl;
    }
}

bool persistent_connection::send(boost::asio::streambuf &request_information, std::string &reply_information)
{
    std::cout << "DOING QUERY in " << id_ << std::endl;
    boost::system::error_code write_ec, read_ec;
    try
    {
        std::cout << "Before write" << std::endl;
        boost::asio::write(socket_, request_information, write_ec);
        std::cout << write_ec.message() << std::endl;
    }catch(std::exception& e)
    {
        std::cout << "Write exception: " << e.what() << std::endl;
    }
    if(write_ec)
    {
        std::cout <<"Write error: " << write_ec.message() << std::endl;
        return false;
    }
    boost::array<char,8192> buf;
    buf.assign(0);
    try
    {
        std::cout << "Before read" << std::endl;
        boost::asio::read(socket_, boost::asio::buffer(buf), boost::asio::transfer_at_least(1), read_ec);
        std::cout << read_ec.message() << std::endl;
    }catch(std::exception& e)
    {
        std::cout << "Read exception: " << e.what() << std::endl;
    }
    if(read_ec)
    {
        std::cout << "Read error: " << read_ec.message() << std::endl;
        return false;
    }
    reply_information = buf.data();
    return true;
}
std::string persistent_connection::get_id()
{
    return id_;
}

如果server1_available_map_.size()> 0,并且while执行并且失败,则发生此操作的路径。然后如果第二个服务器上的size == 0 1_available_map_.size();

调用的输出是:

DOING QUERY in 69a8f0ab-2a06-45b4-be26-37aea6d93ff2
Before write
Success
Before read
End of file
Read error: End of file
Connect handler
DOING QUERY in 4eacaa96-1040-4878-8bf5-c29b87fa1232
Before write
Success
Before read

表示第一个连接得到一个文件结束(连接被另一端的服务器关闭)。第二个连接连接良好(Connect处理程序消息),并且在第二个连接(不同的id)中执行查询,并且写入显然是成功的,并且程序挂起读(因为没有什么可读的)。

有人知道为什么会发生这种情况吗?我好像做错了什么吗?

谢谢

看起来您正在向多个写调用传递相同的boost::asio::streambuf

boost::asio::write(socket_, request_information, write_ec);

缓冲区的内容在第一次调用boost::asio::write时被消耗。这有效地清空了缓冲区,因此没有任何东西可以发送。如果您希望对多次写入使用相同的缓冲区,则传递const字符串。