boost库在工作(39)网络UDP异步服务端之九
前面创建的UDP服务器和客户端,都是同步的方式,也就是说当接收数据时,不能参与别的事情执行的。如果在一个只有界面线程的程序里,又不想创建多线程,导致复杂程度的增加,在这种情况之下,我们还有一个方案可以选择,就是创建一个异步的UDP服务器或客户端,这样既有单线程的简单性,也可以让客户随便操作界面的快速响应的特性。在boost库里使用io_service对象来实现异步是轻而易举的事情,因为封装的接口简单、明了。具体的代码如下:
- // boost_028.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <ctime>
- #include <boost/asio/ip/tcp.hpp>
- #include <boost/asio.hpp>
- #include <boost/bind.hpp>
- #include <boost/enable_shared_from_this.hpp>
- #include <boost/shared_ptr.hpp>
- #include <boost/array.hpp>
- #include <iostream>
- #include <string>
- //使用UDP命名空间
- using boost::asio::ip::udp;
- //把当前时间转换为字符串。
- std::string make_daytime_string()
- {
- using namespace std; //为了使用time_t, time 和 ctime;
- time_t now = time(0);
- return ctime(&now);
- }
- //
- //创建一个异步UDP的时间服务器。
- //软件开发人员: 蔡军生 2013-08-25
- //QQ: 9073204
- //
- class UdpTimeServer
- {
- public:
- //传入IO服务,然后创建一个UDP的SOCKET,IPV4版本,端号为13
- UdpTimeServer(boost::asio::io_service& ioService)
- :m_sockUdp(ioService, udp::endpoint(udp::v4(), 13))
- {
- //进入接收服务中。
- RecvTime();
- }
- private:
- //接收收客户端的请求。
- void RecvTime(void)
- {
- //异步接收数据
- m_sockUdp.async_receive_from(
- boost::asio::buffer(m_recvBuf), m_endpointRemote,
- boost::bind(&UdpTimeServer::handleRecvTime, this,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred));
- }
- //当收到客户端数据时,就进入本函数响应处理
- void handleRecvTime(const boost::system::error_code& error,
- std::size_t /*bytes_transferred*/)
- {
- //如果没有出错,就把时间字符串发送给客户端。
- if (!error || error == boost::asio::error::message_size)
- {
- boost::shared_ptr<std::string> strMessage(
- new std::string(make_daytime_string()));
- m_sockUdp.async_send_to(boost::asio::buffer(*strMessage), m_endpointRemote,
- boost::bind(&UdpTimeServer::handleSendTime, this, strMessage,
- boost::asio::placeholders::error,
- boost::asio::placeholders::bytes_transferred));
- //接收下一次的信息。
- RecvTime();
- }
- }
- //当发送时间字符串给客户端成功之后响应。
- void handleSendTime(boost::shared_ptr<std::string> /*strMessage*/,
- const boost::system::error_code& /*error*/,
- std::size_t /*bytes_transferred*/)
- {
- }
- private:
- udp::socket m_sockUdp; //服务器的SOCKET。
- udp::endpoint m_endpointRemote; //收到数据时的端点信息。
- boost::array<char, 1> m_recvBuf; //接收数据缓冲区。
- };
- void TestUdp(void)
- {
- boost::asio::io_service ioService;
- UdpTimeServer udpTimeServer(ioService);
- ioService.run();
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- //
- TestUdp();
- return 0;
- }
在这个例子里,主要封装了一个服务器UdpTimeServer,它是采用io_service对象和socket对象的异步特性来构造,有事件响应之后才去执行相应的操作,不过这样比前面的同步方式,还是复杂了一些,但带来了避免多线程之间的同步问题。
boost库在工作(39)网络UDP异步服务端之九的更多相关文章
- TCP/IP网络编程之基于UDP的服务端/客户端
理解UDP 在之前学习TCP的过程中,我们还了解了TCP/IP协议栈.在四层TCP/IP模型中,传输层分为TCP和UDP这两种.数据交换过程可以分为通过TCP套接字完成的TCP方式和通过UDP套接字完 ...
- 【gRPC】C++异步服务端优化版,多服务接口样例
官方的C++异步服务端API样例可读性并不好,理解起来非常的费劲,各种状态机也并不明了,整个运行过程也容易读不懂,因此此处参考网上的博客进行了重写,以求顺利读懂. C++异步服务端实例,详细注释版 g ...
- boost库在工作(37)网络UDP服务端之七
前面介绍的都是网络TCP的服务器和客户端,其实还有UDP的服务器和客户端,同时也有同步和异步之分.UDP与TCP最大的区别,就是TCP是基于连接的,而UDP是无连接的.这里所谓的连接是指对方中断服务时 ...
- boost库在工作(32)网络服务端之二
在这个例子里,服务器对象主要使用boost::asio::io_service对象,这个对象主要用来构造异步接收数据使用,接着定义boost::asio::ip::tcp::acceptor对象,这个 ...
- boost库在工作(36)网络服务端之六
在上面介绍了管理所有连接的类,这个类主要就是添加新的连接,或者删除不需要的连接.但是管理的类CAllConnect是没有办法知道什么时候添加,什么时候删除的,它需要从接收到连接类里获取得到新的连接,从 ...
- boost库在工作(15)绑定器与函数对象之三
前面已经可以优美地解决两个参数的函数给算法for_each调用了,但是又会遇到这样的一种情况,当需要三个参数或者三个以上的参数给算法for_each调用呢?从STL里的绑定器bind1st,显然是不行 ...
- boost库在工作(40)串行通讯
现代的计算机技术进步很快,各种的通讯也日新月异,像USB.网络.蓝牙.WIFI等通讯技术飞速地出现,改变了整个计算机的通讯能力,速度已经达到GBit级别.但是有一种最原始的通讯方式,还是保留了30年, ...
- 第5章-unix网络编程 TCP/服务端程序示例
这一章主要是完成一个完整的tcp客户/服务器程序.通过一很简单的例子.弄清客户和服务器如何启动,如何终止,发生了某些错误会发生什么.这些事很重要的 客户端代码 #include "unp. ...
- Socket 学习(三).2 udp 穿透 服务端 与 客户端 通讯
之前演示的 是 局域网通讯,也可以用作服务器之间的通讯,不能穿透. 想要穿透就要用 udp 了, 后续再讲解 udp 打洞 . 客户端: using System; using System.Wind ...
随机推荐
- PHP5生成图形验证码(有汉字)
利用PHP5中GD库生成图形验证码 类似于下面这样 1.利用GD库函数生成图片,并在图片上写指定字符 imagecreatetruecolor 新建一个真彩色图像 imagecolora ...
- Sublime text3配置LiveReload
Tip: LiveReload是很棒的插件,可以在浏览器中实时预览,但是在Sublime text3里,从Package Control中安装的LiveReload是无法使用的,但是可以选择手动安装解 ...
- LDAP禁止匿名访问
LDAP默认是允许用户匿名访问的,如下图:在使用工具连接时,勾选匿名绑定后,不需要输入UserDN和密码就可能连接到LDAP服务器,但是只能进行read及search操作.不能做任何的修改及删除操作. ...
- 关于java中根据身份证求生日和年龄的问题
/*这个也没什么大的功能,也没什么安全验证,只是对输入的身份证号码的长度进行了验证.其他的功能可以自己添加.*/import java.util.*; import java.util.Scanner ...
- html中行内元素与块级元素的区别。
在标准文档流里面,块级元素具有以下特点 1.总是在新行上开始,占据一整行: 2.高度,行高以及外边框和内边距都可以控制: 3.宽度始终是与游览器宽度一样,与内容无关: 4.它可以容纳内联元素和其他块级 ...
- Js字面变量,定义问题
Js字面变量.浏览器的版本问题:
- (转)深入理解 __doPostBack
在我的随笔<Page,你是怎样处理回发事件的?>中曾提出一个疑问,如何得到引起页面PostBack的控件?通过阅读Page类的源码,误打误撞,无意中看到了__EVENTTARGET和__E ...
- Android Studio ---------------常用快捷键(更新中。。。。。。)
##常用快捷键: Ctrl+X(或Y) 删除行 Ctrl+D 复制行 Ctrl+Alt+L 格式化代码 Ctrl + Alt + V 提取变量 Shift+F6 重命名 Ctrl+F12显示当前文件的 ...
- keil中查看内存数据
1.工具栏中 view->Memory Windows 然后 c:0 表示读取0地址开始的代码区数据 d:0 表示读取0地址开始的数据区数据 x:0表示读取0地址开始的外部数据区
- android单选按钮选择,RadioGroup,radioButton
android单选按钮选择,RadioGroup,radioButton 14. 四 / android基础 / 没有评论 单选布局绑定 如何识别选择