专栏首页高性能服务器开发windows完成端口(三)

windows完成端口(三)

系列目录 windows完成端口(一) windows完成端口(二) windows完成端口(三) windows完成端口(四) windows完成端口(五) windows完成端口(六)

1

现在还剩下最后一个问题,就是工作线程如何退出。当然你可以在每次判断标识位前先判断一个退出标识。但是如果工作线程正好被GetQueuedCompletionStatus挂载那里呢?如何唤醒,微软提供了另外一个函数:PostQueuedCompletionStatus,看下这个函数的签名:

BOOL WINAPI PostQueuedCompletionStatus(  
  _In_     HANDLE       CompletionPort,  
  _In_     DWORD        dwNumberOfBytesTransferred,  
  _In_     ULONG_PTR    dwCompletionKey,  
  _In_opt_ LPOVERLAPPED lpOverlapped  
);  

这个函数可以唤醒被GetQueuedCompletionStatus函数挂起的工作线程,当然其第三个参数也是一个CompletionKey(dwCompletionKey)。你可以使用这个dwCompletionKey做标识干一些其它的事情,当然设置一个退出码也可以。例如:

PostQueuedCompletionStatus(m_hIOCompletionPort, 0,
                           (DWORD)EXIT_CODE, NULL);  

这样工作线程里面就可以使用EXIT_CODE来作为退出标志:

DWORD ThreadFunction()  
{  
    OVERLAPPED           *pOverlapped = NULL;  
    PER_SOCKET_CONTEXT   *pSocketContext = NULL;  
    DWORD                dwBytesTransfered = 0;  

    BOOL bReturn = GetQueuedCompletionStatus(m_hIOCompletionPort, 
                                             &dwBytesTransfered, 
                                             (PULONG_PTR)&pSocketContext,
                                             &pOverlapped, INFINITE);  

    // 如果收到的是退出标志,则直接退出  
    if ( EXIT_CODE==(DWORD)pSocketContext )  
    {  
        return 0;  
    }  

    if (((SOME_STRUCT*)pSocketContext)->s == 侦听socket句柄)  
    {  
        /*连接成功后可以做以下事情:  
         1. 获取对端和本端的ip地址和端口号,
            即AcceptEx的第三个参数lpOutputBuffer中拿
            (这一步,不是必须)  
         2. 如果对端连接成功后会发数据过来,
            则可以从初始化时调用AcceptEx准备的缓冲区里面拿到
            即AcceptEx的第三个参数lpOutputBuffer中拿
           (这一步不是必须)  

         3. 再次调用AcceptEx补充一个sAcceptSocket
           (这一步是必须的)  

         4. 调用WSASend准备发送数据工作
            或调用WSARecv准备接收数据工作(这一步,不是必须)*/ 
    }  
    //普通客户端socket收发数据  
    else  
    {  
        //通过pOverlapped结构得到pIOContext  
        PER_IO_CONTEXT* pIOContext = (PER_IO_CONTEXT*)pOverlapped;    
        if (pIOContext->Type == 收)  
        {             
            //解析收到的数据(这一步,不是必须)  
            //调用WSASend准备发送数据工作(比如应答客户端)(这一步,不是必须)  
            //继续调用WSARecv准备收取数据工作(这一步,不是必须)  
        }  
        else if (pIOContext->Type == 发)  
        {  
            //调用WSARecv准备收取数据工作(这一步,不是必须)  
        }  
    }  

    return 0;  
}  

至此,关于完成端口的东西就全部介绍完了。我们小结一下,掌握完成端口的关键在于理解以下几点:

  1. 完成端口绑定了某个socket后,不仅其事件的读写检测由操作系统完成,而且就算是接受新连接、收发数据的动作也是由操作系统代劳了,操作系统完成后会通知你。等你收到通知时,一切都完成好了。你可以直接取出对应的数据使用。
  2. 要想第1点介绍的事情由操作系统代劳,你必须预先准备很多数据结构,比如两端的地址结构体、收发缓冲区、和用来表示新连接的socket等等,这些准备工作可能在程序初始化阶段,也可能在工作线程某个事件处理的地方。
  3. 初始化准备好的各种缓冲区如何在工作线程里面引用到的关键就在于绑定完成端口时CompletionKey和准备收发缓冲区时OVERLAPPED结构体的使用, CompletionKey对应PER Socket Data, OVERLAPPED对应Per IO Data,即CompletionKey是单Socket数据,OVERLAPPED是单IO数据。

由于公众号文章字数有限,您可以接着阅读下一篇:《windows完成端口(四)》 系列目录 windows完成端口(一) windows完成端口(二) windows完成端口(三) windows完成端口(四) windows完成端口(五) windows完成端口(六)

本文分享自微信公众号 - 高性能服务器开发(easyserverdev)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-04-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何做压测?

    在开始做压测计划之前,一定要先明确压测的目标是什么,虽然最终的目标肯定都是优化系统的性能,但是不同的出发点,可能需要采取不同的方法。

    范蠡
  • 大量的 TIME_WAIT 状态连接怎么处理?(文末有福利)

    Nginx 作为反向代理时,大量的短链接,可能导致 Nginx 上的 TCP 连接处于 time_wait 状态:

    范蠡
  • 从TCP协议的原理来谈谈rst复位攻击

    在谈RST攻击前,必须先了解TCP:如何通过三次握手建立TCP连接、四次握手怎样把全双工的连接关闭掉、滑动窗口是怎么传输数据的、TCP的flag标志位里RST在...

    范蠡
  • laravel 事件/监听器实例代码

    上一篇文章实现了记录用户访问,设计上是有缺陷的,代码紧耦合在中间件。如果后续修改需求,不仅记录 ip、城市,还需要记录数据到新的数据表,或者需要进行其它统计,那...

    砸漏
  • 一个关于Angular Directive selector里的中括号使用问题

    其实对于Angular指令的selector,我一直搞得不是太清楚,看下面的例子:selector的定义里,包含了中括号。

    Jerry Wang
  • 搭建英文外贸B2B网站的实用建议!

    小编有三年的B2B网站建设经验,对b2b网站建设有一定的见解,今天写这篇文章从三个方面给新手准备搭建b2b英文外贸网站一些建议。

    小刘谷歌seo博客wyseoblog.com
  • 如何使用 React 构建自定义日期选择器(1)

    在 web 上经常看到包含一个或多个日期的表单。无论是出生日期还是航班时间表日期,您总希望用户能够提供了有效的日期。

    IMWeb前端团队
  • 火遍大厂的ServiceMesh编程模式到底是什么?

    Fallacies of Distributed Computing Explained:

    JavaEdge
  • 把Cloud for Customer的attachment视图直接放到工作中心视图去

    版权声明:本文为博主汪子熙原创文章,未经博主允许不得转载。 https://jerry.blog.csdn.net/article/detai...

    Jerry Wang
  • 谷歌推出基于注意机制的全新翻译框架,Attention is All You Need!

    AI 科技评论消息,谷歌最近与多伦多大学等高校合作发表论文,提出了一种新的网络框架——Transformer。Transformer是完全基于注意力机制(att...

    AI科技评论

扫码关注云+社区

领取腾讯云代金券