2014-06-25 15 views
1

我正在看012B上的LibEvent示例 - 爲什麼在那個示例中evutil_make_socket_nonblocking(使得套接字非阻塞)函數被調用兩次?libevent:爲什麼evutil_make_socket_nonblocking在他們的例子中調用了兩次

她是代碼(我已經簡單地從LIBEVENT頁複印):

/* For sockaddr_in */ 
#include <netinet/in.h> 
/* For socket functions */ 
#include <sys/socket.h> 
/* For fcntl */ 
#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 

void do_read(evutil_socket_t fd, short events, void *arg); 
void do_write(evutil_socket_t fd, short events, void *arg); 

char 
rot13_char(char c) 
{ 
    /* We don't want to use isalpha here; setting the locale would change 
    * which characters are considered alphabetical. */ 
    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; 
} 

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))) { 
     for (i = 0; i < n; ++i) 
      line[i] = rot13_char(line[i]); 
     evbuffer_add(output, line, n); 
     evbuffer_add(output, "\n", 1); 
     free(line); 
    } 

    if (evbuffer_get_length(input) >= MAX_LINE) { 
     /* Too long; just process what there is and go on so that the buffer 
     * doesn't grow infinitely long. */ 
     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, "\n", 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); 
} 

void 
do_accept(evutil_socket_t listener, short event, void *arg) 
{ 
    struct event_base *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 
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; /*XXXerr*/ 

    sin.sin_family = AF_INET; 
    sin.sin_addr.s_addr = 0; 
    sin.sin_port = htons(40713); 

    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); 
    /*XXX check it */ 
    event_add(listener_event, NULL); 

    event_base_dispatch(base); 
} 

int 
main(int c, char **v) 
{ 
    setvbuf(stdout, NULL, _IONBF, 0); 

    run(); 
    return 0; 
} 

回答

2

這對於監聽套接字調用一次,並且每一次每接受的套接字。

相關問題