IOCP完全开发经验总结(一):简介

背景

在2016年的时候,自己做的一个游戏项目英语杀(C++/Qt)游戏后台使用了很普通的socket连接方式:一个socket+一个线程模式,这种模式连接几百个客户端应该没问题,成千上万个就不行了。虽然当时项目还用不到,但抱着技术第一的态度在网上搜了很久的文章,最终确定了学习和开发IOCP来解决高并发的问题(当初并不知道有libevent、libuv这些库的存在,所以才入了坑),前前后后开发和维护了近4年,看了相当多的IOCP源码(古今中外都有),也解决了非常多的问题和坑,目前项目的生产环境很稳定,阿里云最低配的云主机(1核1G)运行无压力,现就开发时遇到的所有问题统一做一个分析和解答系列文章。

简介

一、后台框架:

1、IOCP内核库

库使用VC6开发(因为编译和运行快,文件小,依赖少),整体就是一个dll,主要封装了IOCP的核心代码,提供了非常多的C函数供使用。

2、Qt封装IOCP的库

这是第一层封装,将Dll库封装为一个类,完成了所有导出函数、句柄的封装,和IOCP库的载入和卸载。

3、Server封装

这是第二层封装,主要加入和解决了以下问题:
1、TCP数据的粘包处理,定义了数据的类型、简单验证、加密等。
2、随机数的同步。
3、定义了用户、群、群主的数据结构和功能,完善了群的管理(包括查找、进入和离开群,创建和解散群,群主的更换和T人,群数据发送和用户信息同步等)。

4、GameServer封装

这主要实现了业务逻辑,也做了其他一些亮点功能,比如多线程完成日志的记录、数据库的查询等。

二、内核库介绍

1、心跳机制

windows系统内核的TCP协议里并没有实现心跳,导致客户端异常断开后无法检测到,所以自己实现了一套写在了核心代码里。

2、自定义程度高

导出的函数中有很多set开头的函数,让开发者自定义某些IOCP的运行机制。

3、回调函数

因为库接口是C,所以只能使用回调函数的机制来运行开发者代码,缺点是使用难度有所提高,但我封装的每一层都有回调函数的示例,参照着写即可。

4、池

内核主要有两个池:SocketContext池和IOContext池,运行起来后不会频繁的new和delete,而是通过池来分配和回收,大大降低了new和delete的开销。

5、收发各使用一个IOContext

Send维护一个发送队列,且发送一个包的最大长度是8192左右,内核发送大数据时按照这个包自动拆分包,且完善了发送错误处理。

6、锁

把这个单独提出来是因为之前的代码里用到了至少3个锁,分别用来保护两个池和一个SocketClient队列,最近我把内核重新进行了大的重构,把这三个锁都去掉了,实现了无锁IOCP,后期的文章里会慢慢进行说明。

7、其他

内核还处理了各式各样的异常和错误。目前就想起来这么多,除了IOCP核心代码是用小猪的更改而来(修改达到70%左右吧),其他的全部都是自己设计和编写的,后期也会进行开源。顺带说一句,用C++开发全栈真是活的不耐烦了。。。

原理和参考

原理方面的东西我就不赘述了,我是直接从最low模型到IOCP模型的,中间还有其他异步模型,因为都不如IOCP我就直接跳过,这里只讲一些小猪的代码里没提到的坑。关于其他异步模型和IOCP的原理、简单实现只需参考小猪的一篇文章就行:

完成端口(CompletionPort)详解 - 手把手教你玩转网络编程系列之三

我的git地址(英语杀):https://gitee.com/leamus
IOCP的git地址:https://gitee.com/leamus/iocp_leamus
讨论QQ群:950384383

最近在开发im服务器 需要大并发链接 QT默认的是使用select模型的 这种轮询方式非常慢 在高并发连接 我们需要epoll才能发挥linux服务器的性能 而且使用简单 整个服务端代码架构无需修改 直接可以使用 只要在 main文件添加: int main int argc char argv[] { #ifdef Q OS LINUX QCoreApplication::setEventDispatcher new EventDispatcherLibEvent ; qInstallMessageHandler customMessageHandler ; #endif QCoreApplication a argc argv ; auto ser new ConfigServer; ser >startServer ; return a exec ; } 在 pro文件添加 linux{ LIBS + levent core SOURCES + common eventdispatcher libevent eventdispatcher libevent cpp common eventdispatcher libevent eventdispatcher libevent config cpp common eventdispatcher libevent eventdispatcher libevent p cpp common eventdispatcher libevent socknot p cpp common eventdispatcher libevent tco eventfd cpp common eventdispatcher libevent tco pipe cpp common eventdispatcher libevent tco cpp common eventdispatcher libevent timers p cpp HEADERS + common eventdispatcher libevent common h common eventdispatcher libevent eventdispatcher libevent h common eventdispatcher libevent eventdispatcher libevent config h common eventdispatcher libevent eventdispatcher libevent config p h common eventdispatcher libevent eventdispatcher libevent p h common eventdispatcher libevent libevent2 emul h common eventdispatcher libevent qt4compat h common eventdispatcher libevent tco h common eventdispatcher libevent wsainit h } 可以直接跨平台了使用了 csdn博客:http: blog youkuaiyun.com rushroom">最近在开发im服务器 需要大并发链接 QT默认的是使用select模型的 这种轮询方式非常慢 在高并发连接 我们需要epoll才能发挥linux服务器的性能 而且使用简单 整个服务端代码架构无需修改 直接可以使用 只要在 main文件添加: [更多]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值