【进程间通信】有名管道

Posted on 2017-10-17 08:01  杨心漂  阅读(241)  评论(0编辑  收藏  举报

 

命名管道

    命名管道,来解决不相关进程间的通信问题。不仅可以在本地机器上实现两个进程之间的通信,还可以跨越网络实现两个进程之间的通信,同时其客户端既可以接收数据也可以发送数据,

       服务端也是既可以接收数据,又可以发送数据的。

  命名管道是通过网络来完成进程之间的通信的,命名管道依赖于底层网络接口,其中包括有 DNS 服务,TCP/IP 协议等等机制,但是其屏蔽了底层的网络协议细节。

  命名管道也被称为FIFO文件,它是一种特殊类型的文件,它在文件系统中以文件名的形式存在。

     命名管道的通信是以连接的方式来进行的,服务器创建一个命名管道对象,然后在此对象上等待连接请求,一旦客户连接过来,则两者都可以通过命名管道读或者写数据。

        命名管道提供了两种通信模式:字节模式和消息模式。 在字节模式下,数据以一个连续的字节流的形式在客户机和服务器之间流动, 而在消息模式下,客户机和服务器则通过一系列的不连续的数据单位,进行数据的收发, 每次在管道上发出一个消息后,它必须作为一个完整的消息读入。

创建命名管道
  int mkfifo(const char *filename, mode_t mode);  
  int mknod(const char *filename, mode_t mode | S_IFIFO, (dev_t)0);  
这两个函数都能创建一个FIFO文件,注意是创建一个真实存在于文件系统中的文件,filename指定了文件名,而mode则指定了文件的读写权限。
 
mknod是比较老的函数,而使用mkfifo函数更加简单和规范,所以建议在可能的情况下,尽量使用mkfifo而不是mknod。
 
 

命名管道使用流程

服务端:

服务端进程调用 CreateNamedPipe 函数来创建一个有名称的命名管道,

在创建命名管道的时候必须指定一个本地的命名管道名称,

Windows 允许同一个本地的命名管道名称有多个命名管道实例,

所以,服务器进程在调用 CreateNamedPipe 函数时必须指定最大允许的实例数(0 -255),

如果 CreateNamedPipe 函数成功返回后,服务器进程得到一个指向一个命名管道实例的句柄,

然后,服务器进程就可以调用 ConnectNamedPipe 来等待客户的连接请求。

在已经建立了连接的命名管道实例中,

服务端进程就会得到一个指向该管道实例的句柄,这个句柄称之为服务端句柄。

同时,服务端进程可以调用 DisconnectNamedPipe 函数,

将一个管道实例与当前建立连接的客户端进程断开,从而可以重新连接到新的客户进程。

当然在服务端也是可以调用 CloseHandle 来关闭一个已经建立连接的命名管道实例。

 

 

客户端

客户端进程调用 CreateFile 函数连接到一个正在等待连接的命名管道上,

在这里客户端需要指定将要连接的命名管道的名称,

CreateFile 成功返回后,客户进程就得到了一个指向已经建立连接的命名管道实例的句柄,

到这里,服务器进程的 ConnectNamedPipe 也就完成了其建立连接的任务。

客户端进程除了调用 CreateFile 函数来建立管道连接以外,

还可以调用 WaitNamedPipe 函数来测试指定名称的管道实例是否可用。

在已经建立了连接的命名管道实例中,客户端进程就会得到一个指向该管道实例的句柄,

这个句柄称之为客户端句柄。

在客户端可以调用 CloseHandle 来关闭一个已经建立连接的命名管道实例。