LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2077|回复: 4

高并发高性能的静态Web服务器+完成端口部分代码

[复制链接]
发表于 2007-4-1 04:32:16 | 显示全部楼层 |阅读模式
SmartHttpd 1.0.0.2

1.基于完称端口的静态Web服务器.
2.适合用户高并发高负荷的场合的静态页面场合特别适用于图片服务器.
3.为了满足高性能的要求以及保持灵活性,动态内容采用预留接口实现.
4.配置说明
  1)配置文件为当前目录下的config.ini
  2)ListenPort:指定绑定端口
  3)WWWRoot:静态页面内容所在目录
  4)AcceptExNum:可承受的突然并发连接(建议采用默认值)
  5)MaxWorkThread:工作线程数目(0代表根据CPU数目指定最佳值)
  6)ServiceName:安装后服务的名称

较1.0.0.1有多处改进,在17000个并发持续连接的情况下仍有良好的性能,改天放Linux下基于epoll模型的


  1. //完成端口的部分代码

  2. //主线程

  3. //创建原始完成端口句柄
  4. hIOCP=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
  5. if(NULL==hIOCP)
  6. {
  7.         //错误处理
  8. }

  9. //创建监听套节字 ListenPort()封装了bind listen等函数
  10. SocketListen=ListenPort();

  11. //绑定原始完成端口句柄到监听套节字SocketListen
  12. if(NULL==CreateIoCompletionPort((HANDLE)SocketListen,hIOCP,0,0))
  13. {
  14.         //错误处理
  15. }

  16. //投递AcceptEx
  17. {
  18.         unsigned long Num;
  19.         unsigned long AcceptExNum;

  20.         //GetConfigInt封装了读取配置文件
  21.         AcceptExNum=GetConfigInt("Httpd","AcceptExNum",2000);

  22.         //投递多个AccpetEx,PostAccpetEx封装了AccpetEx
  23.         for(Num=0;Num<AcceptExNum;Num++)
  24.         {
  25.                 PostAccpetEx(NULL);
  26.         }
  27. }

  28. {        //启动工作线程
  29.        
  30.         unsigned long        MaxWorkThread;
  31.         unsigned long        threadcount;
  32.         DWORD                        dwThreadId;
  33.         HANDLE*                        hThread;

  34.         //读取配置文件中开启线程的数目
  35.         MaxWorkThread=GetConfigInt("Httpd","MaxWorkThread",2);
  36.        
  37.         //0代表根据CPU数目设置线程数目 CPU数目*2+2
  38.         if(MaxWorkThread<1)
  39.         {
  40.                 SYSTEM_INFO systemInfo;
  41.                 GetSystemInfo(&systemInfo);
  42.                 MaxWorkThread=systemInfo.dwNumberOfProcessors*2+2;
  43.         }

  44.         hThread=HeapAlloc(GetProcessHeap(),0,sizeof(HANDLE)*MaxWorkThread);

  45.         for(threadcount=0;threadcount<MaxWorkThread;threadcount++)
  46.         {
  47.                 hThread[threadcount]=CreateThread(NULL,0,WorkerThread,hIOCP,0,&dwThreadId);
  48.         }

  49.         //等待工作线程退出,主线程进入阻塞状态
  50.         WaitForMultipleObjects(MaxWorkThread,hThread,TRUE,INFINITE);
  51.        
  52.         for(threadcount=0;threadcount<MaxWorkThread;threadcount++)
  53.         {
  54.                 CloseHandle(hThread);
  55.         }
  56.        
  57.         HeapFree(GetProcessHeap(),0,hThread);

  58. }



  59. //工作线程

  60. //LOOP循环条件,根据情况设定相应的条件
  61. while(LOOP)
  62. {
  63.         BOOL                        Succes;
  64.         P_IOCPDATA                IOCPData;//自己定义的数据结构
  65.         unsigned long        TransByte;
  66.         LPWSAOVERLAPPED        lpWsaOverlapped;

  67.         //获取完成通知
  68.         //完成端口的精华就在这里
  69.         //通过调用GetQueuedCompletionStatus,线程可以获得原子性的时间段,避免了线程切换的开销
  70.         Succes=
  71.         GetQueuedCompletionStatus(
  72.         hIOCP,
  73.         &TransByte,
  74.         (unsigned long*)&IOCPData,
  75.         &lpWsaOverlapped,
  76.         INFINITE);

  77.         if(Succes&&NULL!=lpWsaOverlapped&&TransByte)//完全正常
  78.         {
  79.                 IOCPData=(P_IOCPDATA)lpWsaOverlapped;

  80.                 //根据不同的I/O类型进行不同的处理
  81.                 switch(IOCPData->IOType)
  82.                 {
  83.                         //AcceptEx具有连接和接受的功能
  84.                         case AcptDone:
  85.                         {
  86.                                 //有一个AccpetEx完成,再投递一个AccpetEx
  87.                                 PostAccpetEx(NULL);
  88.                                 {
  89.                                         //此段代码可以不调用,未发生错误,不知道为什么,
  90.                                         //如果不调用的话,句柄不会很多,不会超出限制
  91.                                         /*
  92.                                         //更行AccpetEx返回的套节字状态
  93.                                         int        ErrorCode;
  94.                                         ErrorCode=
  95.                                         setsockopt(
  96.                                         IOCPData->Socket,
  97.                                         SOL_SOCKET,
  98.                                         SO_UPDATE_ACCEPT_CONTEXT,
  99.                                         (char*)&SocketListen,
  100.                                         sizeof(SocketListen)
  101.                                         );
  102.                                         if(SOCKET_ERROR==ErrorCode)
  103.                                         {
  104.                                                 Test();
  105.                                                 FreeIOCPData(IOCPData);
  106.                                                 continue;
  107.                                         }
  108.                                         */
  109.                                 }
  110.                                 //绑定AccpetEx返回的套节字到hIOCP
  111.                                 if(hIOCP!=CreateIoCompletionPort((HANDLE)IOCPData->Socket,hIOCP,(unsigned long)IOCPData,0))
  112.                                 {
  113.                                         Test();
  114.                                         FreeIOCPData(IOCPData);
  115.                                         continue;
  116.                                 }
  117.                                 //我写的是一个Web服务器,下面的是Http消息头的分析处理
  118.                                 if(HttpParseHead(IOCPData))
  119.                                 {
  120.                                         Respons(IOCPData);
  121.                                 }
  122.                                 break;

  123.                         }
  124.                         //...... 其他处理情况
  125.                 }
  126.         }
  127.         //.... 出现错误情况下的处理
  128. }
  129. //做人要厚道
  130. //转载请保留连接http://hi.baidu.com/xinglp
  131. //xlp1119@163.com,漫步黄昏
复制代码
发表于 2007-4-1 05:38:33 | 显示全部楼层
什么叫做 基于完称端口?新名词我想学习。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-4-1 09:53:42 | 显示全部楼层
就是一种I/O模型,比较高效的,和Linux得epoll差不多
回复 支持 反对

使用道具 举报

发表于 2007-4-6 16:30:16 | 显示全部楼层
好高深呀!看不懂,需要好好学习一下!!!
回复 支持 反对

使用道具 举报

发表于 2007-4-6 22:24:47 | 显示全部楼层
为什么带的是个W32文件?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表