博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux listen
阅读量:4029 次
发布时间:2019-05-24

本文共 1803 字,大约阅读时间需要 6 分钟。

http://blog.163.com/hbu_lijian/blog/static/126129153201372711102269/ 

listen系统可以使一台主机上的一个tcp socket在某个端口号被动侦听,等待来自其它主机的tcp socket的连接请求,下面是listen系统调用的函数原型:
        #include <sys/socket.h>
        int listen(int s, int backlog);
    backlog是侦听队列的长度,在内核函数中,首先对backlog作检查,如果大于128,则强制使其等于128。接下来要检查结构体struct sock的成员sk_state,即当前socket的状态,如果不为TCP_LISTEN,则开始启动端口侦听。启动端口侦听首先要为结构体 struct inet_connection_sock(它是struc sock的扩展,表示一个面向连接的socket)的成员icsk_accept_queue分配内存,icsk_accept_queue的类型是 struct request_sock_queue,定义如下:
    struct request_sock_queue {


        struct request_sock     *rskq_accept_head;
        struct request_sock     *rskq_accept_tail;
        rwlock_t                syn_wait_lock;
        u8                      rskq_defer_accept;
        struct listen_sock      *listen_opt;
    };
    tcp socket在侦听的时候,那些来自其它主机的tcp socket的连接请求一旦被接受(完成三次握手协议),便会建立一个request_sock,建立与请求socket之间的一个tcp连接。该 request_sock会被放在一个先进先出的队列中,等待accept系统调用的处理。但上面的结构体中好像并没有可以存放request_sock 的地方,下面是结构体struct listen_sock的定义:
        struct listen_sock {

            u8          max_qlen_log;
            int         qlen;
            int         qlen_young;
            int         clock_hand;
            u32         hash_rnd;
            u32         nr_table_entries;
            struct request_sock *syn_table[0];
        };
    新建立的request_sock就存放在syn_table中。这是一个哈希数组,总共有nr_table_entries项。实际上在分配内存时,分 配的大小是TCP_SYNQ_HSIZE(512)项。成员nr_table_entries的值是512。成员max_qlen_log以2的对数的形 式表示request_sock队列的最大值。哈希表有512项,但队列的最大值的取值是1024。即max_qlen_log的值为10。qlen是队 列的当前长度。hash_rnd是一个随机数,计算哈希值用,结构体struct request_sock_queue中的rskq_accept_head和rskq_accept_tail分别指向request_sock队列的 队列头和队列尾。
    为struct inet_connection_sock分配完内存后,继续处理,结构体struct sock有两个成员sk_ack_backlog和sk_max_ack_backlog。sk_ack_backlog表示该侦听socket上,当前 连向该socket,但是还没有完成三次握手协议的socket的数量,即还在连接过程中的socket的数量。初始值为 0,sk_max_ack_backlog为该数量的最大值,也就是listen系统调用的第二个参数,即侦听队列的长度,它的真正含义是:侦听 socket能处理的最大并发连接请求数,其最大取值为128。
    到这里,把socket的状态改为TCP_LISTEN,进入侦听状态。然后独占端口,使socket进入mytcp_hashinfo哈希表集中的listening_hash表。侦听建立完成。
    由于侦听socket始终在系统中进行侦听工作,所以在进程结束时,还必须显式结束侦听,进行相应的清理工作。

转载地址:http://ehobi.baihongyu.com/

你可能感兴趣的文章
漂亮的代码,糟糕的行为——解决Java运行时的内存问题
查看>>
Java的对象驻留
查看>>
自己动手写GC
查看>>
Java 8新特性终极指南
查看>>
logback高级特性使用(二) 自定义Pattern模板
查看>>
JVM并发机制探讨—内存模型、内存可见性和指令重排序
查看>>
可扩展、高可用服务网络设计方案
查看>>
如何构建高扩展性网站
查看>>
微服务架构的设计模式
查看>>
持续可用与CAP理论 – 一个系统开发者的观点
查看>>
nginx+tomcat+memcached (msm)实现 session同步复制
查看>>
c++指针常量与常量指针详解
查看>>
c++字符数组和字符指针区别以及str***函数
查看>>
c++类的操作符重载注意事项
查看>>
c++模板与泛型编程
查看>>
STL::deque以及由其实现的queue和stack
查看>>
CS4344驱动
查看>>
WAV文件解析
查看>>
DAC输出音乐2-解决pu pu 声
查看>>
WPF中PATH使用AI导出SVG的方法
查看>>