目录

  • 一、前言
  • 二、基本概念
  • 三、命名管道的创建和使用
    • 3.1 函数原型
      • 3.1.1 CreateNamedPipe
      • 3.1.2 ConnectNamedPipe
      • 3.1.3 WaitNamedPipe
    • 3.2 示例代码
      • 3.2.1 实现步骤
      • 3.2.2 服务端代码
      • 3.2.3 客户端代码
      • 3.2.4 输出结果
  • 四、总结

一、前言

之前的 【学习笔记3】 中讲述了匿名管道的实现方法,本文来学习一下命名管道的内容,希望对自己与各位有所帮助。

二、基本概念

命名管道(Named Pipes),按照字面意思理解就是有名字的管道,它可在同一台计算机的不同进程之间或在跨越一个网络的不同计算机的不同进程之间,支持可靠的、单向或双向的数据通信。

三、命名管道的创建和使用

3.1 函数原型

3.1.1 CreateNamedPipe

/* 创建命名管道 */
HANDLE WINAPI CreateNamedPipe(/*** 管道名称。* 形式:\\.\pipe\pipename。* 最长256个字符,且不区分大小写。* 如果已有同名管道,则创建该管道的新实例。*/LPCTSTR lpName, /*** 管道打开方式。* 常用的管道打开方式有以下三种,更多请查阅MSDN:* PIPE_ACCESS_DUPLEX:该管道是双向的,服务器和客户端进程都可以从管道读取或者向管道写入数据。* PIPE_ACCESS_INBOUND:该管道中数据是从客户端流向服务端,即客户端只能写,服务端只能读。* PIPE_ACCESS_OUTBOUND:该管道中数据是从服务端流向客户端,即客户端只能读,服务端只能写。*/DWORD dwOpenMode,/*** 管道模式。* 常用的管道模式如下,更多请查阅MSDN:* PIPE_TYPE_BYTE:数据作为一个连续的字节数据流写入管道。* PIPE_TYPE_MESSAGE:数据用数据块(名为“消息”或“报文”)的形式写入管道。* PIPE_READMODE_BYTE:数据以单独字节的形式从管道中读出。* PIPE_READMODE_MESSAGE:数据以名为“消息”的数据块形式从管道中读出(要求指定PIPE_TYPE_MESSAGE)。* PIPE_WAIT:同步操作在等待的时候挂起线程。* PIPE_NOWAIT:同步操作立即返回。*/DWORD dwPipeMode,/*** 该管道能创建的最大实例数。* 必须大于1,小于PIPE_UNLIMITED_INSTANCES(255)。*/DWORD nMaxInstances,DWORD nOutBufferSize,  // 管道输出缓冲区容量,设置0时使用默认大小DWORD nInBufferSize,   // 管道输入缓冲区容量,设置0时使用默认大小DWORD nDefaultTimeOut, // 管道默认等待超时LPSECURITY_ATTRIBUTES lpSecurityAttributes // 管道的安全属性
);

返回值:CreateNamedPipe() 执行成功返回命名管道的句柄,否则返回INVALID_HANDLE_VALUE。

3.1.2 ConnectNamedPipe

/* 等待客户端连接命名管道 */
BOOL WINAPI ConnectNamedPipe(HANDLE hNamedPipe,         // 命名管道的句柄LPOVERLAPPED lpOverlapped  // 指向 OVERLAPPED 结构的指针,一般置为NULL即可
);

3.1.3 WaitNamedPipe

/* 客户端连接命名管道 */
BOOL WINAPI WaitNamedPipe(LPCTSTR lpNamedPipeName, // 管道名称。形式:\\servername\pipe\pipename。本机管道的 servername 为"."。/*** 等待命名管道一个实例有效的超时时间(单位:毫秒)。* NMPWAIT_USE_DEFAULT_WAIT:使用命名管道设定值(调用CreateNamedPip()时设置的 nDefaultTimeOut)。* NMPWAIT_WAIT_FOREV:一直等待。*/DWORD nTimeOut
);

返回值:WaitNamedPipe() 在指定时间内连接成功返回TRUE,否则返回FALSE。

注意:

  1. 在指定时间内连接成功返回TRUE,否则返回FALSE。
  2. 如果函数执行成功返回TRUE,表示至少有一个命名管道的实例有效,接下来应该使用 CreateFile() 函数打开命名管道的一个句柄,但是 CreateFile() 可能会打开管道失败,因为该实例有可能被服务端关闭或被已经被其他客户端打开。

3.2 示例代码

3.2.1 实现步骤

  1. 服务端调用 CreateNamedPipe() 创建命名管道并调用 ConnectNamedPipe() 等待客户端连接。
  2. 客户端使调用 WaitNamedPipe() 连接成功后,再调用 CreateFile() 和 WriteFile() 打开管道并向管道中写入一段数据,即向服务端发送消息。
  3. 服务端调用 ReadFile() 从管道中读取数据后(即收到消息),再向管道中写入确认信息表明已经收到数据,即通知客户端已收到。
  4. 客户端收到确认信息后结束,调用 CloseHandle() 关闭管道(该管道是 CreateFile() 打开的)。
  5. 服务端使用 DisconnectNamedPipe() 和 CloseHandle() 断开连接并关闭管道。

3.2.2 服务端代码

#include <stdio.h>
#include <windows.h>
#include <conio.h>int main()
{const char *pStrPipeName = "\\\\.\\pipe\\MyNamePipe";// 创建管道HANDLE hPipe = CreateNamedPipe(pStrPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_WAIT_FOREVER, 0);if (hPipe != INVALID_HANDLE_VALUE) {printf("Successfully created pipe!\n");printf("Waiting for client to connect...\n");}// 等待客户端连接if (ConnectNamedPipe(hPipe, NULL) != NULL) {printf("The connection is successful!\n");printf("Start to receive data:\n");CHAR Buffer[1024] = { 0 };DWORD dwNumberOfBytesRead = 0;// 接收客户端发送的数据ReadFile(hPipe, Buffer, sizeof(Buffer), &dwNumberOfBytesRead, NULL);printf("data len: %d\n", dwNumberOfBytesRead);printf("content:%s\n", Buffer);// 确认已收到数据printf("Send a received flag to the client!\n");strcpy(Buffer, "done");WriteFile(hPipe, Buffer, strlen(Buffer) + 1, &dwNumberOfBytesRead, NULL);}// 断开连接并关闭管道DisconnectNamedPipe(hPipe);CloseHandle(hPipe);return 0;
}

3.2.3 客户端代码

#include <stdio.h>
#include <windows.h>
#include <conio.h>int main()
{const char *pStrPipeName = "\\\\.\\pipe\\MyNamePipe";printf("Connecting to pipe...\n");if (WaitNamedPipe(pStrPipeName, NMPWAIT_WAIT_FOREVER) == FALSE) {printf("Failed to connect to pipe!\n");return 0;}printf("Open pipe!\n");HANDLE hPipe = CreateFile(pStrPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);printf("Send data to the server!\n");CHAR Buffer[1024] = { 0 };DWORD dwNumberOfBytesWritten = 0;// 向服务端发送数据sprintf(Buffer, "Process %d said: %s", GetCurrentProcessId(), "Hello World!");WriteFile(hPipe, Buffer, strlen(Buffer) + 1, &dwNumberOfBytesWritten, NULL);printf("Send data len :%d \n", dwNumberOfBytesWritten);// 接收服务端发回的数据ReadFile(hPipe, Buffer, sizeof(Buffer), &dwNumberOfBytesWritten, NULL);printf("Reply data len: %d\n", dwNumberOfBytesWritten);printf("content:%s\n", Buffer);CloseHandle(hPipe);return 0;
}

3.2.4 输出结果

运行结果如下所示,运行时先启动服务器,然后再启动客户端:

四、总结

由此可见,命名管道的用法其实与套接字非常类似,也是一种实现进程间通信的方法。

至此,管道通信的学习完毕,以下时管道通信的相关笔记,方便查阅:

【学习笔记2】管道通信:输入输出重定向

【学习笔记3】管道通信:匿名管道

【学习笔记5】管道通信:命名管道

【学习笔记5】管道通信:命名管道相关推荐

  1. C# 管道通信-命名管道(一)

    最近在做一个应用程序,涉及到两个应用程序之间的通讯,就想到了用C#的命名管道的方式来实现,经过一番小折腾,总算实现了,现把一些主体的代码粘贴出来与大家分享: 管道通讯会涉及到client端和Serve ...

  2. linux pipe 命名管道,linux 进程学习笔记-named pipe (FIFO)命名管道

    与"无名管道"不同的是,FIFO拥有一个名称来标志它,所谓的名称实际上就是一个路径,比如"/tmp/my_fifo",其对应到磁盘上的一个管道文件,如果我们用f ...

  3. 进程间的通信IPC(无名管道和命名管道)

    进程间的通信IPC介绍 进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息. IPC的方式通常有管道(包括无名管道和命名管道).消息队列.信号量 ...

  4. 进程通信:匿名管道和命名管道

    一.进程间通信方式 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系通常是指父子进程关系. 有名管道 (named pipe) : ...

  5. Linux进程通信——匿名管道、命名管道、管道的特性和共享内存

    Linux进程通信--匿名管道.命名管道.管道的特性和共享内存 一.管道 1.1 什么是管道? 1.2 匿名管道 <1> 匿名管道参数说明 <2> fork共享管道原理 < ...

  6. 进程的通信 - 命名管道

    命名管道概述 命名管道(Named Pipes),顾名思义,一个有名字的管道.命名管道的名字主要是用于确保多个进程访问同一个对象.命名管道不仅可以在同一台计算机之间传输数据,甚至能在跨越一个网络的不同 ...

  7. 进程间通信:管道和命名管道(FIFO)

    目录 概述 IPC 对象的持续性 什么是管道 读取外部程序的输出 将输出送往 popen 传递更多的数据 如何实现 popen pipe 调用 跨越 fork 调用管道 父进程和子进程 管道关闭后的读 ...

  8. Linux IPC:匿名管道 与 命名管道

    目录 一.管道的理解 二.匿名管道 三.命名管道 四.管道的通信流程 五.管道的特性   进程间通信方式有多种,本文介绍的是管道,管道分为匿名管道和命名管道. 一.管道的理解   生活中的管道用来传输 ...

  9. 【Linux】进程间通信--管道(匿名管道和命名管道)

    文章目录 前言 进程间通信的目的 管道 匿名管道 管道特点 站在文件描述符角度理解管道 匿名管道通信读写特点 命名管道 命名管道的原理 命名管道的创建 命名管道完成两个不同进程通信 匿名管道和命名管道 ...

  10. 进程间通信之管道(匿名管道与命名管道)

    进程间通信之管道 进程间通信 管道 什么是管道 管道分类--1.匿名管道 匿名管道举例 管道的特点 管道分类--2.命名管道 创建一个命名管道 举例 命名管道的打开规则 匿名管道与命名管道的区别 具体 ...

最新文章

  1. 计算机组装需要的硬件,组装电脑选择硬件,只要记住2个装机思路,选好硬件配置不是难题...
  2. 堆排序时间复杂度_堆排序算法
  3. 利用Flutter写一个跨平台的果核APP(3)——网络请求
  4. androidstudio带pom的上传到jcenter_输送机@网带输送机@304网带输送机@304不锈钢网带输送机@输送机网带厂家定制...
  5. [Node.js] mySQL数据库 -- 数据库的基本操作
  6. js系列:时间格式转成时间戳和比较某个时段是否在另一个时间段内
  7. 国军标GJB150A霉菌试验详解
  8. 共轭梯度法matlab程序精确线搜索,具有精确线性搜索的改进共轭梯度法
  9. 轻松打造企业内部NOD32升级服务器
  10. 信息系统集成监理费收取标准_信息系统工程监理与咨询服务收费参考标准起草说明...
  11. 白光LED焊接技术要求
  12. 动不动就感冒,用玉屏风来治愈
  13. Relax中的量化管理
  14. [转载]命令行也强大之下载迅雷资源的方法
  15. 【listener hangs】监听hangs,导致新的连接无法连接数据库
  16. 特殊注释标记todo的有关信息
  17. 怎么看计算机电源型号,鲁大师怎么看电源 鲁大师电源参数查看方法
  18. 对nii医学图像进行重采样
  19. 金融计算机杂志排名,中国核心期刊排名_中国金融文化属于核心期刊吗_计算机八大核心期刊...
  20. Matlab移动色带位置

热门文章

  1. 详解 cron 表达式
  2. voltDB官方文档第三章翻译
  3. Java面试都只是背答案吗?
  4. 典型相关分析,奇异值分解,RRR(Reduced-Rank Regression)
  5. Dijkstra【p3003(bzoj2100)】[USACO10DEC]苹果交货Apple Delivery
  6. java preference xml,java-将PreferenceScreen添加到linearlayout
  7. 三维实景地图,挺酷的
  8. C# 写入注册表启动项
  9. 怎么修复计算机硬件,Windows系统崩溃别慌 编辑教你如何修复
  10. π120M60代替ADuM2210SRIZ 双通道数字隔离器 电路简单速度快