• 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对象的异步特性来构造,有事件响应之后才去执行相应的操作,不过这样比前面的同步方式,还是复杂了一些,但带来了避免多线程之间的同步问题。

  • 相关阅读:
    一步完成 MySQL 向 Redis 迁移
    php7性能、兼容性和稳定性探讨
    【高并发简单解决方案】redis缓存队列+mysql 批量入库+php离线整合
    Nginx的Rewrite正则表达式,匹配非某单词
    ajax下载,前端js下载(转)
    根据马甲、应用商店、统计每天的注册量,要求可以根据选择马甲和app,马甲和appstrore和user_login不同表问题
    别名的使用注意,""真坑。
    策略模式Strategy
    关于poi操作excel我使用的一些修饰操作
    java的代理(编程思想)
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/4453016.html
Copyright © 2020-2023  润新知