基于完成端口实现socket通信的研究
作者:冯海东
来源:《智富时代》2015年第12
        【摘 要】在Windows平台上实现基于SocketTCP通信有很多种途径,微软给出了多种套接字模型,这些套接字模型中最复杂同时性能最高的是完成端口模型;本文基于windows平台提供的IO完成端口实现一套高性能TCP通信库,并以伪代码的方式进行了讲解。
        【关键词】SocketIO完成端口;客户端;服务端
        一、简介
        Winsock一共给我们提供了5IO套接字模型,它们分别是select模型、WSAAyncSelect模型、WSAEventSelect模型、重叠IO模型和完成端口模型。前面四种模型比较简单,它们对于处理异步IO请求提供了一套完整的解决方案;但是前四种模型的无法管理众多的套接字,无法满足大量连接的并发数据通信需求。
        完成端口是一种WINDOWS内核对象,英文是I/O Completion Port(缩写为IOCP)。完
成端口内部提供了线程池的管理,可以避免反复创建线程的开销,同时可以根据CPU的个数灵活的决定线程个数,而且可以让减少线程调度的次数从而提高性能。由于这一点,也有很多人把完成端口当成一个线程池来用的。目前完成端口基本上被公认为一种在windows服务平台上比较成熟和高效的IO方法,利用完成端口进行重叠I/O的技术在WindowsNTWIndows2000Windows2003Windows2008上提供了真正的可扩展性。完成端口和Windows Socket2.0结合很好的解决大量连接的并发数据通信问题。
        二、客户端设计
        客户端通信库主要由CMySocketClientExWorkerThreadCSocket三个类来实现。CMySocketClientEx类中最主要的是提供了完成端口和定义了完成事件;并且向外提供动态库到导出函数;导出函数主要包括建立连接函数(AppendConnection)、发送数据函数(WriteBuffer)和断开连接函数(FinishConnection);同时提供回调函数接口,以便向调用者通知一些网络事件,如服务端断开连接、收到服务端数据等。WorkerThread则是封装的工作线程类,为完成端口提供工作线程;这个类为通信库内部使用,不对外提供导出函数。主要提供线程的创建、线程的结束等。CSocket则是用于封装链路信息和套接字;便于通信库管理不同的链路和套接字。图1为客户端通信库的主要结构。
        (一)建立连接流程
        客户端建立连时首先创建Socket对相,并将其中套接字绑定在IOCP上,最后调用ConnetEx进行异步连接,之后系统就会自己去做连接;通过调用GetQueuedCompletionStatus,等待处理完成如果连接成功,就调用上层回调,通知连接建立成功,如果失败,加入重连队列,等待定时器重连。
        (二)关闭链路流程
        客户端关闭链路时首先到链路对应的Socket信息,从重连队列中将其删除,并调用应用层回调函数告知应用层链路已经关闭,最后关闭对应Socket中的套接字并将Socket指针压入空闲链表中。
        (三)接收数据流程
        当接收到系统连接建立成功时,程序除了向上层通知连接建立成功外,还向完成端口提交一个接收数据的请求。这个异步请求一旦提交到完成端口,那么一旦服务器向客户端发送数据,就可以用GetQueuedCompletionStatus检测到,客户端通过不断的向完成端口反复投
递接收数据的异步请求,来接收服务端发送的数据的,图2是接收数据的处理流程。
        (四)发送数据流程
        客户端发送数据时首先给发送数据编号,并向完成端口投递一个写请求,数据将被异步发送,其流程如图3
        (五)主线程流程
        客户端的主线程在启动工作线程后将不断检测是否多余CMyIOBuffer和空闲的Socket,同时还会定时尝试将重连列表中的节点进行重新连接,其流程较为简单。
        三、服务端设计
        服务通信库主要由CMySocketServerExWorkerThreadCsocket三个类来实现。CmySocketServerEx类中最主要的是提供了完成端口和定义了完成事件;并且向外提供动态库到导出函数;导出函数主要包括启动监听端口函数(StartListen)、发送数据函数(WriteBuffer)和断开连接函数(FinishConnectionsocket通信在哪一层);同时提供回调函数接口,以便向调
用者通知一些网络事件,如客户端断开连接、收到客户端数据等。WorkerThread则是封装的工作线程类,为完成端口提供工作线程;这个类为通信库内部使用,不对外提供导出函数。主要提供线程的创建、线程的结束等。Csocket则是用于封装链路信息和套接字;便于通信库管理不同的链路和套接字。图4为服务端通信库的主要结构。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。