Boost.Asio c++ 网络编程翻译(16)

TCP异步服务端
核心功能和同步服务端的功能类似,例如以下:
class talk_to_client : public boost::enable_shared_from_this<talk_to_
   client>
                        , boost::noncopyable {
       typedef talk_to_client self_type;
       talk_to_client() : sock_(service), started_(false) {}
   public:
       typedef boost::system::error_code error_code;
       typedef boost::shared_ptr<talk_to_client> ptr;page76image1880
       void start() {
           started_ = true;

do_read(); }

       static ptr new_() {
           ptr new_(new talk_to_client);
           return new_;
       }
       void stop() {
           if ( !started_) return;
           started_ = false;
           sock_.close();
       }
       ip::tcp::socket & sock() { return sock_;}
       ...
   private:
       ip::tcp::socket sock_;
       enum { max_msg = 1024 };
       char read_buffer_[max_msg];
       char write_buffer_[max_msg];
       bool started_;

};

由于我们是很easy的回显服务,这里不须要一个is_started()方法。

对每一个client,只读取它的消息,回显,然后关闭它。

do_read(),do_write()和read_complete()方法和TCP同步服务端的全然一致。
基本的逻辑相同是在on_read()和on_write()方法中:
void on_read(const error_code & err, size_t bytes) {
       if ( !err) {
           std::string msg(read_buffer_, bytes);
           do_write(msg + "
");
       }

stop(); }

   void on_write(const error_code & err, size_t bytes) {
       do_read();
}
对client的处理例如以下:
ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(),
   8001));
   void handle_accept(talk_to_client::ptr client, const error_code & err)
   {
       client->start();
       talk_to_client::ptr new_client = talk_to_client::new_();
       acceptor.async_accept(new_client->sock(),
           boost::bind(handle_accept,new_client,_1));
   }
   int main(int argc, char* argv[]) {
       talk_to_client::ptr client = talk_to_client::new_();
       acceptor.async_accept(client->sock(),
           boost::bind(handle_accept,client,_1));
       service.run();

每一次client连接到服务时,handle_accept被调用,它会异步地从client读取。然后相同异步地等待一个新的client。

代码
你会在这本书对应的代码中得到全部4个应用(TCP回显同步client,TCP回显同步服务端。TCP回显异步client,TCP回显异步服务端)。

当測试时,你能够使用随意client/服务端组合(比方。一个异步client和一个同步服务端)。


UDP回显服务端/client
由于UDP不能保证全部信息都抵达接收者,我们不能保证“信息以回车结尾”。
没收到消息,我们仅仅是回显,可是没有socket去关闭(在服务端)。由于我们是UDP。

UDP同步回显client
UDP回显client比TCP回显client要简单:
ip::udp::endpoint ep( ip::address::from_string("127.0.0.1"), 8001);
   void sync_echo(std::string msg) {
       ip::udp::socket sock(service, ip::udp::endpoint(ip::udp::v4(), 0)
   );
       sock.send_to(buffer(msg), ep);
       char buff[1024];
       ip::udp::endpoint sender_ep;
       int bytes = sock.receive_from(buffer(buff), sender_ep);
       std::string copy(buff, bytes);
       std::cout << "server echoed our " << msg << ": "
                   << (copy == msg ?

"OK" : "FAIL") << std::endl;

       sock.close();
   }
   int main(int argc, char* argv[]) {
       char* messages[] = { "John says hi", "so does James", "Lucy got
   home", 0 };
       boost::thread_group threads;
       for ( char ** message = messages; *message; ++message) {
           threads.create_thread( boost::bind(sync_echo, *message));
           boost::this_thread::sleep( boost::posix_time::millisec(100));
       }
       threads.join_all();
   }
全部的逻辑都在synch_echo()中;连接到服务端,发送消息。接收服务端的回显,然后关闭连接。

UDP同步回显服务端
UDP回显服务端会是你写过的最简单的服务端:
io_service service;
   void handle_connections() {
       char buff[1024];
       ip::udp::socket sock(service, ip::udp::endpoint(ip::udp::v4(),
   8001));
       while ( true) {
           ip::udp::endpoint sender_ep;
           int bytes = sock.receive_from(buffer(buff), sender_ep);
           std::string msg(buff, bytes);
           sock.send_to(buffer(msg), sender_ep);

} }

   int main(int argc, char* argv[]) {
       handle_connections();

它非常easy,并且能非常好的自释。

我把异步UDPclient和服务端留给读者当作一个练习。

总结
我们已经写了完毕的应用。终于让Boost.Asio得以工作。

回显应用是開始学习一个库时很好的工具。你能够常常学习和执行这个章节所展示的代码,这样你就能够很easy地记住这个库的基础。

在下一章,我们会建立更复杂的client/服务端应用。我们要确保避免低级错误,比方内存泄漏,死锁等等。




原文地址:https://www.cnblogs.com/yjbjingcha/p/7230992.html