• epoll实现linux进程通信


    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
    ");
     17   //unlink(UNIX_DOMAIN);
     18   remove(UNIX_DOMAIN);
     19   printf("clean end.
    ");
     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
    ");
     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
    ");
    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
    ");
    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] = '';
    132           printf("%s",line);
    133           while( ( ret = read(eventfd,line,256)) >0)
    134           {
    135                 line[ret] = '';
    136                 printf("%s",line);
    137           }
    138           printf("
    ");
    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
    ", rcv_num, rcv_buf);
    39 
    40   memset(snd_buf, 0, 256);
    41   strcpy(snd_buf, "message from client");
    42   printf("sizeof(snd_buf): %d
    ", sizeof(snd_buf));
    43 
    44   printf("send data to server... ...
    ");
    45   for(i = 0; i < 4; i++)
    46   {
    47     write(connect_fd, snd_buf, sizeof(snd_buf));
    48   }
    49   printf("send end!
    ");
    50   close(connect_fd);
    51   return 0;
    52 
    53 }

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

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

  • 相关阅读:
    A题
    CTF--web BugKu-ctf-web(1-10)
    CTF--web 攻防世界web题 robots backup
    CTF--web 攻防世界web题 get_post
    BUUCTF-Crypyo-No.1
    攻防世界-新手篇(Mise)~~~
    BJDCTF-2020-WRITEUP---TiKi小组
    TKCTF-学校内部的校赛
    BUUCTF-BJD(更新V1.0)
    线程池(1)-参数
  • 原文地址:https://www.cnblogs.com/xuxu8511/p/3217444.html
Copyright © 2020-2023  润新知