在linux程序中如何使用命名管道实现对文件的读写、求帮助

在linux程序中如何使用命名管道实现对文件的读写、求帮助,第1张

//创建server管道

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)的 *** 作系统上创建。

当讨论管道时,通常涉及到两个进程:客户进程和服务进程。服务进程负责创建管道。客户进程连接到管道。服务进程可以创建一个管道的多个实例,以此支持多个客户进程。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8104284.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存