2.4实验四:使用命名管道实现进程通信
- 格式:doc
- 大小:84.50 KB
- 文档页数:6
进程间通信-命名管道实现引⼦好,到这⾥呢,就需要介绍实现进程间通信的第四种⽅式了,也就是通过命名管道来实现,前⾯介绍的那三种⽅式呢,都是有缺陷或者说局限性太强,⽽这⾥介绍的命名管道相对来说,在这⽅⾯就做得好很多了,⽐如,剪贴板的话只能实现本机上进程之间的通信,⽽邮槽的话虽然是可以实现跨⽹络之间的进程的通信,但⿇烦的是邮槽的服务端只能接收数据,邮槽的客户端只能发送数据,太悲剧了,⽽对于匿名管道的话,其也只能实现本机上进程之间的通信,你要是能够实现本机进程间的通信也就算了,关键是它还只⽤来实现本地的⽗⼦进程之间的通信,也太局限了吧?⽽这⾥介绍的这个命名管道的话,就和他们有些不同了,在功能上也就显得强⼤很多了,⾄少其可以实现跨⽹络之间的进程的通信,同时其客户端既可以接收数据也可以发送数据,服务端也是既可以接收数据,⼜可以发送数据的。
命名管道概述命名管道是通过⽹络来完成进程之间的通信的,命名管道依赖于底层⽹络接⼝,其中包括有 DNS 服务,TCP/IP 协议等等机制,但是其屏蔽了底层的⽹络协议细节,对于匿名管道⽽⾔,其只能实现在⽗进程和⼦进程之间进⾏通信,⽽对于命名管道⽽⾔,其不仅可以在本地机器上实现两个进程之间的通信,还可以跨越⽹络实现两个进程之间的通信。
命名管道使⽤了 Windows 安全机制,因⽽命名管道的服务端可以控制哪些客户有权与其建⽴连接,⽽哪些客户端是不能够与这个命名管道建⽴连接的。
利⽤命名管道机制实现不同机器上的进程之间相互进⾏通信时,可以将命名管道作为⼀种⽹络编程⽅案时,也就是看做是 Socket 就可以了,它实际上是建⽴了⼀个客户机/服务器通信体系,并在其中可靠的传输数据。
命名管道的通信是以连接的⽅式来进⾏的,服务器创建⼀个命名管道对象,然后在此对象上等待连接请求,⼀旦客户连接过来,则两者都可以通过命名管道读或者写数据。
命名管道提供了两种通信模式:字节模式和消息模式。
在字节模式下,数据以⼀个连续的字节流的形式在客户机和服务器之间流动,⽽在消息模式下,客户机和服务器则通过⼀系列的不连续的数据单位,进⾏数据的收发,每次在管道上发出⼀个消息后,它必须作为⼀个完整的消息读⼊。
C++进程通信之命名管道命名管道定义⼀个命名管道是⼀个命名的,单向或双⾯管道的管道服务器和⼀个或多个管道客户端之间的通信。
命名管道的所有实例共享相同的管道名称,但每个实例都有⾃⼰的缓冲区和句柄,并为客户端/服务器通信提供单独的管道。
实例的使⽤使多个管道客户端能够同时使⽤同⼀个命名管道。
这⾥要理解实例的概念:当我⽤CreateNamedPipe在服务器端创建⼀个名为pipeTest的命名管道时,即pipeTest拥有了⼀个实例。
再次重复刚才的操作时,即创建了pipeTest的第⼆个实例;当⽤CreateNamedPipe在服务器端创建⼀个名为pipeTestAnother的命名管道时,则该pipeTestAnother管道拥有了第⼀个实例。
命名管道的使⽤步骤服务器端:⾸先,使⽤创建属于该管道的实例。
然后等待客户端实例的连接,服务器端可以使⽤ConnectNamedPipe进⾏阻塞同步等待客户端实例的连接,也可以⾮阻塞,然后执⾏ReadFile不停读取客户端发送到管道的数据。
客户端:执⾏WaitNamedPipe(不是真正的⽤于连接的函数)来等待管道的出现,存在管道后,执⾏CreateFile来连接存在的服务器管道,获取对应句柄后,执⾏WriteFile往管道发送数据。
上⾯是以最简单的单向的客户端发送数据进管道,服务器端接受管道数据。
还有其他的通信选项。
包括双通道的Read&Write。
Read&Write过程中的同步与异步;按字节流⽅式/消息的⽅式写⼊/读取管道数据。
CreateNamedPipeHANDLE CreateNamedPipeA([in] LPCSTR lpName,[in] DWORD dwOpenMode,[in] DWORD dwPipeMode,[in] DWORD nMaxInstances,[in] DWORD nOutBufferSize,[in] DWORD nInBufferSize,[in] DWORD nDefaultTimeOut,[in, LPSECURITY_ATTRIBUTES lpSecurityAttributes);功能:创建命名管道的实例并返回⽤于后续管道操作的句柄。
第1篇一、实验目的1. 理解进程通信的概念和原理;2. 掌握进程通信的常用机制和方法;3. 能够使用进程通信机制实现进程间的数据交换和同步;4. 增强对操作系统进程管理模块的理解。
二、实验环境1. 操作系统:Linux2. 编程语言:C3. 开发环境:GCC三、实验内容1. 进程间通信的管道机制2. 进程间通信的信号量机制3. 进程间通信的共享内存机制4. 进程间通信的消息队列机制四、实验步骤1. 管道机制(1)创建管道:使用pipe()函数创建管道,将管道文件描述符存储在两个变量中,分别用于读和写。
(2)创建进程:使用fork()函数创建子进程,实现父子进程间的通信。
(3)管道读写:在父进程中,使用read()函数读取子进程写入的数据;在子进程中,使用write()函数将数据写入管道。
(4)关闭管道:在管道读写结束后,关闭对应的管道文件描述符。
2. 信号量机制(1)创建信号量:使用sem_open()函数创建信号量,并初始化为1。
(2)获取信号量:使用sem_wait()函数获取信号量,实现进程同步。
(3)释放信号量:使用sem_post()函数释放信号量,实现进程同步。
(4)关闭信号量:使用sem_close()函数关闭信号量。
3. 共享内存机制(1)创建共享内存:使用mmap()函数创建共享内存区域,并初始化数据。
(2)映射共享内存:在父进程和子进程中,使用mmap()函数映射共享内存区域。
(3)读写共享内存:在父进程和子进程中,通过指针访问共享内存区域,实现数据交换。
(4)解除映射:在管道读写结束后,使用munmap()函数解除映射。
4. 消息队列机制(1)创建消息队列:使用msgget()函数创建消息队列,并初始化消息队列属性。
(2)发送消息:使用msgsnd()函数向消息队列发送消息。
(3)接收消息:使用msgrcv()函数从消息队列接收消息。
(4)删除消息队列:使用msgctl()函数删除消息队列。
[转载]使⽤命名管道实现进程间通信使⽤命名管道实现进程间通信来源 : VChelp4.5 进程间通信在Win32下提供的进程间通信⽅式有以下⼏种:剪贴板Clipboard:在16位时代常使⽤的⽅式,CWnd类中提供了⽀持。
COM/DCOM:通过COM系统的代理存根⽅式进⾏进程间数据交换,但只能够表现在对接⼝函数的调⽤时传送数据,通过DCOM可以在不同主机间传送数据。
Dynamic Data Exchange (DDE):在16位时代常使⽤的⽅式。
File Mapping:⽂件映射,在32位系统中提供的新⽅法,可⽤来共享内存。
Mailslots:邮件槽,在32位系统中提供的新⽅法,可在不同主机间交换数据,分为服务器⽅和客户⽅,双⽅可以通过其进⾏数据交换,在Win9X下只⽀持邮件槽客户。
Pipes:管道,分为⽆名管道:在⽗⼦进程间交换数据;有名管道:可在不同主机间交换数据,分为服务器⽅和客户⽅,在Win9X下只⽀持有名管道客户。
RPC:远程过程调⽤,很少使⽤,原因有两个:复杂⽽且与UNIX系统的RCP并不完全兼容。
但COM/DCOM的调⽤是建⽴在RPC的基础上的。
Windows Sockets:⽹络套接⼝,可在不同主机间交换数据,分为服务器⽅和客户⽅。
(相关介绍见Visual C++/MFC⼊门教程第六章⽹络通信开发)WM_COPYDATA:通过发送WM_COPYDATA消息并将数据放在参数中来传递数据给其他进程。
下⾯主要介绍⼀下命名管道的⽤法,命名管道是⼀个有名字,单向或双向的通信管道。
管道的名称有两部分组成:计算机名和管道名,例如\\[host_name]\pipe\[pipe_name]\(括号内为参数)。
对于同⼀主机来讲允许有多个同⼀命名管道的实例并且可以由不同的进程打开,但是不同的管道都有属于⾃⼰的管道缓冲区⽽且有⾃⼰的通讯环境互不影响,并且命名管道可以⽀持多个客户端连接⼀个服务器端。
命名管道客户端不但可以与本机上的服务器通讯也可以同其他主机上的服务器通讯。
进程的管道通信实验是一个非常有用的实验,它允许两个进程之间进行数据交换。
这个实验主要涉及到了管道、管道缓冲区以及进程之间的通信机制。
以下是对这个实验的总结:
1. 管道的概念和作用:
管道是一种用于进程间通信的机制,它允许两个进程之间进行数据交换。
在管道通信实验中,我们创建了一个管道,并使用它来在两个进程之间传递数据。
管道的作用是连接两个进程,使得它们可以相互发送和接收数据。
2. 管道缓冲区:
管道缓冲区是管道中的一个重要概念。
当一个进程向管道写入数据时,数据会被写入缓冲区中,等待另一个进程读取。
当缓冲区中的数据被读取后,缓冲区中的数据会被移除,为新的数据腾出空间。
3. 进程间的通信:
在管道通信实验中,我们创建了两个进程,并使用管道来在它们之间进行通信。
一个进程向管道写入数据,另一个进程从管道读取数据。
通过这种方式,两个进程可以相互发送和接收数据。
4. 实验中的问题和解决方案:
在实验中,我们遇到了一些问题,如管道中的数据读写错误、进程间的通信问题等。
为了解决这些问题,我们采取了一些措施,如检查数据的读写是否正确、确保进程间的通信畅通等。
5. 实验的意义和收获:
通过这个实验,我们深入了解了进程间通信的概念和机制,并掌握了管道通信的基本原理和方法。
此外,我们还学会了如何解决实验中遇到的问题,提高了我们的编程能力和解决问题的能力。
总之,进程的管道通信实验是一个非常有意义的实验,它让我们深入了解了进程间通信的原理和方法。
通过这个实验,我们不仅掌握了相关的知识和技能,还提高了我们的编程能力和解决问题的能力。
实验四:进程通信实验实验学时:3学时一、实验目的1、熟悉操作系统进程通信原理2、设计程序,实现共享内存、管道通信、消息通信二、实验基本原理1、进程间通信的几种方法简介(1)消息队列:消息队列是消息的链接表,包括Posix消息队列systemV消息队列。
有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
(2)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。
是针对其他通信机制运行效率较低而设计的。
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(3)无名管道(Pipe)及有名管道(named pipe):有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;无名管道可用于有亲缘关系的进程之间彼此的通信,进行通信时候必须有一定的机制保证对管道写和读的互斥:即在读是要关闭写的端口,而在写的时候也要保证读的一端是关闭的。
2、进程通信函数(1)消息队列有关系统调用函数a.创建消息队列使用msgget()函数:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key_t key, int flag) ;该函数成功调用返回消息队列标识符。
其中的key是关键字,可以由ftok()函数得到:key=ftok(“.”,’a’);其中”.”可以是任何目录,’a’是任意字符,即所有群组标识。
flag是标识,IPC_CREAT位表示创建,一般由服务器程序创建消息队列时使用。
如果是客户程序,必须打开现存的消息队列,必须不使用IPC_CREAT。
发送和接收的消息都必须使用一个类似msgbuf的结构表示,msgbuf结构定义如下:struct msgbuf{long mtype;char mtext[1];}上面的定义,消息内容只有一个字节,是不实用的,一般我们需要重新定义一个结构:struct amsgbuf{long mtype;char mtext[200];}其中的mtype都是消息类型。
操作系统实验报告用管道实现进程通信1. 实验目的(1)了解Windows系统环境下的进程通信机制。
(2)熟悉Windows系统提供的进程通信API。
2. 实验预备知识(1)根据《计算机操作系统实验指导》中相应内容填写(2)3. 实验内容一个基于有名管道的C/S模式应用,客户端发送命令到服务器,服务器执行命令,并将命令返回信息回传给客户端要求:A.客户端进程完成的工作1.建立私有有名管道2.打开服务端的共有有名管道3.等待用户输入命令4.将私有管道名和命令写入公有管道5.从私有管道中读服务端返回的结果B.服务端进程完成的工作1.建立服务端公有有名管道2.从公有有名管道中读取客户数据3.执行命令,并将结果写入客户私有管道4.实验代码服务器程序:// PipeClient.cpp : Defines the entrypoint for the console application.//#include "stdafx.h"#include "PipeClient.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCWinApp theApp;using namespace std;int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {BOOL rc=0;char lpName[]="\\\\.\\pipe\\myPipe";char InBuffer[50]="";char OutBuffer[50]="";DWORD BytesRead;int nRetCode=0; int err=0;while(1){strcpy(InBuffer,"");strcpy(OutBuffer,"");printf("Input Data Please!\n");scanf("%s",InBuffer);rc=strcmp(InBuffer,"end");if(rc=0){rc=CallNamedPipe(lpName,InBuffer,sizeof(InBuffer) ,OutBuffer,sizeof(OutBuffer),&BytesRead,NMPWAIT_USE_DEFAULT_ WAIT);break;}rc=WaitNamedPipe(lpName,NMPWAIT_WAIT_FOREVER);if(rc==0){err=GetLastError();printf("Wait Pipe Fail!err=%d\n",err);exit(1);}else printf("Wait Pipe Success!\n");rc=CallNamedPipe(lpName,InBuffer,sizeof(InBuffer) ,OutBuffer,sizeof(OutBuffer),&BytesRead,NMPWAIT_USE_DEFAULT_W AIT);rc=strcmp(OutBuffer,"end");if(rc==0) break;if(rc==0){err=GetLastError();printf("Pipe Call Fail!err=%d\n",err);exit(1);}else printf("Pipe Call Success!\nData from Server is %s\n",OutBuffer);}printf("Now Client to be END\n");return nRetCode;}客户端程序:// 24.cpp : Defines the entry point for the console application.#include "stdafx.h"#include "PipeServer.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////// //////////////////////////// The one and only application objectCWinApp theApp;using namespace std;int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {int nRetCode = 0;int err;BOOL rc;HANDLE hPipeHandle1;char lpName[]="\\\\.\\pipe\\myPipe";char InBuffer[50]="";char OutBuffer[50]="";DWORD BytesRead,BytesWrite;hPipeHandle1=CreateNamedPipe((LPCTSTR)lpName,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED|WRITE_DAC ,PIPE_TYPE_MESSAGE|PIPE_READMODE_BYTE|PIPE_WAIT, 1,20,30,NMPWAIT_USE_DEFAULT_WAIT,(LPSECURITY_ATTRIBUTES)NULL);if((hPipeHandle1==INVALID_HANDLE_VALUE)||(hPipeHand le1==NULL)){err=GetLastError();printf("Server Pipe Create Fail!err=%d\n");exit(1);}else printf("Server Pipe Create Success!\n");while(1){//guangdaorc=ConnectNamedPipe(hPipeHandle1,(LPOVERLAPPED)NU LL);if(rc==0){err=GetLastError();printf("Server Pipe Conner Fail err=%d\n",err);exit(2);}else printf("Server Pipe Conner Success!\n");strcpy(InBuffer,"");strcpy(OutBuffer,"");//命名管道读数据rc=ReadFile(hPipeHandle1,InBuffer,sizeof(InBuffer ),&BytesRead,(LPOVERLAPPED)NULL);if(rc==0&&BytesRead==0){err=GetLastError();printf("Server Read Pipe Fail!err=%d\n",err);exit(3);}else{printf("Server Read Pipe Success!\nDATA from Client is=%s\n",InBuffer);}rc=strcmp(InBuffer,"end");if(rc==0) break;printf("Please Input Data to Send\n");scanf("%s",OutBuffer);//向管道写数据rc=WriteFile(hPipeHandle1,OutBuffer,sizeof(OutBuf fer),&BytesWrite,(LPOVERLAPPED)NULL);if(rc==0) printf("Server Write Pipe Fail!\n");else printf("Server Write Pipe Success!\n");DisconnectNamedPipe(hPipeHandle1);rc=strcmp(OutBuffer,"end");if(rc==0) break;}printf("Now Server be END!\n");CloseHandle(hPipeHandle1);return nRetCode;}。
Linux进程间通信-命名管道前⾯我们讲了进程间通信的⼀种⽅式,。
我们知道,匿名管道只能⽤于⽗⼦关系的进程之间。
那么没有这种关系的进程之间该如何进⾏数据传递呢?1.什么是命名管道匿名管道是在缓存中开辟的输出和输⼊⽂件流的空间,只能⽤于⽗⼦关系的进程之间。
因为⽗⼦进程的输⼊和输出⽂件描述符是⼀致的。
命名管道是⼀种实际存在的FIFO⽂件,称作“管道⽂件”,⽤于不同进程之间,命名管道进程间打开同⼀个FIFO⽂件,进⾏数据传递。
我们可以像普通⽂件⼀样操作FIFO⽂件。
不同进程,引⽤同⼀个FIFO⽂件,进⾏数据传递。
2.创建命名管道mkfifo函数:创建⼀个命名管道int mkfifo(const char *filename,mode_t mode);filename:指定FIFO⽂件的名称mode:指定⽂件的读写权限3.访问命名管道打开FIFO⽂件有四种⽅式:open(const char *filename,O_RDONLY);open(const char *filename,O_RDONLY|O_NONBLOCK);open(const char *filename,O_WRONLY);open(const char *filename,O_WRONLY|O_NONBLOCK);需要注意的是,不能以O_RDWR模式打开FIFO⽂件,因为这样⼀个进程写⼊的数据会被该进程读取,FIFO⼀般只⽤做单向的数据传递。
open函数的第⼆个参数,表⽰是读管道,还是写管道。
O_NONBLOCK表⽰FIFO管道的读写是⾮阻塞的,默认的话,是阻塞的。
那么何为阻塞呢?⼀个进程写模式打开管道的时候,必须有另⼀个进程以读模式打开;或读模式的时候,必须有另⼀个进程写写模式打开,否则该进程open函数阻塞,直到满⾜以上关系。
⾮阻塞,意味着open函数会⽴即返回,若没有其他进程以只读⽅式打开,open返回-1,并且FIFO也不会被打开。
实验四 进程间通信一、实验目的1. 掌握利用管道机制实现进程间的通信的方法2. 掌握利用消息缓冲队列机制实现进程间的通信的方法3. 掌握利用共享存储区机制实现进程间的通信的方法4. 了解Linux系统中进程软中断通信的基本原理二、实验学时2学时三、实验内容1.掌握实现进程间通信的系统调用的功能和方法进程通信,是指进程之间交换信息。
从这个意义上讲,进程之间的同步、互斥也是一种信息交换,也是一种通信。
但是,这里所说的“通信”是指进程之间交换较多的信息这样一种情况,特别是在由数据相关和有合作关系的进程之间,这种信息交换是十分必要和数量较大的。
进程间通信是协调解决多个进程之间的约束关系,实现进程共同进展的关键技术,是多道系统中控制进程并发执行必不可少的机制。
(1)进程的通信方式:a. 直接通信是指信息直接传递给接收方,如管道。
在发送时,指定接收方的地址或标识,。
在接收时,允许接收来自任也可以指定多个接收方或广播式地址, send(Receiver, message)。
意发送方的消息,并在读出消息的同时获取发送方的地址, receive(Sender,message)b. 间接通信:借助于收发双方进程之外的共享数据结构作为通信中转,如消息队列。
这种数据结构称为缓冲区或信箱。
通常收方和发方的数目可以是任意的。
(2)进程间通信的类型:a. 共享存储器系统:基于共享数据结构的通信方式:只能传递状态和整数值(控制信息),包括进程互斥和同步所采用的信号量机制。
速度快,但传送信息量小,编程复杂,属于低级通信;基于共享存储区的通信方式:能够传送任意数量的数据,属于高级通信。
b. 消息传递系统:在消息传递系统中,进程间的数据交换以消息为单位,用户直接利用系统提供的一组通信命令(原语)来实现通信。
c. 管道通信:管道是一条在进程间以字节流方式传送的通信通道。
它由OS 核心的缓冲区(通 常几十KB)来实现,是单向的;在实质上,是一个有OS 维护的特殊共享文件,常用于命令行所指定的输入输出重定向和管道命令。
学生姓名:张鹏学号:150705040实验地点:数计学院407实验室实验课时:3学时实验器材:计算机课程名称:计算机操作系统实验名称:2.4实验四:使用命名管道实现进程通信一、实验目的1、进一步掌握windows系统环境下进程通信机制。
2、熟悉进程通信API二、实验环境及工具Windows 7 操作系统,VC6三、实验内容使用Windows系统提供的命名管道完成两个进程之间的通信,要求能正确使用创建命名管道CreateNamePipe()、连接命名管道ConnectNamePipe()、拆除命名管道的连接DisconnectNamePipe()、连接服务器已建立的命名管道CallNamePipe()、等待命名管道WaitNamePipe()等API.四、实验步骤服务端// PipeServer.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "PipeServer.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// The one and only application objectCWinApp theApp;using namespace std;int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){int nRetCode = 0;int err;BOOL rc;HANDLE hPipeHandle1;char lpName[]="\\\\.\\pipe\\myPipe";char InBuffer[50]="";char OutBuffer[50]="";DWORD BytesRead,BytesWrite;hPipeHandle1=CreateNamedPipe((LPCTSTR)lpName,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED|WRITE_DAC,PIPE_TYPE_MESSAGE|PIPE_READMODE_BYTE|PIPE_W AIT,1,20,30,NMPWAIT_USE_DEFAULT_WAIT,(LPSECURITY_A TTRIBUTES)NULL);if((hPipeHandle1==INV ALID_HANDLE_V ALUE)||(hPipeHandle1==NULL)){err=GetLastError();printf("Server Pipe Creat Fail!err=%d\n",err);exit(1);}else printf("Server Pipe Creat Success!\n");while(1){rc=ConnectNamedPipe(hPipeHandle1,(LPOVERLAPPED)NULL);if(rc==0){err=GetLastError();printf("Server Pipe Connect Fail err=%d\n",err);exit(2);}else printf("Server Pipe Connect Success\n");strcpy(InBuffer,"");strcpy(OutBuffer,"");rc=ReadFile(hPipeHandle1,InBuffer,sizeof(InBuffer),&BytesRead,(LPOVERLAPPED)NULL);if(rc==0&&BytesRead==0){err=GetLastError();printf("Server Read Pipe Fail err=%d\n",err);exit(3);}else{printf("Server Read Pipe Success!\nDA TA from Client is=%s\n",InBuffer);}rc=strcmp(InBuffer,"end");if(rc==0) printf("Server Write Pipe Fail!\n");else printf("Server Write Pipe Success!\n");DisconnectNamedPipe(hPipeHandle1);rc=strcmp(OutBuffer,"end");if(rc==0) break;}printf("Now Server be END!\n");CloseHandle(hPipeHandle1);/* // initialize MFC and print and error on failureif (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)){// TODO: change error code to suit your needscerr << _T("Fatal Error: MFC initialization failed") << endl;nRetCode = 1;}else{// TODO: code your application's behavior here.CString strHello;strHello.LoadString(IDS_HELLO);cout << (LPCTSTR)strHello << endl;}*/return nRetCode;}客户端// PipeClient.cpp : Defines the entry point for the console application.#include "stdafx.h"#include "PipeClient.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////// ////////// The one and only application objectCWinApp theApp;using namespace std;int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]){BOOL rc=0;char lpName[]="\\\\.\\pipe\\myPipe";char InBuffer[50]="";char OutBuffer[50]="";DWORD BytesRead;int nRetCode = 0; int err=0;while(1){strcpy(InBuffer,"");strcpy(OutBuffer,"");printf("Input Data Please!\n");scanf("%s",InBuffer);rc=strcmp(InBuffer,"end");// initialize MFC and print and error on failureif (rc==0){rc=CallNamedPipe(lpName,InBuffer,sizeof(InBuffer),OutBuffer,sizeof(Ou tBuffer),&BytesRead,NMPWAIT_USE_DEFAULT_WAIT);break;}rc=WaitNamedPipe(lpName,NMPWAIT_WAIT_FOREVER);if(rc==0)err=GetLastError();printf("Wait Pipe Fail!err=%d\n",err);exit(1);}else printf("Wait Pipe Success!\n");rc=CallNamedPipe(lpName,InBuffer,sizeof(InBuffer),OutBuffer,sizeof(Ou tBuffer),&BytesRead,NMPWAIT_USE_DEFAULT_WAIT);rc=strcmp(OutBuffer,"end");if(rc==0)break;if(rc==0){err=GetLastError();printf("Pipe Call Fail!err=%d\n",err);exit(1);}else printf("Pipe Call Success!\nData from Server is %s\n",Out Buffer);}printf("Now Client to be End!\n");return nRetCode;}五、实验结论Windows进程通信工具有管道Pipe、共享内存、文件映射等,其中管道通信是拥有两个端点通信句柄的进程间的通信方式。
分为单向和双向。
单向是指一个端点写,另一个端点读。
管道分为匿名管道和命名管道。
匿名管道适用于父进程和子进程、两个子进程之间。
匿名管道不能在网上和不相关进程间使用。
命名管道适用于不相关的进程和不同计算机之间。
命名管道在网络上同时和多个管道通信会困难许多。