2011-08-12 8 views
1

私が探している以下のコード(user368831から)を参照してください。メインループが他のタスクを実行できる間に、接続とデータをリッスンして読み取るスレッド化されたTCPセッションにするために少し修正しました。boost :: asio :: io_serviceでメインのデータを取得します

class CSession 
{ 
public: 
    CSession(boost::asio::io_service& io_service) : m_Socket(io_service) 
    {} 

    tcp::socket& socket() return m_Socket; 

    void start() 
    { 
     boost::asio::async_read_until(m_Socket, m_Buffer, " ", 
             boost::bind(&CSession::handle_read, this, 
             boost::asio::placeholders::error, 
             boost::asio::placeholders::bytes_transferred)); 
    } 

    void handle_read(const boost::system::error_code& error, 
        size_t bytes_transferred) 
    { 
     if (!error) 
     { 
      ostringstream ss; 
      ss << &m_Buffer; 
      m_RecvMsg = ss.str(); 
      std::cout << "handle_read():" << m_RecvMsg << std::endl; 
     } 
     else 
      delete this; 
    }  

private: 
    boost::asio::streambuf m_Buffer; 
    tcp::socket    m_Socket; 
    string     m_RecvMsg; 
}; 

class CTcpServer 
{ 
public: 
    CTcpServer(short port) 
    : m_Acceptor(m_IOService, tcp::endpoint(tcp::v4(), port)), 
    m_Thread(boost::bind(&boost::asio::io_service::run, &m_IOService)) 
    {   
     CSession* new_session = new CSession(m_IOService); 

     m_Acceptor.async_accept(new_session->socket(), 
           boost::bind(&CTcpServer::handle_accept, this, new_session, 
           boost::asio::placeholders::error)); 
    }; 

    void handle_accept(CSession* new_session, const boost::system::error_code& error) 
    { 
     if (!error) 
     { 
      new_session->start(); 
      new_session = new CSession(m_IOService); 
      m_Acceptor.async_accept(new_session->socket(), 
      boost::bind(&CTcpServer::handle_accept, this, new_session, 
          boost::asio::placeholders::error)); 
     } 
     else 
      delete new_session; 
    } 

private: 
    boost::asio::io_service m_IOService; 
    tcp::acceptor   m_Acceptor; 
    boost::thread   m_Thread; 

}; 

void main() 
{ 
     : 
    CTcpServer *server = new CTcpServer(6002); // tcp port 6002 
    /* How to get the incoming data sent from the client here?? */ 
    // string message; 
    // while(1) 
    // { 
    // if (server->incomingData(message)) 
    // { 
    //  std::cout << "Data recv: " << message.data() << std::endl; 
    // } 
    //  : 
    //  : // other tasks 
    //  : 
    // } 
} 

はしかし、どのように私はそれは、クライアントからのデータを監視し、handle_read()が呼び出されたときにtrueを返しますよう、メインループでincomingDataを()コードのですか?

この場合、Boost :: signalsライブラリを使用できますか?

+0

asioのポスト機能があなたに使用されているかどうか確認してください – Arunmu

+0

サーバーを独自のスレッドに配置していますか? –

答えて

1

このコードは正直に恐ろしいです。あなたが生のポインタを使用している方法のためにメモリリークが多くあります。 Asioはshared_ptrで最もうまく動作します。オブジェクトの存続期間については保証が必要です。私はあなたがこのコードを投げ捨てて、asioの事例に従うだけの単純さを見て始めることをお勧めします。

コーディングしたい方法は、それが動作する方法ではないので、そのロジックをhandle_readに入れる必要があります。あなたのプロトコルに従って完全なメッセージを持っているときにhandle_readが呼び出されるときは、main whileループではなく、このメソッドで発生させたいロジックを置くべきです。あなたのメインスレッドでは、単にio_service::run()と呼ぶべきです。

+0

ありがとうございました!実際、上記のコードはBoost C++ ASIOの例のWebサイト(http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp)にあります。だから私はshared_ptrを使うべきです。また、io_service :: run()はCTcpServerコンストラクタで行われます。 – tanlccc

+0

@ tanlcc、ええ、それは別のスレッドでディスパッチしています。あなたのメインスレッドはwhileループを実行し、2つをやり取りする場合は、2つのキューの間に何らかの形のキュー(および同期化メカニズム)が必要です。 – Nim

関連する問題