参考链接:http://bbs.pediy.com/thread-144492.htm
LPC即是”本地过程调用(Local Procedure Call)”。
端口是一种面向连接的通信机制,通信的双方需要先建立起“连接”。这种连接一般建立在用户进程之间。在建立了连接的双方之间有几种交换报文的方法:
不带数据的纯报文。
不大于256字节的短报文。
如果是大于256字节的长报文,就要在双方之间建立两个共享内存区(Section)。双方通过共享内存区交换数据,但通过报文进行协调和同步。
Tips:大块数据之所以要通过共享内存区交换,一来是因为这样就为用于Port机制的缓冲区设置了一个上限,便于内存管理。而更重要的是提高了效率,因为否则便要在发送端把大块数据搬入内核空间,又在接收端把大块数据搬到用户空间。
典型的LPC建立连接和通信过程如下:
符号说明:S提供服务方(服务端) C请求服务方(客户端)
S1、服务线程首先通过NtCreatePort()创建一个命名的连接端口、即Port对象(这个对象名应为客户线程所知).
S2、建立上述连接端口后,服务线程通过NtListenPort()等待接收来自客户线程的连接请求(服务线程被阻塞).
C1、客户线程通过NtConnectPort()创建客户方的无名通信端口,向上述命名的连接端口发出连接请求(客户线程阻塞)。
S3、服务线程收到连接请求(被唤醒)后,如果同意连接则通过NtAcceptConnectPort()创建服务方无名通信端口、接受连接、并返回该无名通信端口的handle。然后通过NtCompleteConnectPort()唤醒客户线程。
C2、客户线程被唤醒、返回所创建的无名通信端口handle。
S4、服务线程另创建一个新线程负责为客户线程提供服务。该线程因企图从上述通信端口接收报文、等待来自客户端的请求而阻塞。因此、新创建的线程是LPC服务线程,原来的服务线程是端口服务线程。
S5、端口服务线程再次调用NtListenPort(),等待来自其它客户的连接请求。(S2---S5的循环)
C3、客户线程通过NtRequestWaitReplyPort()向服务方发送报文,请求得到LPC服务,并因等待而被阻塞。
S6、LPC服务线程因接收到报文而被唤醒,并根据报文内容提供相应的LPC服务。
S7、LPC服务线程通过NtReplyPort()向客户方发送回答报文。客户线程解除阻塞。