2010-11-28 12 views
3

サーバー上で接続を維持しているクライアントを作成しようとしました。Boost asio:クライアント接続を維持する方法

ただし、データを1回受信すると接続が切断されました。なぜか分からない。

私はループを作るべきだと思いますが、それは良い考えではないと私は言っていました。

class client 
{ 
public: 
    client(boost::asio::io_service& io_service, 
     const std::string& host, const std::string& service) 
    : connection_(io_service) 
    { 
    // Resolve the host name into an IP address. 
    boost::asio::ip::tcp::resolver resolver(io_service); 
    boost::asio::ip::tcp::resolver::query query(host, service); 
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator = 
     resolver.resolve(query); 
    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator; 

    // Start an asynchronous connect operation. 
    connection_.socket().async_connect(endpoint, 
     boost::bind(&client::handle_connect, this, 
      boost::asio::placeholders::error, ++endpoint_iterator)); 
    } 

    /// Handle completion of a connect operation. 
    void handle_connect(const boost::system::error_code& e, 
     boost::asio::ip::tcp::resolver::iterator endpoint_iterator) 
    { 
    if (!e) 
    { 
     // Successfully established connection. Start operation to read the list 
     // of stocks. The connection::async_read() function will automatically 
     // decode the data that is read from the underlying socket. 
     connection_.async_read(stocks_, 
      boost::bind(&client::handle_read, this, 
      boost::asio::placeholders::error)); 
    } 
    else 
    { 
     std::cerr << e.message() << std::endl; 
    } 
    } 

    /// Handle completion of a read operation. 
    void handle_read(const boost::system::error_code& e) 
    { 
    if (!e) 
    { 
     // Print out the data that was received. 
     for (std::size_t i = 0; i < stocks_.size(); ++i) 
     { 
     std::cout << "Paquet numero " << i << "\n"; 
     std::cout << " age: " << stocks_[i].age << "\n"; 
     std::cout << " name: " << stocks_[i].nom << "\n"; 
     } 

       // Maybe Should i put something here ? 
    } 
    else 
    { 
     // An error occurred. 
     std::cerr << "Error : " << e.message() << std::endl; 
     connection_.socket().close(); 
    } 

    // or maybe here ? 

    } 

private: 
    /// The connection to the server. 
    connection   connection_; 
    std::vector<stock> stocks_; 
}; 

このような主なルックス:1の場合

int main(int argc, char* argv[]) 
{ 
    try 
    { 
    // Check command line arguments. 
    if (argc != 3) 
    { 
     std::cerr << "Usage: client <host> <port>" << std::endl; 
     return 1; 
    } 

    boost::asio::io_service io_service; 

    client client(io_service, argv[1], argv[2]); 
    io_service.run(); 
    } 
    catch (std::exception& e) 
    { 
    std::cerr << e.what() << std::endl; 
    } 

    return 0; 
} 

答えて

7

は、お使いのASIO io_serviceがやるべき仕事が不足しています。

connection_.async_read(stocks_, 
     boost::bind(&client::handle_read, this, 
     boost::asio::placeholders::error)); 

通常、あなたは非同期プログラミングをしている場合、一度非同期:あなたはあなたのコメントを入れてhandle_readでは、あなたは次の非同期読み出し動作をスケジュールすることができ、「たぶん、私はここで何かを置く必要があります」。ハンドラが呼び出されると、次の非同期を呼び出します。これは、非同期接続ハンドラの場合と同じです。

+0

+1これは正しい答えです。あなたは 'async'演算を連鎖させる必要があります。ほとんどの場合、OPは 'client :: handle_read'メソッドで' async_write'または別の 'async_read'を開始する必要があります。 –

+0

私の同様の状況。私は最初にサーバーに書き込んでから、サーバーからデータを送信した後にhandleを呼び出すのではなく、すぐにハンドルでEOFを取得します。 – neckTwi

関連する問題