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)

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

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ASP.NETCore

微软为.NET程序员带来了最优的跨平台开发体验-WSL

在前几个Visual Studio Code更新中发现有一个重要得特性,就是nodejs可以使用VS Code在WSL中进行Debug了(WSL是指Win10中...

1064
来自专栏全华班

python学习手册-环境安装和配置

导读 | python学习手册 ? 一、python 安装和配置 下载安装包 首先需要在官网 https://www.python.org/ 下载pyth...

3494
来自专栏腾讯移动品质中心TMQ的专栏

让你相见恨晚的android权限业务实践

在上一篇Android权限中,我们介绍了一些权限相关的知识,也简述了新的Android M带来的权限变化,我们如何应对这种变化?是摆着我们面前的紧要问题。 现在...

2599
来自专栏专注数据中心高性能网络技术研发

解决Boost库链接出错问题

安装完最新的Boost库 官方说明中有一句话: Finally, $ ./b2 install will leave Boost binaries in the...

2483
来自专栏Rindew的iOS技术分享

iOS组件化(初)

1943
来自专栏蓝天

UNIX和Linux信号

1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区...

1734
来自专栏jessetalks

ASP.NET安全

ASP.NET 安全 概述   安全在web领域是一个永远都不会过时的话题,今天我们就来看一看一些在开发ASP.NET MVC应用程序时一些值得我们注意的安全问...

4718
来自专栏FreeBuf

Office文档嵌入对象点击执行的社工技巧

Microsoft Office相信大家都用过。Office在文档中嵌入对象极大的方便了我们的日常使用,但同时也为我们带来了众多安全问题。可以说,Office文...

1556
来自专栏张善友的专栏

冗余代码检查工具Simian

微软web2.0开发示例Kobe,重蹈了Oxite的覆辙。Ayende连续发表了五篇高质量的Kobe探讨贴: Kobe – In the nuts & bolt...

3308
来自专栏CodingToDie

每日推荐

你的桌面还杂乱无章吗?你还在为苦苦搜寻一个文件而劳心费力吗?你还在桌面上建快捷方式吗? 有了它,以上都不是问题.

852

扫码关注云+社区