VC命名管道通信的实现
c语言有名管道fifo管道的用法

c语言有名管道fifo管道的用法【C语言有名管道(FIFO管道)的用法】中括号为主题的文章【引言】C语言是一种广泛应用于系统软件开发的编程语言,拥有丰富的库函数和系统调用接口。
在C语言中,有名管道(也称为FIFO管道)是一种特殊的文件类型,用于实现不同进程之间的通信。
本文将一步一步详细介绍C语言有名管道(FIFO 管道)的用法,以帮助读者更好地理解和使用该功能。
【目录】一、什么是有名管道二、有名管道的创建三、有名管道的打开和关闭四、有名管道的读写操作五、有名管道的进程间通信六、有名管道的应用示例七、有名管道的优缺点八、总结【一、什么是有名管道】有名管道是一种特殊的文件类型,在文件系统中以文件的形式存在。
它是C语言用于进程间通信的一种方式,可以实现不同进程之间的数据传输。
有名管道是一种半双工的通信机制,允许一个进程写入数据到管道,同时另一个进程从管道中读取数据。
有名管道适用于在不相关的进程之间进行通信,特别是父子进程之间。
【二、有名管道的创建】要创建一个有名管道,首先需要使用C语言库函数mkfifo来创建一个文件节点(相当于管道的入口)。
mkfifo函数的原型如下:int mkfifo(const char *pathname, mode_t mode);其中,pathname代表要创建的有名管道的文件路径,mode用于设置管道的权限。
例如,以下代码会创建一个名为myfifo的有名管道:#include <sys/types.h>#include <sys/stat.h>int main() {mkfifo("myfifo", 0666);return 0;}运行该程序后,系统中将会被创建一个名为myfifo的有名管道。
【三、有名管道的打开和关闭】打开一个有名管道以进行读取和写入操作,可以使用C语言库函数open。
open 函数的原型如下:int open(const char *pathname, int flags);其中,pathname代表要打开的有名管道的文件路径,flags用于指定打开管道的方式(只读、只写、读写)。
c语言进程间通信的几种方法

c语言进程间通信的几种方法一、管道(Pipe)管道是一种半双工的通信方式,它可以在两个相关的进程之间传递数据。
具体而言,管道可以分为匿名管道(只能在父子进程之间使用)和有名管道(可以在不相关的进程之间使用)。
1. 匿名管道匿名管道主要通过pipe函数创建,它只能在具有亲缘关系的进程之间使用。
父进程调用pipe函数创建管道后,可以通过fork函数创建子进程,并通过管道进行通信。
父进程通过write函数将数据写入管道,子进程通过read函数从管道中读取数据。
2. 有名管道有名管道是一种特殊的文件,可以在不相关的进程之间进行通信。
创建有名管道可以使用mkfifo函数,在进程间通信时,一个进程以写的方式打开管道,另一个进程以读的方式打开管道,就可以进行数据的读写。
二、共享内存(Shared Memory)共享内存是一种高效的进程间通信方式,它可以在多个进程之间共享同一块物理内存区域。
具体而言,共享内存的创建过程包括创建共享内存区域、映射到进程的虚拟地址空间和访问共享内存。
1. 创建共享内存区域使用shmget函数创建共享内存区域,需要指定共享内存的大小和权限等参数。
2. 映射到进程的虚拟地址空间使用shmat函数将共享内存区域映射到进程的虚拟地址空间,使得进程可以通过访问内存的方式进行通信。
3. 访问共享内存通过对共享内存区域的读写操作,实现进程间的数据交换。
三、消息队列(Message Queue)消息队列是一种可以在不相关的进程之间传递数据的通信方式。
它是一种存放在内核中的消息链表,进程可以通过系统调用对消息进行发送和接收。
1. 创建消息队列使用msgget函数创建消息队列,需要指定消息队列的键值和权限等参数。
2. 发送消息使用msgsnd函数向消息队列中发送消息,需要指定消息队列的标识符和消息的类型等参数。
3. 接收消息使用msgrcv函数从消息队列中接收消息,需要指定消息队列的标识符、接收消息的缓冲区和接收消息的类型等参数。
linux c管道的用法

linux c管道的用法
Linux中的C管道是一种进程间通信机制,允许一个进程将其
输出连接到另一个进程的输入,从而实现数据的传输和共享。
C语言中可以使用管道来创建和操作管道。
以下是一些常见的C管道用法:
1. 创建管道:使用`pipe()`函数来创建管道。
该函数接受一个
整型数组作为参数,其中包含两个文件描述符。
第一个描述符用于读管道,第二个描述符用于写管道。
2. 管道通信:通过fork()函数创建进程后,可以使用管道进行
进程间通信。
一个进程将数据写入管道的写描述符,而另一个进程从管道的读描述符读取数据。
3. 关闭管道描述符:进程在使用完管道后,应该关闭不再需要的管道描述符。
使用`close()`函数来关闭文件描述符。
4. 重定向管道:通过dup2()函数将标准输入、标准输出或标准错误重定向到管道的输入或输出描述符。
5. 非阻塞管道:通过设置文件描述符的属性,可以将管道设置为非阻塞模式,从而避免在读取或写入管道时进程被阻塞。
6. 管道和多进程:可以使用多个管道在多个进程之间进行通信。
一个进程使用一个管道的读端和另一个进程的写端进行通信,并使用另一个管道的读端和第三个进程的写端进行通信,以此
类推。
这些是一些基本的C管道用法,还有其他更高级的用法,如
使用select()函数进行多路复用、使用匿名管道和命名管道等。
在使用C管道时,需要注意正确地打开、读取和关闭管道描
述符,并处理可能的错误。
进程间通信-命名管道实现

进程间通信-命名管道实现引⼦好,到这⾥呢,就需要介绍实现进程间通信的第四种⽅式了,也就是通过命名管道来实现,前⾯介绍的那三种⽅式呢,都是有缺陷或者说局限性太强,⽽这⾥介绍的命名管道相对来说,在这⽅⾯就做得好很多了,⽐如,剪贴板的话只能实现本机上进程之间的通信,⽽邮槽的话虽然是可以实现跨⽹络之间的进程的通信,但⿇烦的是邮槽的服务端只能接收数据,邮槽的客户端只能发送数据,太悲剧了,⽽对于匿名管道的话,其也只能实现本机上进程之间的通信,你要是能够实现本机进程间的通信也就算了,关键是它还只⽤来实现本地的⽗⼦进程之间的通信,也太局限了吧?⽽这⾥介绍的这个命名管道的话,就和他们有些不同了,在功能上也就显得强⼤很多了,⾄少其可以实现跨⽹络之间的进程的通信,同时其客户端既可以接收数据也可以发送数据,服务端也是既可以接收数据,⼜可以发送数据的。
命名管道概述命名管道是通过⽹络来完成进程之间的通信的,命名管道依赖于底层⽹络接⼝,其中包括有 DNS 服务,TCP/IP 协议等等机制,但是其屏蔽了底层的⽹络协议细节,对于匿名管道⽽⾔,其只能实现在⽗进程和⼦进程之间进⾏通信,⽽对于命名管道⽽⾔,其不仅可以在本地机器上实现两个进程之间的通信,还可以跨越⽹络实现两个进程之间的通信。
命名管道使⽤了 Windows 安全机制,因⽽命名管道的服务端可以控制哪些客户有权与其建⽴连接,⽽哪些客户端是不能够与这个命名管道建⽴连接的。
利⽤命名管道机制实现不同机器上的进程之间相互进⾏通信时,可以将命名管道作为⼀种⽹络编程⽅案时,也就是看做是 Socket 就可以了,它实际上是建⽴了⼀个客户机/服务器通信体系,并在其中可靠的传输数据。
命名管道的通信是以连接的⽅式来进⾏的,服务器创建⼀个命名管道对象,然后在此对象上等待连接请求,⼀旦客户连接过来,则两者都可以通过命名管道读或者写数据。
命名管道提供了两种通信模式:字节模式和消息模式。
在字节模式下,数据以⼀个连续的字节流的形式在客户机和服务器之间流动,⽽在消息模式下,客户机和服务器则通过⼀系列的不连续的数据单位,进⾏数据的收发,每次在管道上发出⼀个消息后,它必须作为⼀个完整的消息读⼊。
VC中利用管道技术取得DOS或者命令行以及外部程序的执行结果

VC中利用管道技术取得DOS或者命令行以及外部程序的执行结果管道技术是一种常用的方法,用于在操作系统或者编程语言中将输出流关联到输入流。
通过使用管道,可以将一个进程的输出直接作为另一个进程的输入,从而实现进程之间的通信和数据传递。
在VC中,可以利用管道技术获取DOS或者命令行以及外部程序的执行结果。
1.执行DOS或者命令行命令要在VC中执行DOS或者命令行命令并获取执行结果,首先需要使用`popen(`函数创建一个管道,并将命令作为参数传递给该函数。
`popen(`函数返回一个文件指针,可以通过该指针读取命令的输出结果。
以下是一个示例代码:```c#include <stdio.h>int main(void)FILE *fp;char buf[1024];fp = _popen("dir", "r");if (fp == NULL)return 1;}while (fgets(buf, sizeof(buf), fp) != NULL)printf("%s", buf);}_pclose(fp);return 0;```上述代码中,使用`_popen(`函数执行`dir`命令并将其结果输出到文件指针`fp`中。
然后,通过循环读取文件指针中的内容,并打印到标准输出中。
最后,使用`_pclose(`函数关闭文件指针。
2.执行外部程序要在VC中执行外部程序并获取执行结果,也可以使用`popen(`函数。
只需将外部程序的路径和参数作为命令传递给`popen(`函数即可。
以下是一个示例代码:```c#include <stdio.h>int main(void)FILE *fp;char buf[1024];fp = _popen("C:\\Program Files\\example.exe arg1 arg2", "r");if (fp == NULL)return 1;}while (fgets(buf, sizeof(buf), fp) != NULL)printf("%s", buf);}_pclose(fp);return 0;```上述代码中,将外部程序的路径和参数作为命令传递给`_popen(`函数,跳转到该路径下并执行该程序,并将执行结果输出到文件指针`fp`中。
C++进程通信之命名管道

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);功能:创建命名管道的实例并返回⽤于后续管道操作的句柄。
[转载]使用命名管道实现进程间通信
![[转载]使用命名管道实现进程间通信](https://img.taocdn.com/s3/m/545bc0ebaff8941ea76e58fafab069dc5022473e.png)
[转载]使⽤命名管道实现进程间通信使⽤命名管道实现进程间通信来源 : 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]\(括号内为参数)。
对于同⼀主机来讲允许有多个同⼀命名管道的实例并且可以由不同的进程打开,但是不同的管道都有属于⾃⼰的管道缓冲区⽽且有⾃⼰的通讯环境互不影响,并且命名管道可以⽀持多个客户端连接⼀个服务器端。
命名管道客户端不但可以与本机上的服务器通讯也可以同其他主机上的服务器通讯。
C语言进程间通信方法

C语言进程间通信方法在多道程序设计中,不同的进程之间需要进行通信和协调,以实现数据交换和资源共享。
而在C语言中,有几种主要的进程间通信方法,包括管道、信号、共享内存和消息队列。
下面将逐一介绍这些方法的特点和应用场景。
1. 管道(Pipe)管道是一种半双工的通信方式,它可以在父进程和子进程之间创建一个用于通信的文件描述符。
管道可以分为匿名管道和命名管道两种。
匿名管道只能在具有亲缘关系的进程之间使用,使用函数pipe()可以创建一个管道,并返回两个文件描述符,分别用于读取和写入管道。
父进程可以将数据写入管道,子进程则从管道中读取数据。
命名管道则允许没有亲缘关系的进程之间进行通信,用于创建命名管道的函数为mkfifo()。
不同于匿名管道,命名管道可以在文件系统中创建一个特殊的文件,进程可以通过打开该文件进行通信。
2. 信号(Signal)信号是一种异步的通信方式,它用于通知进程发生了某个特定事件。
在C语言中,可以使用signal()函数来设置信号的处理函数。
进程可以通过发送信号给另一个进程来实现简单的通信。
信号的应用场景较为广泛,例如进程终止和异常处理。
当进程接收到信号时,可以根据信号的类型来执行相应的处理操作。
3. 共享内存(Shared Memory)共享内存允许多个进程之间访问同一块物理内存,以实现高效的数据共享。
进程可以使用shmget()函数创建一个共享内存区域,并使用shmat()函数将共享内存映射到本进程的地址空间中。
共享内存的好处在于数据传输效率高,因为进程直接访问内存而无需通过中介来实现通信。
然而,共享内存的使用需要更加小心,因为没有任何机制来保护共享数据的完整性和一致性。
4. 消息队列(Message Queue)消息队列是一种可以在不同进程之间传输数据的通信方式。
它允许将消息发送到消息队列中,并由其他进程从中读取。
消息的顺序按照发送的顺序进行。
通过调用msgget()函数可以创建或打开一个消息队列,而使用msgsnd()函数和msgrcv()函数分别用于发送和接收消息。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC命名管道通信的实现
无论是SQL Server的用户,还是PB的用户,作为C/S结构开发环境,他们在网络通信的
实现上,都有一种共同的方法——命名管道。
由于当前操作系统的不惟一性,各个系统
都有其独自的通信协议,导致了不同系统间通信的困难。
尽管TCP/IP协议目前已发展成
为Internet的标准,但仍不能保证C/S应用程序的顺利进行。
命名管道作为一种通信方
法,有其独特的优越性,这主要表现在它不完全依赖于某一种协议,而是适用于任何
协议——只要能够实现通信。
命名管道具有很好的使用灵活性,表现在:
1) 既可用于本地,又可用于网络。
2) 可以通过它的名称而被引用。
3) 支持多客户机连接。
4) 支持双向通信。
5) 支持异步重叠I/O操作。
不过,当前只有Windows NT支持服务端的命名管道技术。
一、命名管道程序设计的实现
1.命名管道Server和Client间通信的实现流程
(1)建立连接:服务端通过函数CreateNamedPipe创建一个命名管道的实例并返回用于
今后操作的句柄,或为已存在的管道创建新的实例。
如果在已定义超时值变为零以前,有
一个实例管道可以使用,则创建成功并返回管道句柄,并用以侦听来自客户端的连接请求,
该功能通过ConnectNamedPipe函数实现。
另一方面,客户端通过函数WaitNamedPipe使服务进程等待来自客户的实例连接,如
果在超时值变为零以前,有一个管道可以为连接使用,则WaitNamedPipe将返回True,并
通过调用CreateFile或CallNamedPipe来呼叫对服务端的连接。
此时服务端将接受客户端
的连接请求,成功建立连接,服务端ConnectNamedPipe返回True,客户端CreateFile将返
回一指向管道文件的句柄。
从时序上讲,首先是客户端通过WaitNamedPipe使服务端的CreateFile在限时时间内
创建实例成功,然后双方通过ConnectNamedPipe和CreateFile成功连接,并返回用以通信
的文件句柄,此时双方即可进行通信。
(2)通信实现:建立连接之后,客户端与服务器端即可通过ReadFile和WriteFile,
利用得到的管道文件句柄,彼此间进行信息交换。
(3)连接终止:当客户端与服务端的通信结束,或由于某种原因一方需要断开时,客
户端应调用CloseFile,而服务端应接着调用DisconnectNamedPipe。
当然服务端亦可通
过单方面调用DisconnectNamedPipe终止连接。
最后应调用函数CloseHandle 来关闭该管道。
2.命名管道服务器端和客户端代码实现
(1)客户端:
HANDLE CltHandle;
charpipenamestr[30];
sprintf(pipenamestr,″\\\\servername\\pipe\\pipename″)
if (WaitNamedPipe( pipenamestr, NMPWAIT—WAIT—FOREVER)==FALSE
// 管道名要遵循UNC,格式为\ \.\pipe\pipname,名字不分大小写。
AfxMessageBox(″操作失败,请确定服务端正确建立管道实例!″);
Else
CltHandle=CreateFile(pipenamestr, GENERIC—READ|GENERIC—WRITE, FILE—SHARE—READ| FILE—SHARE—WRITE,NULL, OPEN—EXISTING,
//为了与命名管道连接,此参数应一直为OPEN—EXISTING
FILE—ATTRIBUTE—ARCHIVE|FILE—FLAG—WRITE—THROUGH,
// FILE—FLAG—WRITE—THROUGH会使管道WriteFile调用处于阻塞状态,直到数据传送成功。
NULL);
If (CltHandle== INVALID—HANDLE—VALUE)
AfxMessageBox(″管道连接失败″);
Else
DoUsertTransactInfo();
//执行用户自定义信息交换函数——从管道读、写信息。
……
(2)服务端:
HANDLE SvrHandle;
charpipenamestr[30];
sprintf(pipenamestr,″\\\\.\\pipe\\pipename″)
SvrHandle=CreateNamedPipe(pipenamestr,
PIPE—ACCESS—DUPLEX|FILE—FLAG—WRITE—THROUGH,
//阻塞模式,这种模式仅对″字节传输管道″操作有效。
FILE—WAIT|PIPE—TYPE—BYTE,
//字节模式
PIPE—UNLIMITED—INSTANCES,
128,128,
NULL,NULL);
// SECURITY—ATTRIBUTES结构指针,描述一个新管道,确定子进程的继承权,如果为NULL则该命名管道不能被继承。
If (SvrHandle==INVALID—HANDLE—VALUE)
AfxMessageBox(″管道创建失败,请确定客户端提供连接可能!″);
Else
If (ConnectNamedPipe(SvrHandle,NULL)==FALSE)
AfxMessageBox(″建立连接失败!″);
Else
DoUsertTransactInfo();
//用户自定义信息交换函数
……
二、程序设计的注意事项
1.如果命名管道客户端已打开,函数将会强迫关闭管道,用DisconnectNamedPipe关闭
的管道,其客户端还必须用CloseHandle来关闭最后的管道。
2. ReadFile和WriteFile的hFile句柄是由CreateFile及ConnectNamedPipe返回得到。
3.一个已被某客户端连接的管道句柄在被另一客户通过ConnectNamedPipe 建立连接之前,服务端必须用DisconnectNamedPipe函数对已存在的连接进行强行拆离。
服务端拆离管道会造成管道中数据的丢失,用FlushFileBuffers函数可以保证数据不被丢失。
4.命名管道服务端可以通过新创建的管道句柄或已被连接过其他客户的管道句
柄来使用ConnectNamedPipe函数,但在连接新的客户端之前,服务端必须用函数
DisconnectNamedPipe切断之前的客户句柄,否则ConnectNamedPipe 将会返回False。
5.阻塞模式,这种模式仅对“字节传输管道"操作有效,并且要求客户端与服务端不
在同一机器上。
如果用这种模式,则只有当函数通过网络向远端计算机管道缓冲器写数
据成功时,才能有效返回。
如果不用这种模式,系统会运行缺省方式以提高网络的工作效率。
6.用户必须用FILE—CREATE—PIPE—INSTANCE 来访问命名管道对象。
新的命名管
道建立后,来自安全参数的访问控制列表定义了访问该命名管道的权限。
所有命名管道
实例必须使用统一的管道传输方式、管道模式等参数。
客户端未启动,管道服务端不能
执行阻塞读操作,否则会发生空等的阻塞状态。
当最后的命名管道实例的最后一个句柄
被关闭时,就应该删除该命名管道。