mkfifo(Server_FIFO_Name,0777)
//打开服务器端口,等待读取。此时如果客户端还未写入数据服务器端会被阻塞。
server_fifo_fd = open(Server_FIFO_Name , O_RDONLY)
if( -1 == server_fifo_fd ){
fprintf( stderr , "Server fifo failure\n" )
exit(EXIT_FAILURE)
}
//从管道中读取数据。
read_res = read ( server_fifo_fd , &my_data , sizeof(my_data))
if(read_res >0){
//将字符串翻转.
reverse ( my_data.str )
//将客户端的pid号加入回送管道文件名中.
sprintf ( client_fifo, Client_FIFO_Name , my_data.client_pid)
//打开回送管道。
client_fifo_fd = open ( client_fifo , O_WRONLY )
if( -1 != client_fifo_fd ){
//向管道中写入返回的数据.
write ( client_fifo_fd , &my_data, sizeof(my_data))
close ( client_fifo_fd )
}
}
("\\\\.\\pipe\\ethan",PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,0,1,1024,1024,0,
NULL)
由于FIFO是作为一个有名文件存在于文件系统中的,需要确认你是否有创建文件的权限。看你上面写的文件的路径好像有问题哦。
下面是UNIX环境命名管道的例子。
头文件:
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<fcntl.h>
#include<limits.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<ctype.h>
#define SERVER_FIFO_NAME "/opt/chengxs/temp/fifo/serv_fifo" /*服务专用的fifo*/
#define CLIENT_FIFO_NAME "/opt/chengxs/temp/fifo/client_%d_fifo" /*客户专用的fifo*/
struct data_to_pass
{
pid_t client_pid
char text_data[256-1]
}
客户端:
/*
*客户程序
*/
#include"cliserv.h"
int main()
{
int server_fifo_fd,client_fifo_fd
struct data_to_pass my_request
int times_to_send
char client_fifo_name[256]
pid_t mypid
/*打开服务管道*/
server_fifo_fd = open(SERVER_FIFO_NAME,O_WRONLY)
if(server_fifo_fd == -1)
{
perror("Sorry,no server")
exit(1)
}
/*创建以进程ID命名的客户接收管道*/
mypid = getpid()
sprintf(client_fifo_name,CLIENT_FIFO_NAME,mypid)
if(mkfifo(client_fifo_name,0777) == -1)
{
perror(client_fifo_name)
exit(2)
}
/*向服务进程连续发送和接收五次数据*/
for(times_to_send=0times_to_send<5times_to_send++)
{
sprintf(my_request.text_data,"Hello from %d,%d",mypid,times_to_send)
my_request.client_pid = mypid
/*向服务进程发出请求*/
printf("%d send: %s,",mypid,my_request.text_data)
write(server_fifo_fd,&my_request,sizeof(my_request))
/*从服务进程接收回答,打开客户有名管道*/
client_fifo_fd = open(client_fifo_name,O_RDONLY)
if(client_fifo_fd!=-1)
{
if(read(client_fifo_fd,&my_request,sizeof(my_request))>0)
{
printf("%d received: %s\n",mypid,my_request.text_data)
}
close(client_fifo_fd)
}
}
close(server_fifo_fd)
unlink(client_fifo_fd)
exit(0)
}
服务端:
/*
*服务程序
*/
#include"cliserv.h"
int main()
{
int server_fifo_fd,client_fifo_fd
struct data_to_pass my_data
int nbytes
char client_fifo_name[256]
char * tmp_char_ptr
/*创建并打开服务FIFO*/
mkfifo(SERVER_FIFO_NAME,0777)
server_fifo_fd = open(SERVER_FIFO_NAME,O_RDONLY)
if(server_fifo_fd == -1)
{
perror("Server info failed!")
exit(1)
}
/*客户请求排队*/
sleep(10)
do
{
/*接收来自客户的请求*/
nbytes = read(server_fifo_fd,&my_data,sizeof(my_data))
if(nbytes>0)
{
/*处理客户请求*/
tmp_char_ptr = my_data.text_data
while(*tmp_char_ptr)
{
*tmp_char_ptr = toupper(*tmp_char_ptr)
tmp_char_ptr++
}
/*返回处理过的数据*/
sprintf(client_fifo_name,CLIENT_FIFO_NAME,my_data.client_pid)
client_fifo_fd = open(client_fifo_name,O_WRONLY)
if(client_fifo_fd != -1)
{
write(client_fifo_fd,&my_data,sizeof(my_data))
close(client_fifo_fd)
}
}
}while(nbytes>0)
close(server_fifo_fd)
unlink(SERVER_FIFO_NAME)
return 0
}
运行时:
先运行服务端程序,在运行客户端程序。
*** 作系统中负责线程间通讯的东西叫管道。管道(pipe)是进程用来通讯的共享内存区域。一个进程往管道中写入信息,而其它的进程可以从管道中读出信息。如其名,管道是进程间数据交流的通道。邮路(Mailslots)的功能与管道类似,也是进程间通讯(interprocess communications,IPC)的媒介,只不过其具体实现方式与管道有些差别。一个基于Win32的应用程序可以在邮路中储存消息,这些消息通常通过网络发往一个指定的计算机或某域名(域是共享一个组名的一组工作站或服务器。)下的所有计算机。你也可以使用命名管道代替邮路来进行进程间通信。命名管道最适合用来两个进程间的消息传递,邮路则更适合一个进程向多个进程广播消息。邮路具有一个重要的特点,它使用数据包广播消息。广播(broadcast)是网络传输中使用的术语,它意味着接收方收到数据后不发送确认消息通知发送方。而管道(这里的管道指命名管道,有关命名管道以下详解。)则不同,它更类似于打电话,你只对一个当事人说话,但是你却非常清楚你的话都被对方听到。邮路和管道一样,也是一个虚拟文件,它保存在内存中,但是你却必须使用普通的Win32文件函数访问它,比如CreateFile、ReadFile、WriteFile等。邮路中储存的数据可以是任何形式的,唯一的要求是不得超过64K。与磁盘文件不同的是,邮路是一个临时的对象,当某个邮路所有的句柄都关闭的时候,该邮路及其中的数据就被删除。
管道的类型有两种:匿名管道和命名管道。匿名管道是不命名的,它最初用于在本地系统中父进程与它启动的子进程之间的通信。命名管道更高级,它由一个名字来标识,以使客户端和服务端应用程序可以通过它进行彼此通信。而且,Win32命名管道甚至可以在不同系统的进程间使用,这使它成为许多客户/服务器应用程序的理想之选。
就像水管连接两个地方并输送水一样,软件的管道连接两个进程并输送数据。一个一个管道一旦被建立,它就可以象文件一样被访问,并且可以使用许多与文件 *** 作同样的函数。可以使用CreateFile函数获取一个已打开的管道的句柄,或者由另一个进程提供一个句柄。使用WriteFile函数向管道写入数据,之后这些数据可以被另外的进程用ReadFile函数读取。管道是系统对象,因此管道的句柄在不需要时必须使用CloseHandle函数关闭。
匿名管道只能单向传送数据,而命名管道可以双向传送。管道可以以比特流形式传送任意数量的数据。命名管道还可以将数据集合到称为消息的数据块中。命名管道甚至具有通过网络连接多进程的能力。但遗憾的是Windows9X不支持创建命名管道,它只能在WindowsNT系列(如Windows NT,Windows 2000,Windows XP)的 *** 作系统上创建。
当讨论管道时,通常涉及到两个进程:客户进程和服务进程。服务进程负责创建管道。客户进程连接到管道。服务进程可以创建一个管道的多个实例,以此支持多个客户进程。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)