2013-04-23 66 views
0

我在创建发送请求的客户端程序时遇到问题。该请求正在使用保持活动的TCP HTTP连接。当一个连接关闭(由于超时或最大命中),我尝试并开始一个新的连接,如果没有可用的,并重新发送请求。但是,连接工作正常,当我尝试发送写入时,没有任何内容被发送(根据Wireshark),但是我的写入错误代码是成功的。接收服务器也没有收到任何信息。这里是我的代码的主要部分:asio写成功,但没有发送信息

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.1\r\n"; 
     request_stream << "Host: 10.1.10.160\r\n"; 
     request_stream << "Accept: */*\r\n"; 
     request_stream << "Connection: keep-alive\r\n\r\n"; 

     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,如果同时执行,并失败。然后如果第二个server1_available_map_.size();上的大小== 0;

输出用于该呼叫是:

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 

其示出了第一连接获取文件的端部(连接由服务器上的另一端封闭)。第二个连接连接正常(连接处理程序消息),查询在第二个连接(不同的id)中执行,并且写入显然成功,并且程序挂在读取上(因为没有任何可读的内容)。

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

谢谢

回答

1

它看起来像你传球同样的boost :: ASIO ::流缓冲到多个写入调用。

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

缓冲区的内容第一次调用消耗的boost ::支持ASIO ::写。这有效地清空了缓冲区,因此没有什么需要发送的。如果要为多次写入使用相同的缓冲区,则传递一个常量字符串。

+0

非常感谢,就是这样,不知道从流缓冲读书是破坏性的。 – Eumcoz 2013-04-23 19:12:14

相关问题