首页 > 代码库 > 命名管道
命名管道
命名管道屏蔽了底层的网络协议细节,在不了解网络协议的情况下也可以利用命名管道来实现进程间通信;命名管道不仅可以在本机上实现两个进程间的通信,还可以跨网络实现两个进程间的通信;
1、创建命名管道
HANDLE CreateNamedPipe(
LPCTSTR lpName,
DWORD dwOpenMode,
DWORD dwPipeMode,
DWORD nMaxInstances,
DWORD nOutBufferSize,
DWORD nInBufferSize,
DWORD nDefaultTimeOut,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
lpName:指向一个字符串,该字符串的格式必须为:“\\.\pipe\pipename”;该字符串开始是两个连续的反斜杠,其后的圆点表示是本地机器,如果要与远程的服务器建立连接,应在圆点位置处指定这个远程服务器的名称;接下来是“pipe”这个固定不可更改的字符串,大小写无所谓;最后是所创建的命名管道的名称;
dwOpenMode:指定管道的访问方式、重叠方式、写直通方式、管道句柄的安全访问方式;
管道访问方式:
PIPE_ACCESS_DUPLEX --双向模式,服务器进程和客户端进程都可以从管道读取数据和向管道中写入数据;
PIPE_ACCESS_INBOUND --服务器端只能从管道中读取数据,客户端只能向管道写入数据;
PIPE_ACCESS_OUTBOUND --服务器只能向管道中写入数据,客户端只能从管道中读取数据;
重叠方式和写直通方式:
FILE_FLAG_WRITE_THROUGH --允许写直通方式;该方式只影响对字节类型管道的写入操作,并且只有当客户端和服务器端位于不同的计算机上时才有效;如果采用该方式,只有等到欲写入命名管道的数据通过网络传送过去,并且放在了远程计算机的管道缓冲区中后,写数据的函数才会成功返回;
FILE_FLAG_OVERLAPPED --允许重叠方式;如果采用该方式,那些需要一定时间才能完成的读写操作会立即返回,前台线程可执行其他操作,而耗时的操作可以在后台进行;
管道句柄的安全访问方式:
WRITE_DAC --调用者对命名管道的任意访问控制列表(ACL)都可以进行写入访问;
WRITE_OWNER --调用者对命名管道的所有者可以进行写入访问;
ACCESS_SYSTEM_SECURITY --调用者对命名管道的安全访问控制列表(SACL)可以进行写入访问;
dwPipeMode:指定管道句柄的类型、读取、等待方式;同一个命名管道的每一个实例必须具有相同的类型,但不同实例可以指定不同的读取方式和等待方式;字节模式只能用字节流方式读取,而消息模式既可以用消息流方式读取也可以用字节流方式读取;设为0时取默认值;
管道句柄的类型:
PIPE_TYPE_BYTE --数据以字节流的形式写入管道,该类型不能在PIPE_READMODE_MESSAGE读方式下使用;默认类型;
PIPE_TYPE_MESSAGE --数据以消息流的形式写入管道;
管道句柄的读取方式:
PIPE_READMODE_BYTE --以字节流的方式从管道读取数据;默认方式;
PIPE_READMODE_MESSAGE --以消息流的方式从管道读取数据,该方式只能在PIPE_TYPE_MESSAGE模式下使用;
管道句柄的等待方式:
PIPE_WAIT --阻塞方式;默认方式;
PIPE_NOWAIT --非阻塞方式;
nMaxInstances:指定管道能够创建的最多实例数;取值范围为:1~PIPE_UNLIMITED_INSTANCES,如果是PIPE_UNLIMITED_INSTANCES则可以创建的管道实例数目仅受限于系统可使用的资源;
nOutBufferSize:指定为输出缓冲区所保留的字节数;
nInBufferSize:指定为输入缓冲区所保留的字节数;
nDefaultTimeOut:指定默认的超时值,单位为ms;同一个管道的不同实例必须指定相同的超时值;
lpSecurityAttributes:指向SECURITY_ATTRIBUTES结构的指针,可以设置为NULL;
2、让服务器端等待客户端的连接请求
BOOL ConnectNamedPipe(
HANDLE hNamedPipe,
LPOVERLAPPED lpOverlapped
);
hNamedPipe:指向一个命名管道实例的服务器端的句柄,该句柄即为CreateNamedPipe函数的返回值;
lpOverlapped:指向OVERLAPPED结构体的指针;如果hNamedPipe参数所标识的管道是用FILE_FLAG_OVERLAPPED标记打开的,则这个参数所指向的OVERLAPPED结构体中必须包含人工重置事件对象句柄;
3、客户端等待可用的命名管道
BOOL WaitNamedPipe(
LPCTSTR lpNamedPipeName,
DWORD nTimeOut
);
lpNamedPipeName:指定命名管道的名称,名称格式为:“\\.\pipe\pipename”,如果服务器端和客户端在同一计算机上,名称开始的两个反斜杠后为圆点;如果是跨网络通信,则在圆点位置处应指定服务器端所在主机名;
nTimeOut:指定超时间隔,包括:
NMPWAIT_USE_DEFAULT_WAIT --超时间隔就是服务器端创建该命名管道时指定的超时值;
NMPWAIT_WAIT_FOREVER --一直等待,直到出现一个可用的命名管道的实例
命名管道