zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    LeetCode 258 Add Digits
    LeetCode 231 Power of Two
    LeetCode 28 Implement strStr()
    LeetCode 26 Remove Duplicates from Sorted Array
    LeetCode 21 Merge Two Sorted Lists
    LeetCode 20 Valid Parentheses
    图形处理函数库 ImageTTFBBox
    php一些函数
    func_get_arg(),func_get_args()和func_num_args()的用法
    人生不是故事,人生是世故,摸爬滚打才不会辜负功名尘土
  • 原文地址:https://www.cnblogs.com/xiaohexiansheng/p/5907474.html
Copyright © 2011-2022 走看看