zoukankan      html  css  js  c++  java
  • Linux 初识Libevent网络库

    初识Libevent

    libevent是用c写的高并发网络io库,只要有文件描述符,就都可使用libevent。

    libevent使用回调函数(callback) 。

    有了libevent,网络编程我有

    1, FIFO的进程间通信。

    利用FIFO的进程间通信read端:

    #include <event2/event.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #define MYFIFO "myfifo"
    
    //call back
    void readcb(evutil_socket_t fd, short what, void* arg){
      //read fifo
      char buf[24] = {0};
      int len = read(fd, buf, sizeof(buf));
      buf[len] = '';
      printf("data len = %d, buf = %s
    ", len, buf);
      printf("read event:%s
    ", what & EV_READ ? "Yes" : "No");
    }
    
    int main(){
      unlink(MYFIFO);
      mkfifo(MYFIFO, 0664);
    
      int fd = open(MYFIFO, O_RDONLY | O_NONBLOCK);
      //int fd = open(MYFIFO, O_RDONLY);
    
      struct event_base* base;
      base = event_base_new();
    
      //create event
      struct event* ev = NULL;
      ev = event_new(base, fd, EV_READ | EV_PERSIST | EV_ET, readcb, NULL);
    
      //add event
      event_add(ev, NULL);
    
      //start
      event_base_dispatch(base);
    
      //free event
      event_free(ev);
      event_base_free(base);
      close(fd);
    
      return 0;
    }
    
    

    利用FIFO的进程间通信write端:

    #include <event2/event.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    
    #define MYFIFO "myfifo"
    
    //call back
    void writecb(evutil_socket_t fd, short what, void* arg){
      //write fifo
      char buf[24] = {0};
      static int num = 0;
      sprintf(buf, "num = %d", num++);
      write(fd, buf, strlen(buf) + 1);
    }
    
    int main(){
    
      int fd = open(MYFIFO, O_WRONLY | O_NONBLOCK);
    
      struct event_base* base;
      base = event_base_new();
    
      //create event
      struct event* ev = NULL;
      ev = event_new(base, fd, EV_WRITE | EV_PERSIST | EV_ET, writecb, NULL);
    
      //add event
      event_add(ev, NULL);
    
      //start
      event_base_dispatch(base);
    
      //free event
      event_free(ev);
      event_base_free(base);
      close(fd);
    
      return 0;
    }
    
    
    

    2, socket通信。

    server端:

    #include <event2/event.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <event2/bufferevent.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <event2/listener.h>
    
    //write callback
    void write_cb(struct bufferevent* bev, void* ctx){
      printf("all is sent
    ");
    }
    
    //read callback
    void read_cb(struct bufferevent *bev, void *ctx){
      char buf[64];
      size_t ret = bufferevent_read(bev, buf, sizeof(buf));
      buf[ret] = '';
      printf("server recf:%s
    ", buf);
    
      bufferevent_write(bev, "hahaha", 6);
    }
    
    //event callback
    void event_cb(struct bufferevent *bev, short what, void *ctx){
    
      if(what & BEV_EVENT_EOF){
        printf("EOF
    ");
      }
      if(what & BEV_EVENT_CONNECTED){
        printf("connected
    ");
      }
    }
    
    //listener call back
    void listencb(struct evconnlistener* listener, evutil_socket_t fd,
    	      struct sockaddr* cli, int len, void* ptr){
    
      struct event_base* base = evconnlistener_get_base(listener);
      struct bufferevent* bev =
        bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    
      //set callback function
      bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL);
      bufferevent_enable(bev, EV_READ | EV_WRITE);
    
      
      //set water
      bufferevent_setwatermark(bev, EV_READ, 10, 0);
      bufferevent_setwatermark(bev, EV_WRITE, 1, 2);
    
    }
    
    int main(int argc, char** argv){
    
      int port = atoi(argv[1]);
      struct event_base* base;
      base = event_base_new();
      if(!base){
        perror("event_base_new");
        exit(1);
      }
    
      struct sockaddr_in s;
      s.sin_family = AF_INET;
      s.sin_port = htons(port);
      s.sin_addr.s_addr = htonl(INADDR_ANY);
      struct evconnlistener* listener =
        evconnlistener_new_bind(base, listencb, NULL, LEV_OPT_CLOSE_ON_FREE,
    			    -1, (struct sockaddr*)&s, sizeof(s));
      if(!listener){
        perror("bind");
        exit(1);
      }
      event_base_dispatch(base);
      event_base_free(base);
    }
    
    

    client端:

    #include <event2/event.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <event2/bufferevent.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <event2/listener.h>
    #include <event2/dns.h>
    #include <stdlib.h>
    #include <event2/util.h>
    
    //read write callback
    void readcb(struct bufferevent *bev, void *ctx){
      char buf[64];
      size_t ret = bufferevent_read(bev, buf, sizeof(buf));
      buf[ret] = '';
      printf("client recf:%s
    ", buf);
    
    }
    
    //event callback
    void eventcb(struct bufferevent *bev, short what, void *ctx){
      if(what & BEV_EVENT_CONNECTED){
        printf("connect okay
    ");  
      }
      else if(what & BEV_EVENT_ERROR){
        struct event_base* base = ctx;
        int err = bufferevent_socket_get_dns_error(bev);
        if(err){
          printf("DNS error:%s
    ", evutil_gai_strerror(err));
        }
        printf("closing
    ");
        bufferevent_free(bev);
        event_base_loopexit(base, NULL);
      }
    }
    
    //terminal read callback
    void termicb(evutil_socket_t fd, short what, void* ptr){
      char buf[64] = {0};
      int len = read(fd, buf, sizeof(buf));
      buf[len] = '';
      printf("in termicb
    ");
      struct bufferevent* bev = ptr;
      bufferevent_write(bev, buf, len);
    }
    int main(int artc, char** argv){
    
      struct event_base* base;
      base = event_base_new();
     
      struct evdns_base* dns_base;
      dns_base = evdns_base_new(base, 1);
    
      struct bufferevent* bev;
      bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
    
      int port = atoi(argv[2]);
      bufferevent_setcb(bev, readcb, NULL, eventcb, base);
      bufferevent_enable(bev, EV_READ);
      bufferevent_socket_connect_hostname(bev, dns_base, AF_INET, argv[1], port);
    
      struct event* ev = event_new(base, STDIN_FILENO, EV_READ | EV_PERSIST, termicb, bev);
      event_add(ev, NULL);
      event_base_dispatch(base);
      event_base_free(base);
    }
    
    

    c/c++ 学习互助QQ群:877684253

    本人微信:xiaoshitou5854

  • 相关阅读:
    顺序容器
    forward_list
    array
    第十一章 关联容器
    C++数组
    C++标准库算法
    第十章 泛型算法
    第九章 顺序容器
    操作系统概述
    文件输入输出
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/11139758.html
Copyright © 2011-2022 走看看