unix 无关系进程间通信-有名管道

  1. 有名管道是专用于无关系进程间的通信
  2. open("../share_fifo", O_RDONLY, 777); 这个以只读打开有名管道,会产生阻塞,直到有其它进程以写打开才会继续执行下去
  3. open("../share_fifo", O_RDONLY|O_NONBLOCK, 777); 这个以只读且注明以非阻塞打开,open不会产生阻塞,导致read()函数对有无数据读完即离开
  4. open(fifo,O_WRONLY, 777) 阻塞到其它进行以读打开这个管道
  5. open(fifo,O_WRONLY|O_NONBLOCK, 777) 没有阻塞,如果没有其它进行以读打开管道会立即返回报错-1 ENXIO
  6. 写一个无读打开的管道会产生一个信号 SIGPIPE,可以捕捉以信号来进行后续处理
  7. 此例程,功能为一个服务进程 与 多个客户进程之间的通信
  8. 程序还需要进行一步完美

server.c

  
  
  
  
  1. #include <stdlib.h> 
  2. #include <sys/types.h> 
  3. #include <sys/stat.h> 
  4. #include <fcntl.h> 
  5. #include <unistd.h> 
  6. #include <limits.h> 
  7. #include <string.h> 
  8. #include <stdbool.h> 
  9. #include <stdio.h> 
  10. #include <stdlib.h> 
  11.  
  12. #define MAXLINE 100 
  13.  
  14. pid_t str_handler(char*); 
  15. void handler_client_corrupt(int); 
  16. static char* itoa(int);//因为itoa是一个非标准C函数,因此需要自己定义 
  17. void del_fifo(void);//退出时将管道删除 
  18.  
  19. int main() 
  20.         int fd; 
  21.         int count = 10
  22.         int BUF_SIZE; 
  23.         pid_t client_id; 
  24. //注册 程序退出时执行删除管道 
  25.       if(atexit(del_fifo)) 
  26.       { 
  27.             perror("atexit\n"); 
  28.             exit(1);          
  29.       } 
  30. #if 1 
  31. // 创建一个客户端到服务器共享有命管道,此管道必需不存在  
  32.         if(0 != mkfifo("../share_fifo", 0777 )) 
  33.         { 
  34.                 perror("mkfifo\n"); 
  35.                 exit(1); 
  36.         } 
  37.         fputs("share_fifo has been created\n",stdout); 
  38. #endif 
  39. //打开管道并设置只读 
  40.         fd = open("../share_fifo", O_RDONLY, S_IRUSR|S_IRGRP|S_IROTH); 
  41.          if(fd<0
  42.         { 
  43.                 perror("open\n"); 
  44.                 exit(1);                
  45.         }  
  46. //初始化缓存数组 
  47.         (MAXLINE > PIPE_BUF) ?  (BUF_SIZE = PIPE_BUF) :  (BUF_SIZE = MAXLINE); 
  48.         //原子操作写进fifo最大数据量,若超过会导致进行间的竟争 MAXLINE < PIPE_BUFPIPE_BUF = 4096 
  49.         //#define PIPE_BUF     4096 
  50.         //usr/lib/limits.h 
  51.         char buf[BUF_SIZE]; 
  52.         memset(buf, sizeof(buf), 0); 
  53. //读取数据并进行处理 
  54.         while(20) 
  55.         {      
  56. //读客户端发来的信息内容,并冲洗标准输入出进行显示 
  57.                 int num;   
  58.                 num = read(fd, buf, BUF_SIZE); 
  59.                 if(-1 == num) 
  60.                 { 
  61.                         perror("read\n"); 
  62.                         exit(1);                       
  63.                 } 
  64.                 fputs(buf,stdout); 
  65.                 //由于标准输出需要遇到换行符“\n”才会进行显示,而收到内容中没有换行符,使此函数进行冲洗显示 
  66.                 putchar('\n'); 
  67.                  
  68. //回复客户端,并对回复的内容进行处理                
  69.                 client_id = str_handler(buf); 
  70.                  
  71.                 //处理回复内容字符串 
  72.                 char str[100] = "receided successfully:"; 
  73.                 strcat(str,itoa(client_id)); 
  74.                 int len = strlen(str); 
  75.                 char str_reply[len+1]; 
  76.                 strcpy(str_reply, str); 
  77.                  
  78.                 //处理客户端路径 
  79.                 char tmp[100]= "../"; 
  80.                 strcat(tmp,itoa(client_id)); 
  81.                 len = strlen(tmp); 
  82.                 char path[len+1]; 
  83.                 strcpy(path,tmp); 
  84.             
  85.                 //打开对应客户端的管道进行写操作 
  86.                 int cfd = open(path,O_WRONLY, S_IWUSR|S_IWGRP); 
  87.                 if(cfd<0
  88.                 { 
  89.                         perror("open_1\n"); 
  90.                         exit(1);                
  91.                 } 
  92.                 //回复对应的客户端             
  93.                 if(write(cfd, str_reply, (strlen(str_reply)+1) ) == -1) 
  94.                 { 
  95.                         perror("write\n"); 
  96.                         exit(1);                
  97.                 } 
  98.                 //写完后关闭对应的管道 
  99.                 if(close(cfd)) 
  100.                 { 
  101.                         perror("close\n"); 
  102.                         exit(1);                   
  103.                 } 
  104.                 sleep(1); 
  105.         } 
  106.       if(close(fd)) 
  107.       { 
  108.             perror("close\n"); 
  109.             exit(1);                   
  110.       }        
  111.         
  112.         return 0; 
  113.  
  114.  
  115. pid_t str_handler(char*buf) 
  116.         pid_t tmp;  
  117.         int len = strlen(buf); 
  118.          
  119.         tmp = atoi(buf); 
  120.         printf("len :%d tmp:%d,buf:%s\n",len,tmp,buf); 
  121.         if( (tmp == 0) || (tmp < 0) ) 
  122.         { 
  123.                 return -1; 
  124.         } 
  125.         return tmp; 
  126.  
  127. static char* itoa(int i) 
  128.       char * local =  (char*) malloc(10); 
  129.       memset(local,10,0); 
  130.       sprintf(local,"%d",i); 
  131.       return local; 
  132.  
  133.  
  134.  
  135. void del_fifo(void) 
  136.       if(remove("../share_fifo")) 
  137.       { 
  138.             perror("remove\n"); 
  139.             exit(1);     
  140.       } 


client.c

  
  
  
  
  1. #include <unistd.h> 
  2. #include <stdio.h> 
  3. #include <string.h> 
  4. #include <stdlib.h> 
  5. #include <sys/types.h> 
  6. #include <sys/stat.h> 
  7. #include <fcntl.h> 
  8.  
  9. #define MAXLINE 100 
  10. char buf[MAXLINE]; 
  11.  
  12. char tmp[100]= "../"; 
  13. char* path; 
  14.  
  15. static char* itoa(int i) 
  16.       char * local =  (char*) malloc(10); 
  17.       memset(local,10,0); 
  18.       sprintf(local,"%d",i); 
  19.       return local; 
  20.  
  21. void del_fifo(void) 
  22.       if(remove(path)) 
  23.       { 
  24.             perror("remove\n"); 
  25.             exit(1);     
  26.       } 
  27.  
  28.  
  29. int main(int argc, char** argv) 
  30.       int fd0 , fd1; 
  31.        
  32.       int len; 
  33.             
  34.       strcat(tmp,itoa(getpid())); 
  35.       len = strlen(tmp); 
  36.       char tmp_path[len+1]; 
  37.       strcpy(tmp_path,tmp); 
  38.       path = tmp_path
  39.             
  40.       if(0 != mkfifo(path, 0777 )) 
  41.       { 
  42.             perror("mkfifo\n"); 
  43.             exit(1); 
  44.       }   
  45.        
  46.  #if 0         
  47.       fd0 = open("../client0", O_RDONLY, S_IRUSR|S_IRGRP); 
  48.       if(fd0<0
  49.       { 
  50.             perror("open_0\n"); 
  51.             exit(1);                
  52.       }       
  53. #endif        
  54.     //处理回复内容字符串 
  55.     
  56.     char str[10]; 
  57.     memset(str,10,0); 
  58.     strcpy(str,itoa(getpid())); 
  59.     len = strlen(str); 
  60.     char str_send[len+1]; 
  61.     strcpy(str_send, str); 
  62.     printf("%s\n",str_send); 
  63.      
  64.        fd1 = open("../share_fifo", O_WRONLY, S_IWUSR|S_IWGRP); 
  65.       if(fd1<0
  66.       { 
  67.             perror("open_1\n"); 
  68.             exit(1);                
  69.       } 
  70.  
  71.       fd0 = open(path, O_RDONLY|O_NONBLOCK, S_IRUSR|S_IRGRP); 
  72.       if(fd0<0
  73.       { 
  74.             perror("open_0\n"); 
  75.             exit(1);                
  76.       } 
  77.              
  78.     int count = 10
  79.       while(count--) 
  80.       { 
  81.  
  82.             if(write(fd1, str_send, (strlen(str_send)+1) ) == -1) 
  83.             //if(write(fd1, "test\n", 5 ) == -1) 
  84.             { 
  85.                   perror("write\n"); 
  86.                   exit(1);                
  87.             } 
  88.             fputs("write complete\n",stdout);   
  89.           #if 0   
  90.             if(close(fd1)) 
  91.             { 
  92.                   perror("close\n"); 
  93.                   exit(1);                   
  94.             }   
  95.           #endif   
  96.             while(read(fd0, buf, MAXLINE)<=0); 
  97.             printf("%s\n",buf);  
  98.             sleep(1);   
  99.              
  100.       } 
  101.       return 0; 

 

你可能感兴趣的:(有名管道)