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
成都创新互联成立于2013年,先为香洲等服务建站,香洲等地企业,进行企业商务咨询服务。为香洲企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
- #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;
- }
附件:http://down.51cto.com/data/2362203
本文标题:unix无关系进程间通信-有名管道
本文来源:http://scgulin.cn/article/pisodh.html