• libevent源码剖析(二)


    struct evconnlistener *
    evconnlistener_new_bind(struct event_base *base, evconnlistener_cb cb,
        void *ptr, unsigned flags, int backlog, const struct sockaddr *sa,
        int socklen)
    {
    /*
    共7个入参:
    @base  --base指针;
    @cb  --监听回调,当监听的事件触发时执行;
    @ptr  --一个空指针类型,这里是将base指针强转后传入;
    @flags  --监听标志(选项),通常会设置地址复用等标志;
    @backlog  --连接队列最大长度,填"-1"默认128;
    @sa  --服务端socket地址;
    @socklen  --地址长度;
    
    
    */
        //1.先准备一个监听器指针
        struct evconnlistener *listener;
    
        /*
        2.创建套接字:
            --设置协议族
            --设置协议名和非阻塞
        */
        evutil_socket_t fd;
        int on = 1;
        int family = sa ? sa->sa_family : AF_UNSPEC;
        int socktype = SOCK_STREAM | EVUTIL_SOCK_NONBLOCK;//TCP,非阻塞
    
        if (backlog == 0)
            return NULL;
        //内部调用exec()前关闭此文件描述符;
        if (flags & LEV_OPT_CLOSE_ON_EXEC)
            socktype |= EVUTIL_SOCK_CLOEXEC;
    
        fd = evutil_socket_(family, socktype, 0);
        if (fd == -1)
            return NULL;
    
        //3.给套接字设置心跳检测
        if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on))<0)
            goto err;
    
        //4.给套接字设置地址复用
        if (flags & LEV_OPT_REUSEABLE) {
            if (evutil_make_listen_socket_reuseable(fd) < 0)
                goto err;
        }
    
        //5.给套接字设置端口复用
        if (flags & LEV_OPT_REUSEABLE_PORT) {
            if (evutil_make_listen_socket_reuseable_port(fd) < 0)
                goto err;
        }
    
        if (flags & LEV_OPT_DEFERRED_ACCEPT) {
            if (evutil_make_tcp_listen_socket_deferred(fd) < 0)
                goto err;
        }
    
        if (flags & LEV_OPT_BIND_IPV6ONLY) {
            if (evutil_make_listen_socket_ipv6only(fd) < 0)
                goto err;
        }
        //6.给套接字绑定地址
        if (sa) {
            if (bind(fd, sa, socklen)<0)
                goto err;
        }
        
        /*7.
            入参:event_base指针、监听回调、event_base的空指针类型、监听队列长度、已初始化的套接字;
            返回:一个可用的“监听器”指针;
        */
        listener = evconnlistener_new(base, cb, ptr, flags, backlog, fd);
        if (!listener)
            goto err;
    
        return listener;
    err:
        evutil_closesocket(fd);
        return NULL;
    }
  • 相关阅读:
    走出软件作坊
    [Flash入门基本动画]第8课
    [Flash入门基本动画]第6课
    数据中心十项节能妙招
    全面实施虚拟化的五个步骤
    Javascript的匿名函数
    TSQL调试器重返SQL Server 2008
    SQL Server 2008(BI)PPT下载
    通过数据中心整合和虚拟化实现高密度服务器配置
    [Flash入门基本动画]第7课
  • 原文地址:https://www.cnblogs.com/orejia/p/12349105.html
Copyright © 2020-2023  润新知