sys接口linux编程,网络编程常用接口的内核实现----sys_listen()

四、reqsk_queue_alloc()函数

reqsk_queue_alloc()的源码实现及分析如下所示:

/*

* 用来分配连接请求块散列表,然后将其连接到所在传输控制块的请求

* 块容器中。

*/

int reqsk_queue_alloc(struct request_sock_queue *queue,

unsigned int nr_table_entries)

{

size_t lopt_size = sizeof(struct listen_sock);

struct listen_sock *lopt;

/*

* 取用户设定的连接队列长度最大值参数nr_table_entries和系统最多

* 可同时存在未完成三次握手SYN请求数sysctl_max_syn_backlog两者的

* 最小值,他们都用来控制连接队列的长度,只是前者针对某传输控制

* 块,而后者控制的是全局的

*/

nr_table_entries = min_t(u32, nr_table_entries, sysctl_max_syn_backlog);

nr_table_entries = max_t(u32, nr_table_entries, 8);

/*

* 调用roundup_pow_of_two以确保nr_table_entries的值为2的n次方

*/

nr_table_entries = roundup_pow_of_two(nr_table_entries + 1);

/*

* 计算用来保存SYN请求连接的listen_sock结构的大小

*/

lopt_size += nr_table_entries * sizeof(struct request_sock *);

if (lopt_size > PAGE_SIZE)

/*

* 如果用于保存SYN请求连接的listen_sock结构大于一个页面,

* 则调用__vmalloc()从高位内存中分配虚拟内存,并且清零

*/

lopt = __vmalloc(lopt_size,

GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,

PAGE_KERNEL);

else

/*

* 如果小于一个页面,则在常规内存中分配内存并清零。kzalloc()

* 封装了kmalloc()及memset()

*/

lopt = kzalloc(lopt_size, GFP_KERNEL);

if (lopt == NULL)

return -ENOMEM;

/*

* 从nr_table_entries = max_t(u32, nr_table_entries, 8);中可以看出

* nr_table_entries最小值为8,所以这里从3开始

*/

for (lopt->max_qlen_log = 3;

(1 << lopt->max_qlen_log) < nr_table_entries;

lopt->max_qlen_log++);

/*

* 初始化listen_sock结构中的一些成员,如用于生成连接请求块

* 散列表的hash_rnd等

*/

get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd));

rwlock_init(&queue->syn_wait_lock);

queue->rskq_accept_head = NULL;

lopt->nr_table_entries = nr_table_entries;

/*

* 将散列表连接到所在传输控制块的请求块容器中

*/

write_lock_bh(&queue->syn_wait_lock);

queue->listen_opt = lopt;

write_unlock_bh(&queue->syn_wait_lock);

return 0;

}

从上面的代码中可以看到半连接队列长度的计算过程,nr_table_entries的值存储的就是计算的结果,这个值是基于listen()的第二个参数的值计算得到的。半连接队列的上限值的以2为底的对数存储在lopt的max_qlen_log成员中,对数的计算是通过下面的代码完成的,如下所示:

for (lopt->max_qlen_log = 3;

(1 << lopt->max_qlen_log) < nr_table_entries;

lopt->max_qlen_log++);

五、结束语

在listen()系统调用中,第二个参数backlog对服务器的程序影响是很大的,而且不同的系统对这个参数的使用可能有所不同。前面我们也提到了,《Unix网络编程》中对第二参数backlog的描述是连接队列和半连接队列的长度之和不超过backlog,但是在Linux中并不是这样,限于篇幅,后面会单独写一篇关于backlog参数的分析文章来详细介绍。 见 http://www.linuxidc.com/Linux/2013-02/79859.htm0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值