zoukankan      html  css  js  c++  java
  • Libevent例子(二)

    服务端

    #include<netinet/in.h>
    #include<stdio.h>
    #include<string.h>
    #include<event.h>
    #include<event2/listener.h>
    #include<event2/bufferevent.h>
    #include<event2/thread.h>
    
    
    void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sock, int socklen, void *arg);
    void socket_read_cb(struct bufferevent *bev, void *arg);
    void socket_event_cb(struct bufferevent *bev, short events, void *arg);
    
    int main() {
        //evthread_use_pthreads();//enable threads
        struct sockaddr_in sin;
        memset(&sin, 0, sizeof(struct sockaddr_in));
        sin.sin_family = AF_INET;
        sin.sin_port = htons(18001);
    
        struct event_base *base = event_base_new();
        struct evconnlistener *listener = evconnlistener_new_bind(
                base, listener_cb, base, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, 10, (struct sockaddr *) &sin, sizeof(struct sockaddr_in));
        event_base_dispatch(base);
        evconnlistener_free(listener);
        event_base_free(base);
        return 0;
    }
    
    //一个新客户端连接上服务器了
    //当此函数被调用时,libevent已经帮我们accept了这个客户端。该客户端的
    //文件描述符为fd
    void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sock, int socklen, void *arg) {
        printf("accept a client %d
    ", fd);
        struct event_base *base = (struct event_base *) arg;
        //为这个客户端分配一个bufferevent
        struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
        bufferevent_setcb(bev, socket_read_cb, NULL, socket_event_cb, NULL);
        bufferevent_enable(bev, EV_READ | EV_PERSIST);
    }
    
    void socket_read_cb(struct bufferevent *bev, void *arg) {
        char msg[4096];
        size_t len = bufferevent_read(bev, msg, sizeof(msg) - 1);
        msg[len] = '';
        printf("server read the data %s
    ", msg);
        char reply[] = "I has read your data";
        bufferevent_write(bev, reply, strlen(reply));
    }
    
    void socket_event_cb(struct bufferevent *bev, short events, void *arg) {
        if (events & BEV_EVENT_EOF) {
            printf("connection closed
    ");
        } else if (events & BEV_EVENT_ERROR) {
            printf("some other error
    ");
        }
        //这将自动close套接字和free读写缓冲区
        bufferevent_free(bev);
    }

    客户端

    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<event.h>
    #include<event2/bufferevent.h>
    #include<event2/buffer.h>
    #include<event2/util.h>
    
    
    int tcp_connect_server(const char *server_ip, int port);
    void cmd_msg_cb(int fd, short events, void *arg);
    void server_msg_cb(struct bufferevent *bev, void *arg);
    void event_cb(struct bufferevent *bev, short event, void *arg);
    
    int main(int argc, char **argv) {
        if (argc < 3) {
            //两个参数依次是服务器端的IP地址、端口号
            printf("please input 2 parameter
    ");
            return -1;
        }
        struct event_base *base = event_base_new();
        struct bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
    
        //监听终端输入事件
        struct event *ev_cmd = event_new(
                base, STDIN_FILENO, EV_READ | EV_PERSIST, cmd_msg_cb, (void *) bev);
    
        event_add(ev_cmd, NULL);
    
        struct sockaddr_in server_addr;
        memset(&server_addr, 0, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1], &server_addr.sin_addr);
        bufferevent_socket_connect(
                bev, (struct sockaddr *) &server_addr, sizeof(server_addr));
        bufferevent_setcb(bev, server_msg_cb, NULL, event_cb, (void *) ev_cmd);
        bufferevent_enable(bev, EV_READ | EV_PERSIST);
        event_base_dispatch(base);
        printf("finished 
    ");
        return 0;
    }
    
    void cmd_msg_cb(int fd, short events, void *arg) {
        char msg[1024];
        int ret = read(fd, msg, sizeof(msg));
        if (ret < 0) {
            perror("read fail ");
            exit(1);
        }
        struct bufferevent *bev = (struct bufferevent *) arg;
        //把终端的消息发送给服务器端
        bufferevent_write(bev, msg, ret);
    }
    
    void server_msg_cb(struct bufferevent *bev, void *arg) {
        char msg[1024];
        size_t len = bufferevent_read(bev, msg, sizeof(msg));
        msg[len] = '';
        printf("recv %s from server
    ", msg);
    }
    
    void event_cb(struct bufferevent *bev, short event, void *arg) {
        if (event & BEV_EVENT_EOF) {
            printf("connection closed
    ");
        } else if (event & BEV_EVENT_ERROR) {
            printf("some other error
    ");
        } else if (event & BEV_EVENT_CONNECTED) {
            printf("the client has connected to server
    ");
            return;
        }
        //这将自动close套接字和free读写缓冲区
        bufferevent_free(bev);
        struct event *ev = (struct event *) arg;
        event_free(ev);
    }
  • 相关阅读:
    MKMapVIew学习系列2 在地图上绘制出你运行的轨迹
    WPF SDK研究 Intro(6) WordGame1
    WPF SDK研究 Intro(3) QuickStart3
    WPF SDK研究 Layout(1) Grid
    WPF SDK研究 目录 前言
    WPF SDK研究 Intro(7) WordGame2
    WPF SDK研究 Layout(2) GridComplex
    对vs2005创建的WPF模板分析
    WPF SDK研究 Intro(4) QuickStart4
    《Programming WPF》翻译 第6章 资源
  • 原文地址:https://www.cnblogs.com/milton/p/7848360.html
Copyright © 2011-2022 走看看