消息通信Server端
基于boost实现的消息通信Server端,目前仅用于接收消息并调用消息处理函数。
1 #ifndef __cooper_server_h_ 2 #define __cooper_server_h_ 3 4 #include "cooper_message.h" 5 6 using boost::asio::ip::tcp; 7 8 typedef deque<CooperMessage> MsgQueueType; 9 typedef boost::function<void(const CooperMessage&)> RecvMsgCallbackFunction; 10 11 const string kIPSendMsgToAll = "255.255.255.255"; 12 const char kServerPort[] = "29317"; 13 14 //---------------------------------------------------------------------- 15 16 class CooperSession; 17 typedef boost::shared_ptr<CooperSession> session_ptr; 18 19 //---------------------------------------------------------------------- 20 21 class SessionSet 22 { 23 public: 24 void Join(session_ptr session); 25 void Leave(session_ptr session); 26 void AsyncWriteSet(const CooperMessage& msg); 27 28 private: 29 set<session_ptr> sessions_; 30 }; 31 32 //---------------------------------------------------------------------- 33 34 class CooperSession : public boost::enable_shared_from_this<CooperSession> 35 { 36 public: 37 CooperSession(boost::asio::io_service& io_service, SessionSet& session_set) 38 : socket_(io_service), session_set_(session_set) 39 { 40 msg_header_ = new char[CooperMessage::header_length]; 41 } 42 43 ~CooperSession() { delete[] msg_header_; } 44 45 tcp::socket& get_socket(); 46 const char* get_remote_ip(); 47 48 void JoinSet(); 49 void AsyncRead(RecvMsgCallbackFunction func); 50 void HandleReadHeader(const boost::system::error_code& error); 51 void HandleReadBody(const boost::system::error_code& error); 52 void AsyncWrite(const CooperMessage& msg); 53 void HandleWrite(const boost::system::error_code& error); 54 55 private: 56 tcp::socket socket_; 57 SessionSet& session_set_; 58 CooperMessage read_msg_; 59 MsgQueueType write_msgs_; 60 RecvMsgCallbackFunction asyncread_cbf_; 61 char* msg_header_; 62 }; 63 64 //---------------------------------------------------------------------- 65 66 class CooperServer 67 { 68 public: 69 CooperServer(boost::asio::io_service& io_service, 70 const tcp::endpoint& endpoint, 71 RecvMsgCallbackFunction func); 72 73 void HandleAccept(session_ptr session, const boost::system::error_code& error); 74 75 private: 76 void AsyncAccept(); 77 78 private: 79 RecvMsgCallbackFunction recvmsg_cbf_; 80 SessionSet session_set_; 81 boost::asio::io_service& io_service_; 82 tcp::acceptor acceptor_; 83 }; 84 85 //---------------------------------------------------------------------- 86 87 #endif // __cooper_server_h_
1 #include "cooper_server.h" 2 3 //---------------------------------------------------------------------- 4 5 tcp::socket& CooperSession::get_socket() 6 { 7 return socket_; 8 } 9 10 const char* CooperSession::get_remote_ip() 11 { 12 return socket_.remote_endpoint().address().to_string().c_str(); 13 } 14 15 void CooperSession::JoinSet() 16 { 17 session_set_.Join(shared_from_this()); 18 printf("new session joined.\n"); 19 } 20 21 void CooperSession::AsyncRead(RecvMsgCallbackFunction func) 22 { 23 asyncread_cbf_ = func; 24 // printf("async_read start\n"); 25 boost::asio::async_read(socket_, 26 boost::asio::buffer(msg_header_, CooperMessage::header_length), 27 boost::bind(&CooperSession::HandleReadHeader, shared_from_this(), 28 boost::asio::placeholders::error)); 29 } 30 31 void CooperSession::HandleReadHeader(const boost::system::error_code& error) 32 { 33 if (!error) { 34 uint body_length = read_msg_.get_body_length(msg_header_); 35 printf("InitMsg body_length=%d\n", body_length); 36 37 if (!read_msg_.InitMsg(msg_header_, body_length)) { 38 session_set_.Leave(shared_from_this()); 39 } 40 41 boost::asio::async_read(socket_, 42 boost::asio::buffer(read_msg_.get_body(), body_length), 43 boost::bind(&CooperSession::HandleReadBody, shared_from_this(), 44 boost::asio::placeholders::error)); 45 } else { 46 session_set_.Leave(shared_from_this()); 47 } 48 } 49 50 void CooperSession::HandleReadBody(const boost::system::error_code& error) 51 { 52 if (!error) { 53 asyncread_cbf_(read_msg_); 54 boost::asio::async_read(socket_, 55 boost::asio::buffer(msg_header_, CooperMessage::header_length), 56 boost::bind(&CooperSession::HandleReadHeader, shared_from_this(), 57 boost::asio::placeholders::error)); 58 } else { 59 session_set_.Leave(shared_from_this()); 60 } 61 } 62 63 void CooperSession::AsyncWrite(const CooperMessage& msg) 64 { 65 string dst_ip(msg.get_dst_ip()); 66 string remote_ip(socket_.remote_endpoint().address().to_string()); 67 68 if (dst_ip != kIPSendMsgToAll && remote_ip != dst_ip) { 69 return; 70 } 71 72 bool write_in_progress = !write_msgs_.empty(); 73 write_msgs_.push_back(msg); 74 75 if (!write_in_progress) { 76 boost::asio::async_write(socket_, 77 boost::asio::buffer(write_msgs_.front().get_data(), 78 write_msgs_.front().get_data_length()), 79 boost::bind(&CooperSession::HandleWrite, shared_from_this(), 80 boost::asio::placeholders::error)); 81 } 82 } 83 84 void CooperSession::HandleWrite(const boost::system::error_code& error) 85 { 86 if (!error) { 87 write_msgs_.pop_front(); 88 89 if (!write_msgs_.empty()) { 90 boost::asio::async_write(socket_, 91 boost::asio::buffer(write_msgs_.front().get_data(), 92 write_msgs_.front().get_data_length()), 93 boost::bind(&CooperSession::HandleWrite, shared_from_this(), 94 boost::asio::placeholders::error)); 95 } 96 } else { 97 session_set_.Leave(shared_from_this()); 98 } 99 } 100 101 //---------------------------------------------------------------------- 102 103 void SessionSet::Join(session_ptr session) 104 { 105 sessions_.insert(session); 106 } 107 108 void SessionSet::Leave(session_ptr session) 109 { 110 printf("%s leave.\n", session->get_remote_ip()); 111 sessions_.erase(session); 112 } 113 114 void SessionSet::AsyncWriteSet(const CooperMessage& msg) 115 { 116 std::for_each(sessions_.begin(), sessions_.end(), 117 boost::bind(&CooperSession::AsyncWrite, _1, boost::ref(msg))); 118 } 119 120 //---------------------------------------------------------------------- 121 122 CooperServer::CooperServer(boost::asio::io_service& io_service, 123 const tcp::endpoint& endpoint, 124 RecvMsgCallbackFunction func) 125 : io_service_(io_service), 126 acceptor_(io_service, endpoint), 127 recvmsg_cbf_(func) 128 { 129 AsyncAccept(); 130 } 131 132 void CooperServer::HandleAccept(session_ptr session, const boost::system::error_code& error) 133 { 134 if (!error) { 135 printf("Accept connection from %s\n", session->get_remote_ip()); 136 session->JoinSet(); 137 session->AsyncRead(recvmsg_cbf_); 138 AsyncAccept(); 139 } 140 } 141 142 void CooperServer::AsyncAccept() 143 { 144 session_ptr new_session(new CooperSession(io_service_, session_set_)); 145 acceptor_.set_option(tcp::acceptor::reuse_address(true)); 146 printf("Server start waiting accept connection.\n"); 147 acceptor_.async_accept(new_session->get_socket(), 148 boost::bind(&CooperServer::HandleAccept, this, new_session, 149 boost::asio::placeholders::error)); 150 }