IOCP_API组件来搭建TCP服务器

转自论坛:http://topic.csdn.net/u/20110127/16/e4da4738-9be3-45bb-bf9c-9e46ebce98e7.html?42267

本文基于沈毅(shenyi0106@163.com qq:52851771)所提供的IOCP_API组件来搭建TCP服务器。

下载地址: http://download.csdn.net/source/2960211

  本文适用于对winsock有一定了解的开发者,当然,如果你不了解winsock也没有关系,IOCP_API为您提供了高度封装的API,您只需要定义几个回调函数,调用几个API即可完成服务器搭建工作,使您可以专注于业务逻辑处理,而无需了解了解通讯底层。

  如果您需要解压缩支持,可以加上Compress.h头文件;如果需要提供大数据包支持,可以加上Packet.h头文件。

    
  下面将介绍如何使用IOCP_API组件:
  首先,导入IOCPServer.h头文件。如果你的工程中不包括socket支持,那查看IOCPServer.h头文件,将部分注释打开。
  其次,定义回调函数。共有三个回调函数,分别是数据处理回调,连接处理回调和连接关闭回调,定义格式如下:

 
C/C++ code
   
   
// 数据处理回调 void DataProcCallBack(SOCKET socket, char * recvBuf, int len); // 连接处理回调 BOOL OnConn(SOCKET socket, char * ip, int port); // 连接关闭回调 void OnClientClose(SOCKET socket, char * ip, int port);

  如果是定义类成员函数,请将函数定义成静态成员函数,原因省略万字......

  再次,调用IOCP_API的函数初始化并启动服务器:
 
C/C++ code
   
   
HANDLE m_hIocp = IOCPInitServer(DataProcCallBack,OnConn,OnClientClose, 4 , 5000 , 10 );
其中各个参数的意义,请参考IOCPServer.h头文件中的说明。

 
C/C++ code
   
   
// 设置服务器参数(可选) IOCPSetMaxAccept( 20000 ); // 设置最大可以接受的客户端数量 IOCPSetTickTime( 300 ); // 设置服务器心跳检测的间隔时间,单位是秒

  最后,如果你在初始化时已经设置了线程池模式,那么你只需要在你的DataProcCallBack函数里专心处理你自己的业务逻辑即可。当然这里不用线程池模式也可以,完全取决于你自己的业务需求。
    
  如果需要回发数据,通过IOCPSend函数发送。

  在此组件中还提供很多其他的辅助功能,比如:
  调用IOCPCloseClient可以强制关闭某个连接,IOCPGetClientCount可以获得当前客户端数,IOCPGetSocketName获得本地IP信息,IOCPGetPeerName获得远端IP信息,
  IOCPSetUserData可以设置句柄相关的任何数据,IOCPGetUserData获得句柄相关的任何数据。

  性能怎么说呢,由于没有测试环境,只做过三四台机器5K多的echo(500ms间隔)并发测试,服务器是普通的双核PC,100M网络,只能说资源占用率比较低,CPU控制在10%以下,内存占用也很低。

  程序的不足:
  1. 采用Accept + 线程模式来接受客户端连接,在大规模并发连接时会丢失一些客户端连接。
  2. 由于采用了内存池管理内存,所以长时间运行不会出现过多的内存碎片,但是由于所采用的内存池是只增加不减少的,也就导致长时间大规模处理数据时,会导致内存上涨,但是业务量下降时,内存占用量并不会减小。

  3.虽然写这个库已经有一段时间了,但是由于对IOCP的理解可能还不是那么好,组件难免回有问题,也请大家多多指教。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 连接oracle时,目录中不能有()字符,否则ADO是无法连接数据库的 修改: 2.1 去掉TCPChannel的BuildPacket函数,改成直接由OnRecv回调函数返回实际数据 去掉UDPChannel的Response函数,改成直接由内部处理 2.2 修改TCPChannel类,实现同步调用接口 定义IRPC接口用来处理同步调用的被调用端 定义Bind函数用来绑定IRPC接口的实例 定义CallEx函数用来实现用户同步调用 2.3 添加bInit变量,用于设置初始化和关闭状态。 设置此变量的目的主要是用来控制,在关闭了socket之后,后续的任何投递都不执行。 修改了IRPC接口名称为IRemoteProcCall,并且调整了部分结构体名称,如RPC相关的结构体, 组合包相关的结构体,以及P2P相关的结构体。 修改TCPChannel类的接口函数Bind成BindEx,使之与TCPChannel的其他接口统一命名。 修改测试Demo,添加多发选项 修改DataType.h中的内存块大小定义 封装临界区类,信号量类 修改TCPListener接口类中的EnumSockets接口,添加pArg参数 Socket类添加ReUseAddr函数,用来设置端口重用 TCPSocket接口类添加GetListener接口用来获得链接管理对象 修改Demo实例中的TCP客户端部分,增加可更改客户端连接数 2.4 添加UDT支持 修改UDPChannel接口类,添加UDT支持接口函数 添加日志支持 添加接口类ILogger,用来实现对日志的输出 添加x64的编译环境 添加部分WARN级别的日志输出 添加C接口,方便非C++语言应用 UDT添加特性,关闭UDT时,给对端发送断线信息,通知对端断线 UDT提高效率,UDT句柄部分改用读写锁来控制,以提高效率 修改OnSend和OnSendTo的行为 修改过的BUG: 1. 数据发送时,如果数据大小正好是MAX_PACKET_SIZE个字节的话,数据发送不出去,在计算包大小时,边界值没处理好。 2. IOCPUnhandledException函数内部逻辑错误,没有关联到自己的异常处理函数中,导致即使调用成功,程序异常了,也无法写dump文件。 3. 修复IOCP UDP Release模式下不能正常运行的BUG。由于传递的输出参数使用了局部变量导致的问题 4. 修复UDT发送时,计算尾包大小错误 5. 修复UDT快速发送错误 6. 修改Queue关闭时,如果有线程正在等待信号,会导致线程死等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值