epoll实现linux进程通信

From: http://www.cnblogs.com/xuxu8511/p/3217444.html

server.c

  1 #include <stdio.h>  2 #include <stdlib.h>  3 #include <string.h>  4 #include <sys/socket.h>  5 #include <sys/un.h>  6 #include <unistd.h>  7 #include <signal.h>  8 #include <sys/epoll.h>  9 #include <errno.h> 10  11 #define UNIX_DOMAIN "/tmp/UNIX.domain" 12  13  14 void handler(){ 15  16   printf("clean program start\n"); 17   //unlink(UNIX_DOMAIN); 18   remove(UNIX_DOMAIN); 19   printf("clean end.\n"); 20 } 21  22 int main(void) 23 { 24   int lsn_fd, apt_fd; 25   struct sockaddr_un srv_addr; 26   struct sockaddr_un clt_addr; 27   socklen_t clt_len; 28   int ret; 29   int i; 30   char recv_buf[1024]; 31   char send_buf[1024];   32  33   signal(SIGTERM,handler);   34  35   //create epoll  36   int epfd,eventfd; 37   struct epoll_event   ev,events[1024]; 38  39   epfd = epoll_create(1024); 40  41   //create socket to bind local IP and PORT 42   lsn_fd = socket(AF_UNIX, SOCK_STREAM, 0); 43   ev.data.fd = lsn_fd; 44   ev.events = EPOLLIN|EPOLLET; 45  46   epoll_ctl(epfd,EPOLL_CTL_ADD,lsn_fd,&ev); 47  48   if(lsn_fd < 0) 49   { 50     perror("can't create communication socket!"); 51     return 1; 52   } 53  54   //create local IP and PORT 55   srv_addr.sun_family = AF_UNIX; 56   strncpy(srv_addr.sun_path, UNIX_DOMAIN, sizeof(srv_addr.sun_path) - 1); 57   //unlink(UNIX_DOMAIN); 58  59   //bind sockfd and sockaddr 60   ret = bind(lsn_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)); 61   if(ret == -1) 62   { 63     perror("can't bind local sockaddr!"); 64     close(lsn_fd); 65     unlink(UNIX_DOMAIN); 66     return 1; 67   } 68  69   //listen lsn_fd, try listen 5 70  71   ret = listen(lsn_fd, 5); 72   if(ret == -1) 73   { 74     perror("can't listen client connect request"); 75     close(lsn_fd); 76     unlink(UNIX_DOMAIN); 77  78     return 1; 79   } 80  81   clt_len = sizeof(clt_addr); 82   while(1) 83   { 84     int nfds = epoll_wait(epfd,events,1024,100); 85     int i=0; 86     for(i=0;i<nfds;++i) 87     { 88       if(events[i].data.fd == lsn_fd) 89       { 90         apt_fd = accept(lsn_fd, (struct sockaddr*)&clt_addr, &clt_len); 91         if(apt_fd < 0){ 92           perror("can't listen client connect request"); 93           close(lsn_fd); 94           unlink(UNIX_DOMAIN); 95           return 1;  96         } 97         char lines[256]; 98         sprintf(lines,"server data  to client\n"); 99         write(apt_fd, lines, 256);100 101         ev.data.fd = apt_fd;102         ev.events = EPOLLIN|EPOLLET;103 104         epoll_ctl(epfd,EPOLL_CTL_ADD,apt_fd,&ev);105 106       }107       else if (events[i].events & EPOLLIN) 108       //write数据109       {110         printf("EPOLLIN\n");111         if( (eventfd = events[i].data.fd) < 0 )112           continue;113 114         int n=0,ret=0 ;115         char line[256];116         if ((ret = read(eventfd,line,256)) < 0){117 118           if(errno == ECONNRESET){119             close(eventfd);120             events[i].data.fd = -1;121           }122           else123             printf("readline error\n");124         }125         else if( ret == 0){126           close(eventfd);127           events[i].data.fd = -1;128         }129         else if( ret > 0 )130         {131           line[ret] = '\0';132           printf("%s",line);133           while( ( ret = read(eventfd,line,256)) >0)134           {135                 line[ret] = '\0';136                 printf("%s",line);137           }138           printf("\n");139         }140       }141       else if (events[i].events & EPOLLOUT){142         //写出的数据,在EPOLLIN处理中设置fd的events为EPOLLOUT|EPOLLET时,即触发该事件143         int eventfd  = events[i].data.fd;144         char line[256];145         write(eventfd,line,256);146 147         ev.data.fd = eventfd;148         ev.events = EPOLLIN | EPOLLET;149 150         epoll_ctl ( epfd, EPOLL_CTL_ADD, eventfd, &ev);151       }152     }153   }154 155   close(apt_fd);156   close(lsn_fd);157   unlink(UNIX_DOMAIN);158   return 0;159 }

client.c

 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/socket.h> 4 #include <sys/un.h> 5 #include <unistd.h> 6  7 #define UNIX_DOMAIN "/tmp/UNIX.domain" 8  9 int main(void)10 {11   int connect_fd;12   struct sockaddr_un srv_addr;13   char snd_buf[256];14   char rcv_buf[256];15   int ret;16   int i;17   connect_fd = socket(AF_UNIX, SOCK_STREAM, 0);18 19   if(connect_fd < 0)20   {21     perror("client create socket failed");22     return 1;23   }24   srv_addr.sun_family = AF_UNIX;25   strcpy(srv_addr.sun_path, UNIX_DOMAIN);26   ret = connect(connect_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr));27 28   if(ret == -1)29   {30     perror("connect to server failed!");31     close(connect_fd);32     unlink(UNIX_DOMAIN);33     return 1;34   }35 36   memset(rcv_buf, 0, 256);37   int rcv_num = read(connect_fd, rcv_buf, sizeof(rcv_buf));38   printf("receive message from server (%d) :%s\n", rcv_num, rcv_buf);39 40   memset(snd_buf, 0, 256);41   strcpy(snd_buf, "message from client");42   printf("sizeof(snd_buf): %d\n", sizeof(snd_buf));43 44   printf("send data to server... ...\n");45   for(i = 0; i < 4; i++)46   {47     write(connect_fd, snd_buf, sizeof(snd_buf));48   }49   printf("send end!\n");50   close(connect_fd);51   return 0;52 53 }

与网络的socket通信的区别,即socket地址有些区别,其他的一样。

sockaddr_in用于网络的socket通信,sockaddr_un用于本机上的进程之间的通信。

只有这样才不会被“不可能”束缚,才能不断超越自我。

epoll实现linux进程通信

相关文章:

你感兴趣的文章:

标签云: