`
yiyeqinghuasoon
  • 浏览: 643393 次
文章分类
社区版块
存档分类
最新评论

进程间通信:同步双工管道

 
阅读更多

因为工作需要,需要设计出一个双工的IPC。在一番比较后,我发现管道是比较符合我们的需求的。但是我们需求要求管道的对方是可信任的,而在vista以下系统是没有GetNamedPipeClientProcessIdGetNamedPipeClientSessionIdGetNamedPipeServerProcessId

GetNamedPipeServerSessionId这样的函数,于是是否可信这个操作就要求由客户端和服务端两方互检来完成,至于互检的思路,我会在之后管道的加强版中给出思路和例子。而本文只是简单介绍一个同步双工管道。

在工作中写的管道模型中,服务端每次被连接上,都会启动一个连接实例(线程)。于是如果存在多个客户端接入的情况下,将启动多个线程。这样的模型比较简单,但是效率存在问题。这些天我参考了微软的例子,重写了管道模型。服务端只启动一个线程,利用该线程的APC完成所有连接的读写操作。因为是同步双工,所以我设计的模型是不停的一问一答。当有消息要发向对方时,只需要向“问”列表中插入消息,底层会将这条消息发往对方;如果“问”表中不存数据,则发一条垃圾消息,对方在接受到这条消息后不做任何处理。这样的设计也就是为了维持管道畅通,不因一个环节卡住导致其他操作不可完成。

对于管道模型,我设计成:传输层,数据层,逻辑层,应用层四层结构。其中传输层只负责管道连接和数据传输,不关心数据内容;数据层会将传输层所有取到的数据以管道句柄为依据进行分组,同时负责将各个连接要传给对方的数据汇总供传输层使用;逻辑层考虑加入验证逻辑,即验证对方是否为可信任,同时为应用层提供方便的调用支持,比如在逻辑层启动一个线程调用一个应用层设置的回调函数来处理接受到的消息,同时暴露一个发送数据的函数供应用层使用。这样应用层只要实现处理消息的回调、调用发送数据的接口即可。(工作中设计的管道模型就是这样子的。因为我准备重写一个更稳定和高效的管道,目前只大致写好了传输层代码。)

服务端


客户端


这个代码中的一些值得注意的设计:

1 在写完成例程中调用异步读,在读完成例程中调用异步写,从而实现同步双工。(特别注意不要在完成例程中的异步操作后WaitforXXEX,否则会出现严重的递归问题,最后内存耗尽,程序挂掉)

2 对每一个接入,都分配一个不可移动的内存,其第一个元素设置成OVERLAPPED结构对象,同时让这个结构对象就是异步操作和完成例程中都会使用的那个参数。如异步操作

完成例程

这样设计,就可以达到一个很重要的目的:在完成例程中获取“读/写”的数据。
对应的工程地址是:CommunicatePipe工程

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics