跨平台网络库(采用C++ 11)

I:跨平台设计基础

在windows下使用0字节的WSARecv/WSASend(读写)作为读写检测,将IOCP作为一个通知模型,而"抛弃"它的异步模型。

即:把它当作epoll来用。使得(方便)网络库的设计(譬如socket的读写处理)在windows和linux下实现统一:  底层获得读写通知,应用层(网络库中)自己处理读写。

II:单线程EventLoop

1:EventLoop是一个单线程的网络IO循环,使用一个iocp(epoll)实例,管理多个DataSocket。

通过EventLoop的addConnection接口为它添加DataSocket(并传入一个回调),并会在EventLoop接手它后触发传入的回调函数--处理链接建立之后的业务逻辑。

DataSocket 即为一个客户端连接-会话,用户可以为它设置事件回调函数。

setDataHandle:设置收到消息后的回调函数。

setDisConnectHandle:设置链接断开后的回调函数。

当然我们也可以通过disConnect主动断开会话的网络连接。

2:EventLoop实现线程安全的wakeup和异步消息队列,用于外部逻辑线程投递异步操作(以及唤醒,以让eventloop尽可能更快的处理请求)。

3:std::shared_ptr作为packet类型,用于将同一个packet投递给多个客户端DataSocket(避免分配多个消息),DataSocket 内置一个队列,保存当前pending在它上的待发packet list。

之所以采用std::shared_ptr,是因为它自带引用计数处理,可以方便的应对同一个消息包发送给多个客户端时,消息包的分配和释放问题(即此消息全部发送给它的目的客户端,那么此消息就可以回收),

无需自己再写一套消息包设计了。

注:目前linux下给客户端flush发送网络消息时,采用writev提高效率,但windows上没有找到相关函数(WSASend不满足要求),但可以在某些时候将消息memcpy到一个缓冲区,然后一次性send(以减少send系统调用次数))。

III: 封装EventLoop的TCPServer

1:TCPServer处理Listen逻辑以及为新到的链接分配(通过EventLoop的addConnection接口)一个EventLoop。

2!:可从源码中看到DataSocket的事件回调函数所附带的参数是DataSocket*, 但是 TcpServer回调函数参数中,表示会话标识的类型为:int64 id,而非裸指针。

这是因为TCPServer多被用于多线程设计,此时会话的有效性(避免串话)(以及内存的有效性-野指针问题)需要保证,而裸指针并非安全的。

3:第二点说到TcpServer多用于多线程设计时,具体如下:

在它的回调函数中,我们可以将消息投递到一个逻辑线程的消息队列,并wakeup逻辑线程的EventLoop),当逻辑线程被唤醒后,从消息队列中同步读取消息,然后处理。

而当逻辑线程需要发送消息则使用: TCPServer的send接口,参数是一个int64_t id 表示要发送消息的会话,紧接着是一个Packet,表示消息内容。

当然!:TCPServer的回调函数中可以立即处理,而非投递到别的线程进行协作,这样用起来当然更简单了。

譬如在某些网络服务中,不需要很耗时的处理,而仅仅是IO密集型(比如网关),  那么建议直接在回调函数中进行处理(譬如转发)。

注: 此网络库参考了 muduo:https://github.com/chenshuo/muduo

另外致谢:sniperhw:http://www.cnblogs.com/sniperhw 近几年的指点

网络库代码地址: https://github.com/IronsDu/accumulation-dev/tree/master/examples/DNet/

目前main.cpp实现的是一个ping pong测试(一个进程内:服务器用TCPServer,用多个客户端线程跑各自的EventLoop)。

从main.cpp也可以看到 单线程EventLoop和TCPServer多线程加消息队列的使用方式。

(VS版本至少 VS2013)(Linux下的话就麻烦g++ /DNet下的那几个cpp文件吧,有几个头文件在根目录的/common和/cpp_common目录)。

(g++ -I../../../common -I../../../cpp_common eventloop.cpp datasocket.cpp TCPServer.cpp main.cpp -std=c++0x -lrt)

TODO::代码中有一些TODO,表示晦涩或者我不太确定没问题~HOHO

另外我很期待后面要做的广播测试(类似MMO的AOI,多个玩家同时移动,要广播给周围N个玩家)。

目前ping pong测试(客户端和服务器在同一个进程内,编译时不开任何优化)在我的机器(AMD Athlon(tm) 7750 Dual-Core Processor,1.3G Hz, CentOS 6.3):

1:TCPServer使用一个线程,并将收到的消息投递到逻辑线程进行ping pong处理。

100个链接,消息包大小为4K,每秒吞吐为190M/s。

1000个链接,消息包大小为4K,每秒吞吐为135M/s。

10000个链接,消息包大小为4K,每秒吞吐为125M/s。

2:TCPServer使用一个线程,直接在自身的消息回调函数中进行ping pong处理。

100个链接,消息包大小为4K,每秒吞吐为315M/s。

1000个链接,消息包大小为4K,每秒吞吐为190M/s。

10000个链接,消息包大小为4K,每秒吞吐为160M/s。

时间: 2024-10-28 21:44:14

跨平台网络库(采用C++ 11)的相关文章

2 C++ ACE 面向对象跨平台网络库学习

2   C++ ACE  面向对象跨平台网络库学习  ACE I/O相关对象 阻塞式 TCP连接Linux Kernel网站服务器的443端口 非阻塞模式 TCP连接百度服务器 设置 TCP连接超时: ACE 客户端 TCP模式.请求HTTP 一个简单的 TCP HTTP server HTTP server 代码 创建网页文件 浏览器测试访问结果 ACE UDP通信单播测试: UDP 单播 服务器端: UDP 单播 客户端: ACE UDP 多播实验: UDP 多播 发送端程序: UDP 多播

跨平台网络库

I:跨平台设计基础 在windows下采用0字节的WSARecv/WSASend(读写)作为读写检测,将IOCP作为一个通知模型,而"抛弃"它的异步模型. 即:把它当作epoll来用.使得(方便)网络库的设计(譬如socket的读写处理)在windows和linux下实现统一:  底层获得读写通知,应用层自己处理读写. II:单线程EventLoop 1:EventLoop是一个单线程的网络IO循环,使用一个iocp(epoll)实例,管理多个DataSocket. 通过EventLo

0806------Linux网络编程----------Echo 网络库 学习笔记

1.Echo网络库的编写 1.1 Echo网络库1.0 1.1.1 Echo网络库 1.0 框架分析 a)class InetAddress: 主要用来定义一个struct sockaddr_in 结构(用自定义端口号初始化),并提供获取这个结构体成员如IP.Port等的接口: b)class Socket : 主要用来把一个普通的 sockfd 变为 listenfd(这里用一个sockfd初始化对象),提供bind .listen.accept 等接口. c)class TcpConnect

C++实现,支持跨平台(Windows,Android,IOS),支持跨语言(C++,C#,Java)的网络库

这个网络库是在 CppNetworkLibrary(http://www.cnblogs.com/winter-yu/p/4688481.html )的基础之上做的一些优化与调整. 具体的亮点如下: 1,支持跨跨平台,包括主流的Windows,Android,IOS,Linux等等. 2,跨语言,客户端支持C++,C#,Java.服务端目前只支持C++. 3,数据包增加了加密及压缩功能,密码会动态随机修改,而不是双方都使用固定密码,保证了数据包的传输安全. 4,客户端支持P2P的消息传输,而不需

基于c++11新标准开发一个支持多线程高并发的网络库

背景 新的c++11标准出后,c++语法得到了很多的扩展,比起以往任何时候都要灵活和高效,提高了程序编码的效率,为软件开发人员节省了不少的时间. 之前我也写过基于ACE的网络服务器框架,但ACE毕竟有些臃肿,内部对象关系错综复杂,容易给人造成只见树木不见森林的错觉. 所以打算用c++11开发一个较为简洁,高效,支持高并发的网络库. 开源         花了两三周,终于把基础的结构开发完成,代码也开源在github上,网址是 https://github.com/lichuan/fly 欢迎各位

使用C++11网络库Handy进行服务器端编程

Handy是一个简洁优雅的C++11网络库,适用于linux与Mac平台.十行代码即可完成一个完整的网络服务器. 下面是echo服务器的代码: #include <handy/handy.h> using namespace std; using namespace handy; int main(int argc, const char* argv[]) { EventBase bases; //事件分发器 Signal::signal(SIGINT, [&]{ bases.exit

boost.ASIO-可能是下一代C++标准的网络库

曾几何时,Boost中有一个Socket库,但后来没有了下文,C++社区一直在翘首盼望一个标准网络库的出现,网络上开源的网络库也有不少,例如Apache Portable Runtime就是比较著名的一个,也有像ACE这样重量级的网络框架.去年,Boost将ASIO纳入了自己的体系,由于Boost的影响力,ASIO有机会成为标准网络库.作者Chris Kohlhoff以ASIO为样本向C++标准委员会提交了一个网络库建议书,里面提到:ASIO的覆盖范围: Networking using TC

C++的开源跨平台日志库glog学习研究(二)--宏的使用

上一篇从整个工程上简单分析了glog,请看C++的开源跨平台日志库glog学习研究(一),这一篇对glog的实现代码入手,比如在其源码中以宏的使用最为广泛,接下来就先对各种宏的使用做一简单分析. 1. 日志输出宏 这里我们以一条最简单的日至输出为例说明: LOG(WARNING) << "This is a warning message"; 这里LOG是一个宏,其定义如下(logging.h line 487): #define LOG(severity) COMPACT

Linux多线程服务端编程:使用muduo C++网络库

内容推荐本 书主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread.这是在Linux下以native语言编写用户态高性能网络程序最成熟的模式,掌握之后可顺利地开发各类常见的服务端网络应用程序.本书以 muduo网络库为例,讲解这种编程模型的使用方法及注意事项.本书的宗旨是贵精不贵多.掌握两种基本的同步原语就可以满足各种多线程同步的功能需求,还能写出更易用的同步设施.掌