unix 无关系进程间通信-有名管道
有名管道是专用于无关系进程间的通信
open("../share_fifo", O_RDONLY, 777); 这个以只读打开有名管道,会产生阻塞,直到有其它进程以写打开才会继续执行下去
open("../share_fifo", O_RDONLY|O_NONBLOCK, 777); 这个以只读且注明以非阻塞打开,open不会产生阻塞,导致read()函数对有无数据读完即离开
open(fifo,O_WRONLY, 777) 阻塞到其它进行以读打开这个管道
open(fifo,O_WRONLY|O_NONBLOCK, 777) 没有阻塞,如果没有其它进行以读打开管道会立即返回报错-1 ENXIO
写一个无读打开的管道会产生一个信号 SIGPIPE,可以捕捉以信号来进行后续处理
此例程,功能为一个服务进程 与 多个客户进程之间的通信
程序还需要进行一步完美
server.c
#include #include #include #include #include #include #include #include #include #include #define MAXLINE 100 pid_t str_handler(char*); void handler_client_corrupt(int); static char* itoa(int);//因为itoa是一个非标准C函数,因此需要自己定义 void del_fifo(void);//退出时将管道删除 int main() { int fd; int count = 10; int BUF_SIZE; pid_t client_id; //注册 程序退出时执行删除管道 if(atexit(del_fifo)) { perror("atexit\n"); exit(1); } #if 1 // 创建一个客户端到服务器共享有命管道,此管道必需不存在 if(0 != mkfifo("../share_fifo", 0777 )) { perror("mkfifo\n"); exit(1); } fputs("share_fifo has been created\n",stdout); #endif //打开管道并设置只读 fd = open("../share_fifo", O_RDONLY, S_IRUSR|S_IRGRP|S_IROTH); if(fd<0) { perror("open\n"); exit(1); } //初始化缓存数组 (MAXLINE > PIPE_BUF) ? (BUF_SIZE = PIPE_BUF) : (BUF_SIZE = MAXLINE); //原子操作写进fifo最大数据量,若超过会导致进行间的竟争 MAXLINE < PIPE_BUFPIPE_BUF = 4096 //#define PIPE_BUF 4096 //usr/lib/limits.h char buf[BUF_SIZE]; memset(buf, sizeof(buf), 0); //读取数据并进行处理 while(20) { //读客户端发来的信息内容,并冲洗标准输入出进行显示 int num; num = read(fd, buf, BUF_SIZE); if(-1 == num) { perror("read\n"); exit(1); } fputs(buf,stdout); //由于标准输出需要遇到换行符“\n”才会进行显示,而收到内容中没有换行符,使此函数进行冲洗显示 putchar('\n'); //回复客户端,并对回复的内容进行处理 client_id = str_handler(buf); //处理回复内容字符串 char str[100] = "receided successfully:"; strcat(str,itoa(client_id)); int len = strlen(str); char str_reply[len+1]; strcpy(str_reply, str); //处理客户端路径 char tmp[100]= "../"; strcat(tmp,itoa(client_id)); len = strlen(tmp); char path[len+1]; strcpy(path,tmp); //打开对应客户端的管道进行写操作 int cfd = open(path,O_WRONLY, S_IWUSR|S_IWGRP); if(cfd<0) { perror("open_1\n"); exit(1); } //回复对应的客户端 if(write(cfd, str_reply, (strlen(str_reply)+1) ) == -1) { perror("write\n"); exit(1); } //写完后关闭对应的管道 if(close(cfd)) { perror("close\n"); exit(1); } sleep(1); } if(close(fd)) { perror("close\n"); exit(1); } return 0; } pid_t str_handler(char*buf) { pid_t tmp; int len = strlen(buf); tmp = atoi(buf); printf("len :%d tmp:%d,buf:%s\n",len,tmp,buf); if( (tmp == 0) || (tmp < 0) ) { return -1; } return tmp; } static char* itoa(int i) { char * local = (char*) malloc(10); memset(local,10,0); sprintf(local,"%d",i); return local; } void del_fifo(void) { if(remove("../share_fifo")) { perror("remove\n"); exit(1); } }
client.c
#include #include #include #include #include #include #include #define MAXLINE 100 char buf[MAXLINE]; char tmp[100]= "../"; char* path; static char* itoa(int i) { char * local = (char*) malloc(10); memset(local,10,0); sprintf(local,"%d",i); return local; } void del_fifo(void) { if(remove(path)) { perror("remove\n"); exit(1); } } int main(int argc, char** argv) { int fd0 , fd1; int len; strcat(tmp,itoa(getpid())); len = strlen(tmp); char tmp_path[len+1]; strcpy(tmp_path,tmp); path = tmp_path; if(0 != mkfifo(path, 0777 )) { perror("mkfifo\n"); exit(1); } #if 0 fd0 = open("../client0", O_RDONLY, S_IRUSR|S_IRGRP); if(fd0<0) { perror("open_0\n"); exit(1); } #endif //处理回复内容字符串 char str[10]; memset(str,10,0); strcpy(str,itoa(getpid())); len = strlen(str); char str_send[len+1]; strcpy(str_send, str); printf("%s\n",str_send); fd1 = open("../share_fifo", O_WRONLY, S_IWUSR|S_IWGRP); if(fd1<0) { perror("open_1\n"); exit(1); } fd0 = open(path, O_RDONLY|O_NONBLOCK, S_IRUSR|S_IRGRP); if(fd0<0) { perror("open_0\n"); exit(1); } int count = 10; while(count--) { if(write(fd1, str_send, (strlen(str_send)+1) ) == -1) //if(write(fd1, "test\n", 5 ) == -1) { perror("write\n"); exit(1); } fputs("write complete\n",stdout); #if 0 if(close(fd1)) { perror("close\n"); exit(1); } #endif while(read(fd0, buf, MAXLINE)<=0); printf("%s\n",buf); sleep(1); } return 0; }
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~