创建与释放
//backlog需要查询平台说明,在linux2.2以后 backlog就变成了已完成连接但未accept的队列的最大值(原来是处于syn状态的,现在换成sysctl 控制的参数tcp_max_syn_backlog)
 
 
struct evconnlistener *evconnlistener_new(struct event_base *base,
    evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,

    evutil_socket_t fd);
 
//evconnlistener_new_bind 可以分配和bind socket fd

struct evconnlistener *evconnlistener_new_bind(struct event_base *base,
    evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,
    const struct sockaddr *sa, int socklen);
void evconnlistener_free(struct evconnlistener *lev);

 
 
flags:
LEV_OPT_LEAVE_SOCKETS_BLOCKING

By default, when the connection listener accepts a new incoming socket, it sets it up to be nonblocking so that you can use it with the rest of Libevent. Set this flag if you do not want this behavior.

LEV_OPT_CLOSE_ON_FREE

If this option is set, the connection listener closes its underlying socket when you free it.

LEV_OPT_CLOSE_ON_EXEC

If this option is set, the connection listener sets the close-on-exec flag on the underlying listener socket. See your platform documentation for fcntl and FD_CLOEXEC for more information.

LEV_OPT_REUSEABLE

By default on some platforms, once a listener socket is closed, no other socket can bind to the same port until a while has passed. Setting this option makes Libevent mark the socket as reusable, so that once it is closed, another socket can be opened to listen on the same port.

LEV_OPT_THREADSAFE

Allocate locks for the listener, so that it’s safe to use it from multiple threads. New in Libevent 2.0.8-rc.

LEV_OPT_DISABLED

Initialize the listener to be disabled, not enabled. You can turn it on manually with evconnlistener_enable(). New in Libevent 2.1.1-alpha.

LEV_OPT_DEFERRED_ACCEPT
If possible, tell the kernel to not announce sockets as having been accepted until some data has been received on them, and they are ready for reading. Do not use this option if your protocol doesn’t start out with the client transmitting data, since in that case this option will sometimes cause the kernel to never tell you about the connection. Not all operating systems support this option: on ones that don’t, this option has no effect. New in Libevent 2.1.1-alpha.
 
 
//设置接收连接的回调函数
 
typedef void (*evconnlistener_cb)(struct evconnlistener *listener,
    evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr);
 
void evconnlistener_set_cb(struct evconnlistener *lev,
    evconnlistener_cb cb, void *arg);
 
//开关控制
int evconnlistener_disable(struct evconnlistener *lev);
int evconnlistener_enable(struct evconnlistener *lev);
 
 
//错误诊断
typedef void (*evconnlistener_errorcb)(struct evconnlistener *lis, void *ptr);
void evconnlistener_set_error_cb(struct evconnlistener *lev,
    evconnlistener_errorcb errorcb);
 
//其他
evutil_socket_t evconnlistener_get_fd(struct evconnlistener *lev);
struct event_base *evconnlistener_get_base(struct evconnlistener *lev);
 
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>

#include <arpa/inet.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

static void
echo_read_cb(struct bufferevent *bev, void *ctx)
{
        /* This callback is invoked when there is data to read on bev. */
        struct evbuffer *input = bufferevent_get_input(bev);
        struct evbuffer *output = bufferevent_get_output(bev);

        /* Copy all the data from the input buffer to the output buffer. */
        evbuffer_add_buffer(output, input);
}

static void
echo_event_cb(struct bufferevent *bev, short events, void *ctx)
{
        if (events & BEV_EVENT_ERROR)
                perror("Error from bufferevent");
        if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
                bufferevent_free(bev);
        }
}

static void
accept_conn_cb(struct evconnlistener *listener,
    evutil_socket_t fd, struct sockaddr *address, int socklen,
    void *ctx)
{
        /* We got a new connection! Set up a bufferevent for it. */
        struct event_base *base = evconnlistener_get_base(listener);
        struct bufferevent *bev = bufferevent_socket_new(
                base, fd, BEV_OPT_CLOSE_ON_FREE);

bufferevent_setcb(bev, echo_read_cb, NULL, echo_event_cb, NULL);

bufferevent_enable(bev, EV_READ|EV_WRITE);
}

static void
accept_error_cb(struct evconnlistener *listener, void *ctx)
{
        struct event_base *base = evconnlistener_get_base(listener);
        int err = EVUTIL_SOCKET_ERROR();
        fprintf(stderr, "Got an error %d (%s) on the listener. "
                "Shutting down.\n", err, evutil_socket_error_to_string(err));

event_base_loopexit(base, NULL);
}

int
main(int argc, char **argv)
{
        struct event_base *base;
        struct evconnlistener *listener;
        struct sockaddr_in sin;

int port = 9876;

if (argc > 1) {
                port = atoi(argv[1]);
        }
        if (port<=0 || port>65535) {
                puts("Invalid port");
                return 1;
        }

base = event_base_new();
        if (!base) {
                puts("Couldn't open event base");
                return 1;
        }

        /* Clear the sockaddr before using it, in case there are extra         * platform-specific fields that can mess us up. */
        memset(&sin, 0, sizeof(sin));
        /* This is an INET address */
        sin.sin_family = AF_INET;
        /* Listen on 0.0.0.0 */
        sin.sin_addr.s_addr = htonl(0);
        /* Listen on the given port. */
        sin.sin_port = htons(port);

listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
            LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
            (struct sockaddr*)&sin, sizeof(sin));
        if (!listener) {
                perror("Couldn't create listener");
                return 1;
        }
        evconnlistener_set_error_cb(listener, accept_error_cb);

event_base_dispatch(base);
        return 0;
}

 
 
 

最新文章

  1. Delete Exists
  2. mysql 允许远程访问
  3. VS与ultraedit 正则表达式替换
  4. 【ASP.NET基础】简单企业产品展示网站--产品编辑CRUD
  5. 【转】 (C#)利用Aspose.Cells组件导入导出excel文件
  6. java.sql.SQLException: Before start of result set
  7. Lost connection to MySQL server at ‘reading initial communication packet&#39;, system error: 0 mysql远程连接问题
  8. poj3693 Maximum repetition substring
  9. discuz!NT 常用操作
  10. jenkins+svn+gradle自动化部署笔记
  11. MVC源码解析 - 进入CLR
  12. 混合式app ionic2.x 手动搭建开发环境教程分享(nodejs,jdk,ant,androidsdk)
  13. 通过s3cmd上传css文件到s3导致样式加载失败
  14. Caused by: javax.persistence.NonUniqueResultException: result returns more than one elements
  15. Linux并发与同步专题 (1)原子操作和内存屏障
  16. C#理解AutoResetEvent和ManualResetEvent
  17. JVM性能参数优化
  18. Winform 设置控件值
  19. php中的static静态变量
  20. 获取本机ip的shell脚本

热门文章

  1. Perl 修改文件内容
  2. ResNet 残差网络训练数据
  3. shiro简单入门介绍
  4. 给已安装的NGINX添加新的模块
  5. mysql使用Navicat 导出和导入数据库
  6. HTML5视频播放插件 video.js介绍
  7. 系统优化怎么做-Linux系统配置优化
  8. GoldenGate -- OGG EXTRACT进程 OGG-00446 报错
  9. 【js】中的小技巧
  10. E. K Balanced Teams