• libevent::bufferevent


    #include <cstdio>
    #include <netinet/in.h>  
    #include <sys/socket.h>   
    #include <fcntl.h> 
    #include <event2/event.h>  
    #include <event2/buffer.h> 
    #include <event2/bufferevent.h>
    #include <assert.h>  
    #include <unistd.h>  
    #include <string.h>   
    #include <stdlib.h> 
    #include <stdio.h>   
    #include <errno.h>  
    
    #define MAX_LINE 16384
    
    struct fd_state
    {
        char buffer[MAX_LINE];
        size_t buffer_used;
        size_t n_written;
        size_t write_upto;
        struct event*read_event;
        struct event*write_event;
    };
    
    void run(void);
    void do_accept(evutil_socket_t listener, short event, void*arg);
    void readcb(struct bufferevent* bev, void * ctx);
    void errorcb(struct bufferevent* bev, short error, void * ctx);
    
    char rot13_char(char c)
    {
        if ((c >= 'a'  &&  c <= 'm ') || (c >= 'A ' && c <= 'M '))
            return c + 13;
        else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z'))
            return c - 13;
        else
            return c;
    }
    
    int main(int c, char**v)
    {
        run();
        return 0;
    }
    
    void run(void)
    {
        evutil_socket_t listener;
        struct sockaddr_in sin;
        struct event_base*base;
        struct event*listener_event;
        base = event_base_new();
        if (!base)
            return;
    
        sin.sin_family = AF_INET; sin.sin_addr.s_addr = 0;
        sin.sin_port = htons(9090);
        listener = socket(AF_INET, SOCK_STREAM, 0);
        evutil_make_socket_nonblocking(listener);
        /*#ifndef WIN32
            {
                int one = 1;
                setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
            }
        #endif    */
        if (bind(listener, (struct sockaddr*) &sin, sizeof(sin)) < 0)
        {
            perror("bind"); return;
        }
        if (listen(listener, 16) < 0)
        {
            perror("listen");
            return;
        }
        listener_event = event_new(base, listener, EV_READ | EV_PERSIST, do_accept, (void*)base);
    
        event_add(listener_event, NULL);
        event_base_dispatch(base);
    }
    
    void do_accept(evutil_socket_t listener, short event, void*arg)
    {
        struct event_base*base = (event_base*)(arg);
        struct sockaddr_storage ss;
        socklen_t slen = sizeof(ss);
        int fd = accept(listener, (struct sockaddr*) &ss, &slen);
        if (fd < 0)
        {
            perror("accept");
        }
        else if (fd > FD_SETSIZE)
        {
            close(fd);
        }
        else
        {
            struct bufferevent* bev;
            evutil_make_socket_nonblocking(fd);
            bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
            bufferevent_setcb(bev, readcb, NULL, errorcb, NULL);
            bufferevent_setwatermark(bev, EV_READ, 0, MAX_LINE);
            bufferevent_enable(bev, EV_READ | EV_WRITE);
        }
    }
    void readcb(struct bufferevent* bev, void * ctx)
    {
        struct evbuffer* input, *output;
        char* line;
        size_t n;
        int i;
        input = bufferevent_get_input(bev);
        output = bufferevent_get_output(bev);
        while ((line = evbuffer_readln(input, &n, EVBUFFER_EOL_LF)))
        {
            printf("str = %s 
    ", line);
    
            for (i = 0; i < n; ++i)
                line[i] = rot13_char(line[i]);
    
            evbuffer_add(output, line, n);
            evbuffer_add(output, "
    ", 1);
            free(line);
        }
    
        if (evbuffer_get_length(input) >= MAX_LINE)
        {
            char buf[1024];
            while (evbuffer_get_length(input))
            {
                int n = evbuffer_remove(input, buf, sizeof(buf));
                for (i = 0; i < n; ++i)
                    buf[i] = rot13_char(buf[i]);
    
                evbuffer_add(output, buf, n);
            }
            evbuffer_add(output, "
    ", 1);
        }
    }
    void errorcb(struct bufferevent* bev, short error, void * ctx)
    {
        if (error & BEV_EVENT_EOF)
        {
            /* connection has been closed, do any clean up here*/
        }
        else if (error & BEV_EVENT_ERROR)
        {
            /* check errno to see what error occurred*/
        }
        else if (error & BEV_EVENT_TIMEOUT)
        {
            /* must be a timeout event handle, handle it*/
        }
        bufferevent_free(bev);
    }
  • 相关阅读:
    Adobe Acrobat XI Pro破解版 v11.0.10中文版
    linux经典面试题
    P1540 机器翻译(STL 链表)
    P1067 多项式输出 (模拟)
    P1003 铺地毯
    [CF547C] Mike and Foam
    [CF351B] Jeff and Furik
    [CF900D] Unusual Sequences
    [CF568B] Symmetric and Transitive
    [CF893E] Counting Arrays
  • 原文地址:https://www.cnblogs.com/osbreak/p/10280172.html
Copyright © 2020-2023  润新知