快速构建MMO服务器框架(六)asio稍微复杂一些的例子:高并发echo

http://blog.csdn.net/cometeor/article/details/4901332

 以下是来自boost example的异步echo server:

  1. //  
  2. // async_tcp_echo_server.cpp  
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~  
  4. //  
  5. // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)  
  6. //  
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying  
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)  
  9. //  
  10. #include <cstdlib>  
  11. #include <iostream>  
  12. #include <boost/bind.hpp>  
  13. #include <boost/asio.hpp>  
  14. using boost::asio::ip::tcp;  
  15. class session  
  16. {  
  17. public:  
  18.   session(boost::asio::io_service& io_service)  
  19.     : socket_(io_service)  
  20.   {  
  21.   }  
  22.   tcp::socket& socket()  
  23.   {  
  24.     return socket_;  
  25.   }  
  26.   void start()  
  27.   {  
  28.     socket_.async_read_some(boost::asio::buffer(data_, max_length),  
  29.         boost::bind(&session::handle_read, this,  
  30.           boost::asio::placeholders::error,  
  31.           boost::asio::placeholders::bytes_transferred));  
  32.   }  
  33.   void handle_read(const boost::system::error_code& error,  
  34.       size_t bytes_transferred)  
  35.   {  
  36.     if (!error)  
  37.     {  
  38.       boost::asio::async_write(socket_,  
  39.           boost::asio::buffer(data_, bytes_transferred),  
  40.           boost::bind(&session::handle_write, this,  
  41.             boost::asio::placeholders::error));  
  42.     }  
  43.     else  
  44.     {  
  45.       delete this;  
  46.     }  
  47.   }  
  48.   void handle_write(const boost::system::error_code& error)  
  49.   {  
  50.     if (!error)  
  51.     {  
  52.       socket_.async_read_some(boost::asio::buffer(data_, max_length),  
  53.           boost::bind(&session::handle_read, this,  
  54.             boost::asio::placeholders::error,  
  55.             boost::asio::placeholders::bytes_transferred));  
  56.     }  
  57.     else  
  58.     {  
  59.       delete this;  
  60.     }  
  61.   }  
  62. private:  
  63.   tcp::socket socket_;  
  64.   enum { max_length = 1024 };  
  65.   char data_[max_length];  
  66. };  
  67. class server  
  68. {  
  69. public:  
  70.   server(boost::asio::io_service& io_service, short port)  
  71.     : io_service_(io_service),  
  72.       acceptor_(io_service, tcp::endpoint(tcp::v4(), port))  
  73.   {  
  74.     session* new_session = new session(io_service_);  
  75.     acceptor_.async_accept(new_session->socket(),  
  76.         boost::bind(&server::handle_accept, this, new_session,  
  77.           boost::asio::placeholders::error));  
  78.   }  
  79.   void handle_accept(session* new_session,  
  80.       const boost::system::error_code& error)  
  81.   {  
  82.     if (!error)  
  83.     {  
  84.       new_session->start();  
  85.       new_session = new session(io_service_);  
  86.       acceptor_.async_accept(new_session->socket(),  
  87.           boost::bind(&server::handle_accept, this, new_session,  
  88.             boost::asio::placeholders::error));  
  89.     }  
  90.     else  
  91.     {  
  92.       delete new_session;  
  93.     }  
  94.   }  
  95. private:  
  96.   boost::asio::io_service& io_service_;  
  97.   tcp::acceptor acceptor_;  
  98. };  
  99. int main(int argc, char* argv[])  
  100. {  
  101.   try  
  102.   {  
  103.     if (argc != 2)  
  104.     {  
  105.       std::cerr << "Usage: async_tcp_echo_server <port>/n";  
  106.       return 1;  
  107.     }  
  108.     boost::asio::io_service io_service;  
  109.     using namespace std; // For atoi.  
  110.     server s(io_service, atoi(argv[1]));  
  111.     io_service.run();  
  112.   }  
  113.   catch (std::exception& e)  
  114.   {  
  115.     std::cerr << "Exception: " << e.what() << "/n";  
  116.   }  
  117.   return 0;  
  118. }  

 

为了模拟高并发连接,顺手写了个异步多连接的客户端程序:

  1. #include <cstdlib>  
  2. #include <cstring>  
  3. #include <iostream>  
  4. #include <boost/asio.hpp>  
  5. #include <boost/bind.hpp>  
  6. using boost::asio::ip::tcp;  
  7. using namespace std;  
  8. static int id = 1;  
  9. const char message[] = "test write string...";  
  10. class echo_session  
  11. {  
  12.     public:  
  13.         echo_session(boost::asio::io_service& io_service)   
  14.             : socket_(io_service)  
  15.         {  
  16.             id_ = id;  
  17.             ++id;  
  18.         }  
  19.         void start(const std::string& ip, const std::string& port)  
  20.         {  
  21.             //解析主机地址  
  22.             tcp::resolver resolver(socket_.io_service());  
  23.             tcp::resolver::query query(tcp::v4(), ip, port);  
  24.             tcp::resolver::iterator iterator = resolver.resolve(query);  
  25.             //异步连接  
  26.             socket_.async_connect(*iterator, boost::bind(&echo_session::handle_connect, this, boost::asio::placeholders::error));  
  27.         }  
  28.     private:  
  29.         void handle_connect(const boost::system::error_code& error)  
  30.         {  
  31.             if (!error)  
  32.             {  
  33.                 //连接成功,发送message中的数据  
  34.                 boost::asio::async_write(socket_,   
  35.                         boost::asio::buffer(message, sizeof(message)),  
  36.                         boost::bind(&echo_session::handle_write, this,  
  37.                             boost::asio::placeholders::error));  
  38.             }  
  39.             else  
  40.                 cout << error << endl;  
  41.         }  
  42.         void handle_write(const boost::system::error_code& error)  
  43.         {  
  44.             if (!error)  
  45.             {  
  46.                 //写入完毕,接收服务器回射的消息  
  47.                 boost::asio::async_read(socket_, boost::asio::buffer(buf_, sizeof(buf_)),  
  48.                         boost::bind(&echo_session::handle_read, this,  
  49.                             boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));  
  50.             }  
  51.             else  
  52.                 cout << error << endl;  
  53.         }  
  54.         void handle_read(const boost::system::error_code& error, size_t bytes_transferred)  
  55.         {  
  56.             if (!error)  
  57.             {  
  58.                 //读取完毕,在终端显示  
  59.                 cout << id_ << ":receive:" << bytes_transferred << "," << buf_ << endl;  
  60.                 //周而复始...  
  61.                 handle_connect(error);  
  62.             }  
  63.             else  
  64.                 cout << error << endl;  
  65.         }  
  66.         int id_;  
  67.         tcp::socket socket_;  
  68.         char buf_[sizeof(message)];  
  69. };  
  70. int main(int argc, char* argv[])  
  71. {  
  72.     const int session_num = 10000;          //连接的数量  
  73.     echo_session* sessions[session_num];  
  74.     memset(sessions, 0, sizeof(sessions));  
  75.     try  
  76.     {  
  77.         if (argc != 3)  
  78.         {  
  79.             std::cerr << "Usage: blocking_tcp_echo_client <host> <port>/n";  
  80.             return 1;  
  81.         }  
  82.         boost::asio::io_service io_service;  
  83.         //创建session_num个连接  
  84.         for (int i=0; i<session_num; ++i)  
  85.         {  
  86.             sessions[i] = new echo_session(io_service);  
  87.             sessions[i]->start(argv[1], argv[2]);  
  88.         }  
  89.         //io_service主循环  
  90.         io_service.run();  
  91.         for (int i=0; i<session_num; ++i)  
  92.             if (sessions[i] != NULL)  
  93.                 delete sessions[i];  
  94.     }  
  95.     catch (std::exception& e)  
  96.     {  
  97.         for (int i=0; i<session_num; ++i)  
  98.             if (sessions[i] != NULL)  
  99.                 delete sessions[i];  
  100.         std::cerr << "Exception: " << e.what() << "/n";  
  101.     }  
  102.     return 0;  
  103. }  

在linux下操作系统默认允许的最大连接数可能不足导致连接抛异常,需要用ulimit -n命令修改。如果提示操作不允许,需要修改系统配置文件。详细


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值