zoukankan      html  css  js  c++  java
  • boost库在工作(39)网络UDP异步服务端之九

     

    前面创建的UDP服务器和客户端,都是同步的方式,也就是说当接收数据时,不能参与别的事情执行的。如果在一个只有界面线程的程序里,又不想创建多线程,导致复杂程度的增加,在这种情况之下,我们还有一个方案可以选择,就是创建一个异步的UDP服务器或客户端,这样既有单线程的简单性,也可以让客户随便操作界面的快速响应的特性。在boost库里使用io_service对象来实现异步是轻而易举的事情,因为封装的接口简单、明了。具体的代码如下:

    [cpp] view plaincopy
     
    1. // boost_028.cpp : Defines the entry point for the console application.  
    2. //  
    3.   
    4. #include "stdafx.h"  
    5. #include <ctime>  
    6.   
    7. #include <boost/asio/ip/tcp.hpp>  
    8. #include <boost/asio.hpp>  
    9. #include <boost/bind.hpp>  
    10. #include <boost/enable_shared_from_this.hpp>  
    11. #include <boost/shared_ptr.hpp>  
    12. #include <boost/array.hpp>  
    13.   
    14. #include <iostream>  
    15. #include <string>  
    16.   
    17. //使用UDP命名空间  
    18. using boost::asio::ip::udp;  
    19.   
    20. //把当前时间转换为字符串。  
    21. std::string make_daytime_string()  
    22. {  
    23.     using namespace std; //为了使用time_t, time 和 ctime;  
    24.     time_t now = time(0);  
    25.     return ctime(&now);  
    26. }  
    27.   
    28. //  
    29. //创建一个异步UDP的时间服务器。  
    30. //软件开发人员: 蔡军生  2013-08-25   
    31. //QQ: 9073204  
    32. //  
    33. class UdpTimeServer  
    34. {  
    35. public:  
    36.     //传入IO服务,然后创建一个UDP的SOCKET,IPV4版本,端号为13  
    37.     UdpTimeServer(boost::asio::io_service& ioService)  
    38.         :m_sockUdp(ioService,  udp::endpoint(udp::v4(), 13))  
    39.     {  
    40.         //进入接收服务中。  
    41.         RecvTime();  
    42.     }  
    43. private:  
    44.     //接收收客户端的请求。  
    45.     void RecvTime(void)  
    46.     {  
    47.         //异步接收数据  
    48.         m_sockUdp.async_receive_from(  
    49.             boost::asio::buffer(m_recvBuf), m_endpointRemote,  
    50.             boost::bind(&UdpTimeServer::handleRecvTime, this,  
    51.             boost::asio::placeholders::error,  
    52.             boost::asio::placeholders::bytes_transferred));  
    53.     }  
    54.   
    55.     //当收到客户端数据时,就进入本函数响应处理  
    56.     void handleRecvTime(const boost::system::error_code& error,  
    57.         std::size_t /*bytes_transferred*/)  
    58.     {  
    59.         //如果没有出错,就把时间字符串发送给客户端。  
    60.         if (!error || error == boost::asio::error::message_size)  
    61.         {  
    62.             boost::shared_ptr<std::string> strMessage(  
    63.                 new std::string(make_daytime_string()));  
    64.   
    65.             m_sockUdp.async_send_to(boost::asio::buffer(*strMessage), m_endpointRemote,  
    66.                 boost::bind(&UdpTimeServer::handleSendTime, this, strMessage,  
    67.                 boost::asio::placeholders::error,  
    68.                 boost::asio::placeholders::bytes_transferred));  
    69.   
    70.             //接收下一次的信息。  
    71.             RecvTime();  
    72.         }  
    73.     }  
    74.   
    75.     //当发送时间字符串给客户端成功之后响应。  
    76.     void handleSendTime(boost::shared_ptr<std::string> /*strMessage*/,  
    77.             const boost::system::error_code& /*error*/,  
    78.             std::size_t /*bytes_transferred*/)  
    79.     {  
    80.   
    81.     }  
    82.   
    83. private:  
    84.     udp::socket m_sockUdp; //服务器的SOCKET。  
    85.     udp::endpoint m_endpointRemote; //收到数据时的端点信息。  
    86.     boost::array<char, 1> m_recvBuf; //接收数据缓冲区。  
    87. };  
    88.   
    89. void TestUdp(void)  
    90. {  
    91.     boost::asio::io_service ioService;  
    92.     UdpTimeServer udpTimeServer(ioService);  
    93.     ioService.run();  
    94. }  
    95.   
    96.   
    97. int _tmain(int argc, _TCHAR* argv[])  
    98. {  
    99.     //  
    100.     TestUdp();  
    101.   
    102.     return 0;  
    103. }  

    在这个例子里,主要封装了一个服务器UdpTimeServer,它是采用io_service对象和socket对象的异步特性来构造,有事件响应之后才去执行相应的操作,不过这样比前面的同步方式,还是复杂了一些,但带来了避免多线程之间的同步问题。

  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/4453016.html
Copyright © 2011-2022 走看看