以下是来自boost example的异步echo server:
// // async_tcp_echo_server.cpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include #include #include #include using boost::asio::ip::tcp; class session { public: session(boost::asio::io_service& io_service) : socket_(io_service) { } tcp::socket& socket() { return socket_; } void start() { socket_.async_read_some(boost::asio::buffer(data_, max_length), boost::bind(&session::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) { boost::asio::async_write(socket_, boost::asio::buffer(data_, bytes_transferred), boost::bind(&session::handle_write, this, boost::asio::placeholders::error)); } else { delete this; } } void handle_write(const boost::system::error_code& error) { if (!error) { socket_.async_read_some(boost::asio::buffer(data_, max_length), boost::bind(&session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else { delete this; } } private: tcp::socket socket_; enum { max_length = 1024 }; char data_[max_length]; }; class server { public: server(boost::asio::io_service& io_service, short port) : io_service_(io_service), acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) { session* new_session = new session(io_service_); acceptor_.async_accept(new_session->socket(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)); } void handle_accept(session* new_session, const boost::system::error_code& error) { if (!error) { new_session->start(); new_session = new session(io_service_); acceptor_.async_accept(new_session->socket(), boost::bind(&server::handle_accept, this, new_session, boost::asio::placeholders::error)); } else { delete new_session; } } private: boost::asio::io_service& io_service_; tcp::acceptor acceptor_; }; int main(int argc, char* argv[]) { try { if (argc != 2) { std::cerr << "Usage: async_tcp_echo_server /n"; return 1; } boost::asio::io_service io_service; using namespace std; // For atoi. server s(io_service, atoi(argv[1])); io_service.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "/n"; } return 0; }
为了模拟高并发连接,顺手写了个异步多连接的客户端程序:
#include #include #include #include #include using boost::asio::ip::tcp; using namespace std; static int id = 1; const char message[] = "test write string..."; class echo_session { public: echo_session(boost::asio::io_service& io_service) : socket_(io_service) { id_ = id; ++id; } void start(const std::string& ip, const std::string& port) { //解析主机地址 tcp::resolver resolver(socket_.io_service()); tcp::resolver::query query(tcp::v4(), ip, port); tcp::resolver::iterator iterator = resolver.resolve(query); //异步连接 socket_.async_connect(*iterator, boost::bind(&echo_session::handle_connect, this, boost::asio::placeholders::error)); } private: void handle_connect(const boost::system::error_code& error) { if (!error) { //连接成功,发送message中的数据 boost::asio::async_write(socket_, boost::asio::buffer(message, sizeof(message)), boost::bind(&echo_session::handle_write, this, boost::asio::placeholders::error)); } else cout << error << endl; } void handle_write(const boost::system::error_code& error) { if (!error) { //写入完毕,接收服务器回射的消息 boost::asio::async_read(socket_, boost::asio::buffer(buf_, sizeof(buf_)), boost::bind(&echo_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } else cout << error << endl; } void handle_read(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { //读取完毕,在终端显示 cout << id_ << ":receive:" << bytes_transferred << "," << buf_ << endl; //周而复始... handle_connect(error); } else cout << error << endl; } int id_; tcp::socket socket_; char buf_[sizeof(message)]; }; int main(int argc, char* argv[]) { const int session_num = 10000; //连接的数量 echo_session* sessions[session_num]; memset(sessions, 0, sizeof(sessions)); try { if (argc != 3) { std::cerr << "Usage: blocking_tcp_echo_client /n"; return 1; } boost::asio::io_service io_service; //创建session_num个连接 for (int i=0; istart(argv[1], argv[2]); } //io_service主循环 io_service.run(); for (int i=0; i
在linux下操作系统默认允许的最大连接数可能不足导致连接抛异常,需要用ulimit -n命令修改。如果提示操作不允许,需要修改系统配置文件。详细