用完成端口搭建自己的网络应用服务

来源:互联网 发布:知乎诈骗 童谣 编辑:程序博客网 时间:2024/05/06 07:01

  最近常看见关于完成端口的讨论,对其实现颇为好奇,于是经过多日连续奋战,终于对完成端口进行了完整封装,这里谈谈我搭建的架构模型。

 设计思路:

 一、系统分为工作线程,AcceptEx投递线程,处理线程,资源回收线程四类线程

 1.1、工作线程若干个,用于处理网络事件方面工作,如处理:客户端接收工作,数据接收
  后进行简单的分包并加入到请求包队列中,数据发送完毕后负责检查是否发送
  完毕,没有发完,则继续发,发送完毕后,改变发送包标志,由回收线程回收

 1.2、AcceptEx投递线程负责投递AcceptEx,通过事件来检测是否需要投递新的AcceptEx
  ,同时,投递的AcceptEx的数量会根据客户端接收的情况动态更改,如果同时间
  有很多客户端在连接,会一次投递更多的AcceptEx

 1.3、处理线程负责处理请求包,线程依然有若干个,同时检测请求包队列,如果收到一个
  请求包,则将其从队列中取出,并做相应的业务处理.可以通过继承CIOCPManager
  并重载OnRequest来进行自己的处理。
  处理线程中当然会有需要发送的数据,这时,调用CIOCPManager的函数SendBuffer
  进行发送,个人觉得没有必要设置一个发送线程来处理这些发送数据。

 1.4、资源回收线程负责对系统的资源进行管理,主要有两方面:1,对投递的发送包进行
  监测,回收一些已经发送完毕的发送包.2,对客户端列表进行检测,如果一个
  客户端的非活动时间超过一定范围后,将客户端关闭并回收

 二、其他细节
 
 2.1、关于工作线程和处理线程的数量,目前是根据系统允许的最大连接数来设置,使用
  每200个客户端使用一个工作线程,每100个客户端使用一个工作线程,如果需要
  更改,请修改配置文件,注意要将系统自动设置设置为0

 2.2、关于一次投递AcceptEx的数量,默认是投递10个,如果很短时间内有多个客户端连接
  那么,每一次事件被激发后,投递数量都比上一次多一倍,当然系统设有最大数量
  在配置中可以修改.

 三、使用方法
 可以通过添加一个自定义的类,继承自CIOCPManager类,重载OnRequest函数,在其中进行
  响应的处理操作。

 CTransFileServer Thread;

 unsigned nThreadID = 0;

 if(Thread.Init(_T("C://ICOPServer.ini")))
 {
  if(Thread.Listen())
  {
   //创建一个响应用户操作的线程,用于停止客户端
   _beginthreadex(NULL, 0 ,ExitThread ,(void*)&Thread , 0, &nThreadID);
   Thread.Run();
  }
 }

 四、优化方法
 1、减少memset的使用。该操作消耗cpu时间比较多,可以通过设置缓冲区内数据长度来控制。
 2,使用优化的memcpy代替原来的memcpy,可以查看:
  http://www.blogcn.com/user8/flier_lu/blog/1577430.html
  http://www.blogcn.com/user8/flier_lu/blog/1577440.html
 3,减少使用memcpy,收到数据后,可以一次封装到请求包中时,直接拷贝过去,而不使用
  先拷贝到接收缓冲区,然后在分析是否能封装请求包。
 4,处理线程应该是先挂起,当有请求时,将请求分给某一个挂起的线程,让其处理。如果
  所有线程都忙,应该新建处理线程。如果处理线程达到一定数量后,应该让请求等待。
 5,客户端退出时,应该通知上层业务处理线程,以便删除相关资源
 6,查找一个挂起的处理线程目前还是顺序查找,应该设计一种更好的查找算法

 

原创粉丝点击