• libev客户端


      1 #include <ev.h>
      2 #include <stdio.h>
      3 #include <netinet/in.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #define PORT 6666
      8 #define BUFFER_SIZE 2048
      9 #define MAX_ALLOWED_CLIENT 10240
     10 
     11 struct ev_io *libevlist[MAX_ALLOWED_CLIENT] = {NULL};
     12 
     13 void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
     14 
     15 void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
     16 
     17 void timer_beat(struct ev_loop *loop, struct ev_timer *watcher, int revents);
     18 
     19 int freelibev(struct ev_loop *loop, int fd);
     20 
     21 
     22 int main()
     23 {
     24     struct ev_loop *loop=ev_default_loop(0);
     25     int sd;
     26     struct sockaddr_in addr;
     27     int addr_len = sizeof(addr);
     28     
     29     //创建一个io watcher和一个timer watcher
     30     struct ev_io socket_accept;
     31     struct ev_timer timeout_w;
     32     //创建socket连接
     33     sd = socket(PF_INET, SOCK_STREAM, 0);
     34     if(sd < 0)    
     35     {
     36         printf("socket error
    ");
     37         return -1;
     38     }
     39     bzero(&addr, sizeof(addr));
     40     addr.sin_family = AF_INET;
     41     addr.sin_port = htons(PORT);
     42     addr.sin_addr.s_addr = INADDR_ANY;
     43     //正常bind
     44     if(bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0)
     45     {
     46         printf("bind error
    ");
     47         return -1;
     48     }
     49     //正常listen
     50     if(listen(sd, SOMAXCONN) < 0)
     51     {
     52         printf("listen error
    ");
     53         return -1;
     54     }
     55     //设置fd可重用
     56     int bReuseaddr=1;
     57     if(setsockopt(sd,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(bReuseaddr)) != 0)
     58     {
     59         printf("setsockopt error in reuseaddr[%d]
    ", sd);
     60         return ;
     61     }
     62     
     63     //初始化io watcher,用于监听fd
     64     ev_io_init(&socket_accept, read_cb, sd, EV_READ);
     65     ev_io_start(loop, &socket_accept);
     66     
     67     ev_run(loop, 0);
     68     
     69     return 1;
     70 }
     71  
     72 void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
     73 {
     74     
     75     //    如果有链接,则继续监听fd;
     76     
     77     struct sockaddr_in client_addr;
     78     socklen_t client_len = sizeof(client_addr);
     79     int client_sd;
     80     //创建客户端的io watcher
     81     struct ev_io *w_client = (struct ev_io*) malloc(sizeof(struct ev_io));
     82     
     83     if(w_client == NULL)
     84     {
     85         printf("malloc error in accept_cb
    ");
     86         return ;
     87     }
     88     
     89     if(EV_ERROR & revents)
     90     {
     91         printf("error event in accept
    ");
     92         return ;
     93     }
     94     
     95     //获取与客户端相连的fd
     96     client_sd = accept(watcher->fd, (struct sockaddr*)&client_addr, &client_len);
     97     if(client_sd < 0)
     98     {
     99         printf("accept error
    ");
    100         return;
    101     }
    102     //如果连接数超出指定范围,则关闭连接
    103     if( client_sd > MAX_ALLOWED_CLIENT)
    104     {
    105         printf("fd too large[%d]
    ", client_sd);
    106         close(client_sd);
    107         return ;
    108     }
    109     
    110     if(libevlist[client_sd] != NULL)
    111     {
    112         printf("client_sd not NULL fd is [%d]
    ", client_sd);
    113         return ;
    114     }
    115     
    116     printf("client connected
    ");
    117     //监听新的fd
    118     ev_io_init(w_client, read_cb, client_sd, EV_READ);
    119     ev_io_start(loop, w_client);
    120     
    121     libevlist[client_sd] = w_client;
    122 
    123 }
    124 
    125 void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
    126 {
    127     char buffer[BUFFER_SIZE];
    128     ssize_t read;
    129     
    130     if(EV_ERROR & revents)
    131     {
    132         printf("error event in read
    ");
    133         return ;
    134     }
    135     //正常的recv
    136     read = recv(watcher->fd, buffer, BUFFER_SIZE, 0);
    137     if(read < 0)
    138     {
    139         printf("read error
    ");
    140         return;
    141     }
    142     
    143     if(read == 0)
    144     {
    145         printf("client disconnected.
    ");
    146         //ev_io_stop(loop, watcher);
    147         //free(watcher);
    148         //如果客户端断开连接,释放响应的资源,并且关闭监听
    149         freelibev(loop, watcher->fd);
    150         return;
    151     }
    152     else
    153     {
    154         //buffer[read] = '';
    155         printf("receive message:%s
    ", buffer);
    156     }
    157     //返回给客户端
    158     send(watcher->fd, buffer, read, 0);
    159     bzero(buffer, read);
    160 }
    161 
    162 int freelibev(struct ev_loop *loop, int fd)
    163 {
    164     //清理相关资源
    165     
    166     if(libevlist[fd] == NULL)
    167     {
    168         printf("the fd already freed[%d]
    ", fd);
    169         return -1;
    170     }
    171     
    172     close(fd);
    173     ev_io_stop(loop, libevlist[fd]);
    174     free(libevlist[fd]);
    175     libevlist[fd] = NULL;
    176     return 1;
    177 }
  • 相关阅读:
    JS闭包
    css3 背景渐变
    css扩展技术:Less和Sass的区别
    HTML5 Canvas八大核心技术及其API用法
    HTML5新标签含义,用法及其与HTML4的区别
    当离散遇见连续
    素数测试
    概率采样问题
    二分查找及其变种
    C++与Java多态的区别
  • 原文地址:https://www.cnblogs.com/xiaohexiansheng/p/5907474.html
Copyright © 2020-2023  润新知