现在的位置: 首页 > 操作系统 > 正文

epoll实现linux进程通信

2019年08月12日 操作系统 ⁄ 共 4004字 ⁄ 字号 评论关闭

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           else
123             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用于本机上的进程之间的通信。

抱歉!评论已关闭.