热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

利用命名管道实现进程间的通信

常规的管道只能连接相关进程,由进程创建并由最后一个进程关闭。命名管道(NamedPipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是命名管道允许无亲缘关系进程间
常规的管道只能连接相关进程,由进程创建并由最后一个进程关闭。

命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是命名管道允许无亲缘关系进程间的通信,它可以在不相关的进程之间和不同计算机之间使用。服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。

命名管道是建立在实际的磁盘介质或文件系统(而不是只存在内存中),任何进程可以通过文件名或路径建立与该文件的联系,命名换到需要一种FIFO文件(有先进先出的原则),虽然FIFO文件的inode节点在磁盘上,但仅是一个节点而已,文件的数据还是存在于内存缓冲页面中,和普通管道相同。它是个FIFO先进先出队列,即使没有进程,命名管道依然可以存在,它不依赖于进程。服务器将字节写入队列,客户端从队列头部移出字节。服务器必须重写数据。它没有竞争的问题,在没有超过管道最大长度的时候,read和write都是原子操作,先将管道清空,然后再将管道写满,在读者和写者联通之前系统内核将进程挂起。FIFO是增强型的管道,适合传递较小的消息,FIFO实际相当于内核内部实现的一个共享文件。

命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节。我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信。将命名管道作为一种网络编程方案时,它实际上建立了一个客户机/服务器通信体系,并在其中可靠地传输数据。创建时可以指定哪一种用户可以访问管道,不需要用户身份验证,能够可靠地传输数据。

命名管道服务器端和客户端的区别在于:服务器端是唯一一个有权创建命名管道的进程,也只有它才能接受命名管道客户端的连接请求。而客户端只能与一个现成的命名管道服务器建立连接。

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

一般不用匿名管道做进程通信,推荐使用命名管道FIFO。和socket相比,不占用端口号,虽然也支持不同机器通信,但一般只用于本机进程通信,支持数据双向或单向传输。

 

服务器端

 1     HANDLE hPipe;
 2     //创建命名管道
 3     hPipe= CreateNamedPipe("\\\\.\\pipe\\FileMonitor", 
 4         PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 
 5         0, 1, 1024, 1024, 0, NULL);
 6     if(INVALID_HANDLE_VALUE == hPipe)
 7     {
 8         AfxMessageBox("创建命名管道失败!");
 9         hPipe = NULL;
10         return 0;
11     }
12     //创建事件对象
13     HANDLE hEvent;
14     hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
15     if(!hEvent)
16     {
17         AfxMessageBox("创建事件对象失败!");
18         CloseHandle(hPipe);
19         hPipe = NULL;
20         return 0;
21     }
22     //等待客户端连接
23     OVERLAPPED ovlap;
24     ZeroMemory(&ovlap, sizeof(OVERLAPPED));
25     ovlap.hEvent = hEvent;
26     if(!ConnectNamedPipe(hPipe, &ovlap))
27     {
28         if(ERROR_IO_PENDING != GetLastError())
29         {
30             AfxMessageBox("等待客户端连接失败!");
31             CloseHandle(hPipe);
32             CloseHandle(hEvent);
33             hPipe = NULL;
34             return 0;
35         }
36     }
37     //等待失败
38     if(WAIT_FAILED == WaitForSingleObject(hEvent, INFINITE))
39     {
40         AfxMessageBox("等待对象失败!");
41         CloseHandle(hPipe);
42         CloseHandle(hEvent);
43         hPipe = NULL;
44         return 0;
45     }
46     CloseHandle(hEvent);
47     const int nBufferLen = 256;  
48     char cRecvMsg[nBufferLen];
49     char cSendMsg[nBufferLen];  
50     DWORD dwLen;  
51 
52     //接收客户端发送的数据  
53     ReadFile(hPipe, cRecvMsg, nBufferLen, &dwLen, NULL);//读取管道中的内容(管道是一种特殊的文件)
54     MessageBox(cRecvMsg);
55 
56     //确认已收到数据  
57     strcpy(cSendMsg, "1");  
58     WriteFile(hPipe, cSendMsg, strlen(cSendMsg) + 1, &dwLen, NULL);   
59 
60     DisconnectNamedPipe(hPipe);   
61     CloseHandle(hPipe);//关闭管道
62     hPipe = NULL;

客户端

 

 1     //等待连接命名管道
 2     if(!WaitNamedPipe("\\\\.\\pipe\\FileMonitor", NMPWAIT_WAIT_FOREVER))
 3     {
 4         AfxMessageBox("当前没有可利用的命名管道示例!");
 5         return 0;
 6     }
 7     //打开命名管道
 8     HANDLE hPipe;
 9     hPipe= CreateFile("\\\\.\\pipe\\FileMonitor", GENERIC_READ | GENERIC_WRITE, 
10         0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
11     if(INVALID_HANDLE_VALUE == hPipe)
12     {
13         AfxMessageBox("打开命名管道失败!");
14         hPipe = NULL;
15         return 0;
16     }
17     //开始传递信息
18     DWORD dwLen;
19     const int nBufferLen = 256;
20     char cRecvMsg[nBufferLen];
21     char cSendMsg[nBufferLen];
22     CString strSendMsg = "";
23 
24     //向客户端发送数据
25     strSendMsg = "发送的数据";
26             
27     if(strSendMsg == "")
28     {
29         AfxMessageBox("空字符串,不能发送!");
30         return 0;
31     }
32     strcpy(cSendMsg, strSendMsg);  
33     WriteFile(hPipe, cSendMsg, strlen(cSendMsg) + 1, &dwLen, NULL);       
34     //接收客户端反馈的数据  
35     ReadFile(hPipe, cRecvMsg, nBufferLen, &dwLen, NULL);  //读取管道中的内容(管道是一种特殊的文件)
 

推荐阅读
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文详细探讨了HTML表单中GET和POST请求的区别,包括它们的工作原理、数据传输方式、安全性及适用场景。同时,通过实例展示了如何在Servlet中处理这两种请求。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • 微软Exchange服务器遭遇2022年版“千年虫”漏洞
    微软Exchange服务器在新年伊始遭遇了一个类似于‘千年虫’的日期处理漏洞,导致邮件传输受阻。该问题主要影响配置了FIP-FS恶意软件引擎的Exchange 2016和2019版本。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 深入解析TCP/IP五层协议
    本文详细介绍了TCP/IP五层协议模型,包括物理层、数据链路层、网络层、传输层和应用层。每层的功能及其相互关系将被逐一解释,帮助读者理解互联网通信的原理。此外,还特别讨论了UDP和TCP协议的特点以及三次握手、四次挥手的过程。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
author-avatar
一切近乎完美
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有