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);
    }
  • 相关阅读:
    pip安装
    nfs
    源码方式安装软件
    自启动
    multipath
    linux永久添加和删除路由
    iscsi
    linux识别workstation磁盘的uuid
    centos镜像各种cd,dvd版本区别
    转:C# 中 MSCHART 饼状图显示百分比
  • 原文地址:https://www.cnblogs.com/milton/p/7848360.html
Copyright © 2011-2022 走看看