zoukankan      html  css  js  c++  java
  • epoll实现压测工具

    代码:

      1 /*
      2  * g++ -o stress_test ./stress_test.cpp
      3  */
      4 
      5 #include <stdlib.h>
      6 #include <stdio.h>
      7 #include <string.h>
      8 #include <errno.h>
      9 
     10 #include <unistd.h>
     11 #include <sys/types.h>
     12 #include <sys/epoll.h>
     13 #include <fcntl.h>
     14 #include <sys/socket.h>
     15 #include <netinet/in.h>
     16 #include <arpa/inet.h>
     17 
     18 static const char *request = "GET / HTTP/1.1
    Host: 192.168.1.5
    Connection: keep-alive
    
    ";
     19 
     20 int setnonblocking(int fd)
     21 {
     22     int old_option = fcntl(fd, F_GETFL);
     23     int new_option = old_option | O_NONBLOCK;
     24     fcntl(fd, F_SETFL, new_option);
     25     
     26     return old_option;
     27 }
     28 
     29 int add_fd(int epoll_fd, int fd)
     30 {
     31     struct epoll_event event;
     32     event.events = EPOLLOUT | EPOLLET | EPOLLERR;
     33     event.data.fd = fd;
     34     epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event);
     35     setnonblocking(fd);
     36 }
     37 
     38 bool write_nbytes(int sockfd, const char *buffer, int len)
     39 {
     40     int bytes_write = 0;
     41     printf("write out %d bytes to socket %d
    ", len, sockfd);
     42     while(1)
     43     {
     44         bytes_write = send(sockfd, buffer, len, 0);
     45         if (bytes_write == -1)
     46         {
     47             printf("send failed, errno[%d], error[%s]
    ", errno, strerror(errno));
     48             return false;
     49         }
     50         else if (bytes_write == 0)
     51         {
     52             printf("send 0 bytes
    ");
     53             return false;
     54         }
     55 
     56         len -= bytes_write;
     57         buffer = buffer + bytes_write;
     58         if (len <= 0)
     59         {
     60             return true;
     61         }
     62     }
     63 }
     64 
     65 bool read_once(int sockfd, char *buffer, int len)
     66 {
     67     int bytes_read = 0;
     68     memset(buffer, '', len);
     69     bytes_read = recv(sockfd, buffer, len, 0);
     70     if (bytes_read == -1)
     71     {
     72         printf("recv failed, errno[%d], error[%s]
    ", errno, strerror(errno));
     73         return false;
     74     }
     75     else if (bytes_read == 0)
     76     {
     77         printf("recv 0 bytes
    ");
     78         return false;
     79     }
     80     printf("read in %d bytes from socket %d
    ", bytes_read, sockfd);
     81 
     82     return true;
     83 }
     84 
     85 int start_conn(int epoll_fd, const char *ip, int port, int num)
     86 {
     87     struct sockaddr_in addr;
     88     bzero(&addr, sizeof(addr));
     89     addr.sin_family = AF_INET;
     90     addr.sin_addr.s_addr = inet_addr(ip);
     91     addr.sin_port = htons(port);
     92 
     93     socklen_t len = sizeof(addr);
     94     for (int i = 0; i < num; ++i)
     95     {
     96         sleep(1);
     97         int fd = socket(AF_INET, SOCK_STREAM, 0);
     98         if (fd == -1)
     99         {
    100             printf("socket failed, errno[%d], error[%s]
    ", errno, strerror(errno));
    101             continue;
    102         }
    103 
    104         if (connect(fd, (struct sockaddr*)&addr, len) == 0)
    105         {
    106             printf("build connection %d
    ", i);
    107             add_fd(epoll_fd, fd);
    108         }
    109         else
    110         {
    111             printf("connect failed, errno[%d], error[%s]
    ", errno, strerror(errno));
    112             continue;
    113         }
    114     }
    115 }
    116 
    117 int close_conn(int epoll_fd, int fd)
    118 {
    119     epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
    120 
    121     printf("close socket[%d]
    ", fd);
    122     close(fd);
    123 }
    124 
    125 int main(int argc, char **argv)
    126 {
    127     if (argc != 4)
    128     {
    129         printf("usage:stress_test ip port num
    ");
    130         exit(-1);
    131     }
    132 
    133     int epoll_fd = epoll_create(10000);
    134     start_conn(epoll_fd, argv[1], atoi(argv[2]), atoi(argv[3]));
    135     epoll_event events[10000];
    136     char buffer[2048];
    137     while (1)
    138     {
    139         int fds = epoll_wait(epoll_fd, events, 10000, 2000);
    140         for (int i = 0; i < fds; ++i)
    141         {
    142             int sockfd = events[i].data.fd;
    143             if (events[i].events & EPOLLIN)
    144             {
    145                 if (!read_once(sockfd, buffer, 2048))
    146                 {
    147                     close_conn(epoll_fd, sockfd);
    148                 }
    149 
    150                 struct epoll_event event;
    151                 event.events = EPOLLOUT | EPOLLET | EPOLLERR;
    152                 event.data.fd = sockfd;
    153                 epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sockfd, &event);
    154             }
    155             else if (events[i].events & EPOLLOUT)
    156             {
    157                 if (!write_nbytes(sockfd, request, strlen(request)))
    158                 {
    159                     close_conn(epoll_fd, sockfd);
    160                 }
    161 
    162                 struct epoll_event event;
    163                 event.events = EPOLLIN | EPOLLET | EPOLLERR;
    164                 event.data.fd = sockfd;
    165                 epoll_ctl(epoll_fd, EPOLL_CTL_MOD, sockfd, &event);
    166             }
    167             else if (events[i].events & EPOLLERR)
    168             {
    169                 close_conn(epoll_fd, sockfd);
    170             }
    171         }
    172     }
    173 
    174     return 0;
    175 }
  • 相关阅读:
    scws安装
    Redis使用
    安装redis服务
    mkdir(): Permission denied
    Zabbix告警脚本-邮件
    Zabbix告警脚本-微信
    Zabbix实现微信告警
    Docker学习之安装mysql
    docker安装使用
    centos6与centos7区别
  • 原文地址:https://www.cnblogs.com/lit10050528/p/5808289.html
Copyright © 2011-2022 走看看