你好,游客 登录 注册 搜索
背景:
阅读新闻

Linux中listen()系统调用的backlog参数分析

[日期:2013-02-23] 来源:Linux社区  作者:moonvs2010 [字体: ]

这篇文章是对上一篇博客网络编程常用接口的内核实现----sys_listen()的补充(见 http://www.linuxidc.com/Linux/2013-02/79858.htm ),上篇文章中我说listen()系统调用的backlog参数既是连接队列的长度,也指定了半连接队列的长度(不能说等于),而不是《Unix网络编程》中讲到的是半连接队列和连接队列之和的上限,也就是说这个说法对Linux不适用。这篇文章中通过具体的代码来说明这个结论,并且会分析如果连接队列和半连接队列都满的话,内核会怎样处理。

首先来看半连接队列的上限是怎么计算和存储的。半连接队列长度的上限值存储在listen_sock结构的max_qlen_log成员中。如果找到监听套接字的sock实例,调用inet_csk()可以获取inet_connection_sock实例,inet_connection_sock结构是描述支持面向连接特性的描述块,其成员icsk_accept_queue是用来管理连接队列和半连接队列的结构,类型是request_sock_queue。listen_sock实例就存储在request_sock_queue结构的listen_opt成员中,它们之间的关系如下图所示(注:本来下面的图应该横着画,但是横着CSDN会显示不全):

半连接队列的长度上限在reqsk_queue_alloc()中计算并设置的,代码片段如下所示:

int reqsk_queue_alloc(struct request_sock_queue *queue,
        unsigned int nr_table_entries)
{
 .......
 
 nr_table_entries = min_t(u32, nr_table_entries, sysctl_max_syn_backlog);
 nr_table_entries = max_t(u32, nr_table_entries, 8);
 nr_table_entries = roundup_pow_of_two(nr_table_entries + 1);
 ......
 
 ......
 
 for (lopt->max_qlen_log = 3;
      (1 << lopt->max_qlen_log) < nr_table_entries;
      lopt->max_qlen_log++);
 
 ......

}

前面的三行代码是调整存储半连接的哈希表的大小,可以看到这个值还受系统配置sysctl_max_syn_backlog的影响,所以如果想调大监听套接字的半连接队列,除了增大listen()的backlog参数外,还需要调整sysctl_max_syn_backlog系统配置的值,这个配置量对应的proc文件为/proc/sys/net/ipv4/tcp_max_syn_backlog。后面的for循环是计算nr_table_entries以2为底的对数,计算的结果就存储在max_qlen_log成员中。

接着来看连接队列长度的上限,这个比较简单,存储在sock结构的sk_max_ack_backlog成员中,在inet_listen()中设置,如下所示:

int inet_listen(struct socket *sock, int backlog)
{
 ......
 
 sk->sk_max_ack_backlog = backlog;
 err = 0;

out:
 release_sock(sk);
 return err;
}

linux
相关资讯       Linux系统调用  listen调用backlog  Linux listen 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款