消息通信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 }

 

posted @ 2017-10-09 15:13  lausaa  阅读(279)  评论(0)    收藏  举报