fbpx
维基百科

命名管道

命名管道是计算机进程间的一种先进先出通信机制。是类Unix系统传统管道的扩展。传统管道属于匿名管道,其生存期不超过创建管道的进程的生存期。但命名管道的生存期可以与操作系统运行期一样长。

Unix 编辑

与传统的无名的shell管道不同,命名管道利用了文件系统。使用mkfifo()[1]mknod()[2]创建命名管道。两个进程可以通过管道的名字打开、读写管道。

例如,可以创建管道,让gzip压缩管道传给它的数据:

 mkfifo my_pipe  gzip -9 -c < my_pipe > out.gz & 

在另一个进程shell中,独立地发送数据给管道以被压缩:

cat file > my_pipe 

命名管道可如普通文件那样被删除:

rm my_pipe 

命名管道可用于从一个进程向另一个进程发送信息而不需使用中间临时文件。例如,gzip解压缩数据可以输出到一个命名管道中:

 mkfifo -m 0666 /tmp/namedPipe  gzip -d < file.gz > /tmp/namedPipe 

然后把解压缩数据存入MySQL的表中[3]:

 LOAD DATA INFILE '/tmp/namedPipe' INTO TABLE tableName; 

如果不使用管道,就需要把解压缩数据完整地保存在文件中以上传到MySQL。

PostgreSQL的命令行工具psql也支持从命名管道装入数据。[4]

Windows操作系统 编辑

命名管道可以类似于文件那样,使用Win32 SDK函数CreateFile, ReadFile, WriteFile, CloseHandle打开、读写、关闭。

与Unix不同,在Windows的命令行界面上不能使用命名管道,除了PowerShell终端模拟器。另一点不同是Windows命名管道是易失的,如果对命名管道的引用为0就会自动被关闭。第三点不同是Windows命名管道被安装在命名管道文件系统(named pipe filesystem,NPFS),安装路径是\\.\pipe\。例如管道名字"foo"的全路径名是\\.\pipe\foo)。

匿名管道实际上是采用随机名字的命名管道。

命名管道可继承安全上下文;可跨计算机做进程间通信;可全双工或半双工通信;可以是面向字节协议英语Byte-oriented分组交换;可靠通信;阻塞或非阻塞读写;标准设备I/O句柄;可用名字来创建句柄;广域网通信效率低(与TCP/IP滑动窗口相比,使用明确的数据请求);可窥探式读(读数据但不从输入缓冲区中删除)。

命名管道可以同时创建多个实例,只要不超过nMaxInstances。一个实例只能连接一个客户端,若想连接其它的客户端,需要先调用DisconnectNamedPipe关闭现有的管道连接。另外创建命名对象时可以为参数dwOpenMode指定FILE_FLAG_FIRST_PIPE_INSTANCE,指定这个参数后,若创建的命名管道对象不是第一个实例,会报错ERROR_ACCESS_DENIED。

.NET Framework 3.5增加了命名管道支持。[5]命名管道可用作Microsoft SQL Server.[6]的客户端点(endpoint)。

命名管道也是伺服器訊息區塊(SMB)支持的一种网络协议。Windows NT的整个NT Domain英语NT Domain服务协议是基于命名管道之上的DCE/RPC服务。Exchange 5.5 Administrative应用也是如此。

API 编辑

  • CreateNamedPipe:创建命名管道
  • ConnectNamedPipe:服务器端等待客户端连接命名管道。若调用此函数之前,客户端已经调用CreateFile连接到了此实例,ConnectNamedPipe返回FALSE,并且GetLastError()返回ERROR_PIPE_CONNECTED,这是一个正常的连接,虽然函数返回了FALSE。
  • WaitNamedPipe:客户端阻塞式连接命名管道。如果
  • DisconnectNamedPipe:服务器端强制关闭命名管道的客户端;客户进程仍然需要调用CloseHandle。服务器端可以进一步再与其他客户端连接
  • PeekNamedPipe:获取但不删除输入缓冲区的数据
  • SetNamedPipeHandleState
  • GetNamedPipeHandleState:
  • GetNamedPipeInfo
  • CallNamedPipe:连接命名管道,读、写各一次,然后断连命名管道
  • TransactNamedPipe:典型用于客户端,完成读、写各一次。
  • GetNamedPipeClientComputerName:获得客户端的计算机名字
  • GetNamedPipeClientProcessId:获得客户端进程ID
  • GetNamedPipeClientSessionId:获得客户端会话ID
  • GetNamedPipeServerProcessId
  • GetNamedPipeServerSessionId
  • ImpersonateNamedPipeClient:服务端接受客户端连接后,必须接收到客户端的消息才能模拟客户端安全上下文

例子 编辑

 //命名管道服务器  #include <windows.h>   #include <stdio.h>     int main(void)   {   HANDLE PipeHandle;   DWORD BytesRead;   CHAR buffer[256];     if ((PipeHandle = CreateNamedPipe("\\\\.\\Pipe\\Jerry",   PIPE_ACCESS_DUPLEX, //open mode   PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, // pipe mode   1,//Num. of MaxInstances: between 1 and PIPE_UNLIMITED_INSTANCES   0, // out buffer size   0, // in buffer size   1000, //timeout   NULL //Security descriptor   )) == INVALID_HANDLE_VALUE)   {   printf("CreateNamedPipe failed with error %d\n",   GetLastError());   return 0;   }     printf("Server is now running\n");     if (ConnectNamedPipe(PipeHandle, NULL) == 0)   {   printf("ConnectNamedPipe failed with error %d\n", GetLastError());   CloseHandle(PipeHandle);   return 0;   }     if (ReadFile(PipeHandle, buffer, sizeof(buffer), &BytesRead, NULL) <= 0)   {   printf("ReadFile failed with error %d\n", GetLastError());   CloseHandle(PipeHandle);   return 0;   }     printf("%.*s\n", BytesRead, buffer);     if (DisconnectNamedPipe(PipeHandle) == 0)   {   printf("DisconnectNamedPipe failed with error %d\n",   GetLastError());   return 0;   }     CloseHandle(PipeHandle);   return 0;   } 
 //客户程序  #include <windows.h>   #include <stdio.h>     #define PIPE_NAME "\\\\.\\Pipe\\Jerry"     void main(void) {     HANDLE PipeHandle;   DWORD BytesWritten;     if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) == 0)   {   printf("WaitNamedPipe failed with error %d\n",   GetLastError());   return;   }     // Open the named pipe file handle   if ((PipeHandle = CreateFile(PIPE_NAME,   GENERIC_READ | GENERIC_WRITE, 0,   (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING,   FILE_ATTRIBUTE_NORMAL,   (HANDLE) NULL)) == INVALID_HANDLE_VALUE)   {   printf("CreateFile failed with error %d\n", GetLastError());   return;   }     if (WriteFile(PipeHandle, "This is a test", 14, &BytesWritten,   NULL) == 0)   {   printf("WriteFile failed with error %d\n", GetLastError());   CloseHandle(PipeHandle);   return;   }     printf("Wrote %d bytes", BytesWritten);     CloseHandle(PipeHandle);   } 

参见 编辑

参考文献 编辑

  1. ^ mkfifo. www.opengroup.org. [2017-09-04]. (原始内容于2010-12-08). 
  2. ^ mknod. www.opengroup.org. [2017-09-04]. (原始内容于2010-12-08). 
  3. ^ MySQL :: MySQL 5.7 Reference Manual :: 13.2.6 LOAD DATA INFILE Syntax. dev.mysql.com. [2017-09-04]. (原始内容于2016-05-04). 
  4. ^ . postgresql.1045698.n5.nabble.com. [2017年9月4日]. (原始内容存档于2011年7月14日). 
  5. ^ System.IO.Pipes Namespace. msdn.microsoft.com. [2017-09-04]. (原始内容于2016-03-11). 
  6. ^ How to connect to a named instance of SQL Server 2005 or SQL Server 2000 by using the client tools in the earlier version of SQL Server. [2017-09-04]. (原始内容于2014-09-13). 

外部链接 编辑

  • The Linux Programmer's Guide: Named Pipes(页面存档备份,存于互联网档案馆
  • Template:Apple man page

命名管道, 是计算机进程间的一种先进先出通信机制, 是类unix系统传统管道的扩展, 传统管道属于匿名管道, 其生存期不超过创建管道的进程的生存期, 但的生存期可以与操作系统运行期一样长, 目录, unix, windows操作系统, 例子, 参见, 参考文献, 外部链接unix, 编辑与传统的无名的shell管道不同, 利用了文件系统, 使用mkfifo, 或mknod, 创建, 两个进程可以通过管道的名字打开, 读写管道, 例如, 可以创建管道, 让gzip压缩管道传给它的数据, mkfifo, pipe, g. 命名管道是计算机进程间的一种先进先出通信机制 是类Unix系统传统管道的扩展 传统管道属于匿名管道 其生存期不超过创建管道的进程的生存期 但命名管道的生存期可以与操作系统运行期一样长 目录 1 Unix 2 Windows操作系统 2 1 API 2 2 例子 3 参见 4 参考文献 5 外部链接Unix 编辑与传统的无名的shell管道不同 命名管道利用了文件系统 使用mkfifo 1 或mknod 2 创建命名管道 两个进程可以通过管道的名字打开 读写管道 例如 可以创建管道 让gzip压缩管道传给它的数据 mkfifo my pipe gzip 9 c lt my pipe gt out gz amp 在另一个进程shell中 独立地发送数据给管道以被压缩 cat file gt my pipe 命名管道可如普通文件那样被删除 rm my pipe 命名管道可用于从一个进程向另一个进程发送信息而不需使用中间临时文件 例如 gzip解压缩数据可以输出到一个命名管道中 mkfifo m 0666 tmp namedPipe gzip d lt file gz gt tmp namedPipe 然后把解压缩数据存入MySQL的表中 3 LOAD DATA INFILE tmp namedPipe INTO TABLE tableName 如果不使用管道 就需要把解压缩数据完整地保存在文件中以上传到MySQL PostgreSQL的命令行工具psql也支持从命名管道装入数据 4 Windows操作系统 编辑命名管道可以类似于文件那样 使用Win32 SDK函数CreateFile ReadFile WriteFile CloseHandle打开 读写 关闭 与Unix不同 在Windows的命令行界面上不能使用命名管道 除了PowerShell终端模拟器 另一点不同是Windows命名管道是易失的 如果对命名管道的引用为0就会自动被关闭 第三点不同是Windows命名管道被安装在命名管道文件系统 named pipe filesystem NPFS 安装路径是 pipe 例如管道名字 foo 的全路径名是 pipe foo 匿名管道实际上是采用随机名字的命名管道 命名管道可继承安全上下文 可跨计算机做进程间通信 可全双工或半双工通信 可以是面向字节协议 英语 Byte oriented 或分组交换 可靠通信 阻塞或非阻塞读写 标准设备I O句柄 可用名字来创建句柄 广域网通信效率低 与TCP IP滑动窗口相比 使用明确的数据请求 可窥探式读 读数据但不从输入缓冲区中删除 命名管道可以同时创建多个实例 只要不超过nMaxInstances 一个实例只能连接一个客户端 若想连接其它的客户端 需要先调用DisconnectNamedPipe关闭现有的管道连接 另外创建命名对象时可以为参数dwOpenMode指定FILE FLAG FIRST PIPE INSTANCE 指定这个参数后 若创建的命名管道对象不是第一个实例 会报错ERROR ACCESS DENIED NET Framework 3 5增加了命名管道支持 5 命名管道可用作Microsoft SQL Server 6 的客户端点 endpoint 命名管道也是伺服器訊息區塊 SMB 支持的一种网络协议 Windows NT的整个NT Domain 英语 NT Domain 服务协议是基于命名管道之上的DCE RPC服务 Exchange 5 5 Administrative应用也是如此 API 编辑 CreateNamedPipe 创建命名管道 ConnectNamedPipe 服务器端等待客户端连接命名管道 若调用此函数之前 客户端已经调用CreateFile连接到了此实例 ConnectNamedPipe返回FALSE 并且GetLastError 返回ERROR PIPE CONNECTED 这是一个正常的连接 虽然函数返回了FALSE WaitNamedPipe 客户端阻塞式连接命名管道 如果 DisconnectNamedPipe 服务器端强制关闭命名管道的客户端 客户进程仍然需要调用CloseHandle 服务器端可以进一步再与其他客户端连接 PeekNamedPipe 获取但不删除输入缓冲区的数据 SetNamedPipeHandleState GetNamedPipeHandleState GetNamedPipeInfo CallNamedPipe 连接命名管道 读 写各一次 然后断连命名管道 TransactNamedPipe 典型用于客户端 完成读 写各一次 GetNamedPipeClientComputerName 获得客户端的计算机名字 GetNamedPipeClientProcessId 获得客户端进程ID GetNamedPipeClientSessionId 获得客户端会话ID GetNamedPipeServerProcessId GetNamedPipeServerSessionId ImpersonateNamedPipeClient 服务端接受客户端连接后 必须接收到客户端的消息才能模拟客户端安全上下文例子 编辑 命名管道服务器 include lt windows h gt include lt stdio h gt int main void HANDLE PipeHandle DWORD BytesRead CHAR buffer 256 if PipeHandle CreateNamedPipe Pipe Jerry PIPE ACCESS DUPLEX open mode PIPE TYPE BYTE PIPE READMODE BYTE pipe mode 1 Num of MaxInstances between 1 and PIPE UNLIMITED INSTANCES 0 out buffer size 0 in buffer size 1000 timeout NULL Security descriptor INVALID HANDLE VALUE printf CreateNamedPipe failed with error d n GetLastError return 0 printf Server is now running n if ConnectNamedPipe PipeHandle NULL 0 printf ConnectNamedPipe failed with error d n GetLastError CloseHandle PipeHandle return 0 if ReadFile PipeHandle buffer sizeof buffer amp BytesRead NULL lt 0 printf ReadFile failed with error d n GetLastError CloseHandle PipeHandle return 0 printf s n BytesRead buffer if DisconnectNamedPipe PipeHandle 0 printf DisconnectNamedPipe failed with error d n GetLastError return 0 CloseHandle PipeHandle return 0 客户程序 include lt windows h gt include lt stdio h gt define PIPE NAME Pipe Jerry void main void HANDLE PipeHandle DWORD BytesWritten if WaitNamedPipe PIPE NAME NMPWAIT WAIT FOREVER 0 printf WaitNamedPipe failed with error d n GetLastError return Open the named pipe file handle if PipeHandle CreateFile PIPE NAME GENERIC READ GENERIC WRITE 0 LPSECURITY ATTRIBUTES NULL OPEN EXISTING FILE ATTRIBUTE NORMAL HANDLE NULL INVALID HANDLE VALUE printf CreateFile failed with error d n GetLastError return if WriteFile PipeHandle This is a test 14 amp BytesWritten NULL 0 printf WriteFile failed with error d n GetLastError CloseHandle PipeHandle return printf Wrote d bytes BytesWritten CloseHandle PipeHandle 参见 编辑匿名管道 匿名命名管道参考文献 编辑 mkfifo www opengroup org 2017 09 04 原始内容存档于2010 12 08 mknod www opengroup org 2017 09 04 原始内容存档于2010 12 08 MySQL MySQL 5 7 Reference Manual 13 2 6 LOAD DATA INFILE Syntax dev mysql com 2017 09 04 原始内容存档于2016 05 04 Nabble Forum Not Found postgresql 1045698 n5 nabble com 2017年9月4日 原始内容存档于2011年7月14日 System IO Pipes Namespace msdn microsoft com 2017 09 04 原始内容存档于2016 03 11 How to connect to a named instance of SQL Server 2005 or SQL Server 2000 by using the client tools in the earlier version of SQL Server 2017 09 04 原始内容存档于2014 09 13 外部链接 编辑The Linux Programmer s Guide Named Pipes 页面存档备份 存于互联网档案馆 Template Apple man page Linux Journal Introduction to Named Pipes MSDN Library Named Pipes 取自 https zh wikipedia org w index php title 命名管道 amp oldid 67338083, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。