先看了这篇:

http://www.cppblog.com/thisisbin/archive/2010/02/07/107444.html

里面说了会维护两个队列,established 和 syn_rcvd的。而back_log指定的长度是两个队列之和(乘以一个系数)

当客户端的第一个SYN到达的时候,TCP会在未完成队列中增加一个新的记录然后回复给客户端三路握手中的第二个分节(服务端的SYN和针对客户端的ACK),这条记录会在未完成队列中一直存在,直到三路握手中的最后一个分节到达,或者直到超时(Berkeley时间将这个超时定义为75秒)

如果当客户端SYN到达的时候队列已满,TCP将会忽略后续到达的SYN,但是不会给客户端发送RST信息,因为此时允许客户端重传SYN分节,如果返回错误信息,那么客户端将无法分清到底是服务端对应端口上没有相应应用程序还是服务端对应端口上队列已满这两种情况

http://blog.csdn.net/wangst4321/article/details/8733212

这篇文章给了一些系数的值:

不同backlog对应的队列长度

系统为正等待连接请求的TCP服务程序,维护一个固定长度的连接队列。这个队列中的连接是已经被TCP接收(已经完成三次握手),但是还没有被应用程序接收(调用accept函数)

Linux的情况

而第一篇文章的评论里面说了,上面这种情况是BSD的情况,Linux里面不是这样的。Linux里面是,这个backlog 就是established的数量,而syn_rcvd数量是另外通过

/proc/sys/net/ipv4/tcp_max_syn_backlog 设置的。具体可以看:

http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html

The interesting question is now how such an implementation behaves if the accept queue is full and a connection needs to be moved from the SYN queue to the accept queue, i.e. when the ACK packet of the 3-way handshake is received.

最关键的情况,是当established队列放不下,怎么办?

文中分析源代码,发现结论是,忽略。意思是当最后一个ack到来时候,本来应该把连接移动到established队列,但是满了,那么就忽略不移动;那么这个时候的情况对应于ack丢失,需要把三次握手里面的第二步(syn+ack)重发,之后又会有ack到来(注意会有超时次数)。而超过次数之后,server端就close了,client再发的话,会收到RST.

还有一个非常有意思的问题:三次握手的客户端,在发出最后一个ack的时候,状态已经是established了。那这个时候,它其实就开始发送数据了。

结果是:If it sends data (without waiting for data from the server first), then that data will be retransmitted as well. Fortunately TCP slow-start should limit the number of segments sent during this phase.

也对应了第二篇文章里面观察到的现象,就是发送的数据也一直得不到确认,而是需要不断重发。(Link

如下为第二篇文章的部分内容:

这里应该注意到客户端认为的连接状态是成功建立的,因为从客户端端口到服务器端口的连接都是处于ESTABLISHED的。这将导致客户端程序执行connect时是成功返回的,并继续下一步的动作,向服务器发送数据。

由于数据的发送是交给系统底层完成的,当客户端执行send时,数据将传送给系统底层。如果系统底层可以接收所有数据,则客户程序认为发送成功并返回。这点通过客户端执行结果,可以得到验证。所有客户端都是立即完成,并输出以下信息:
connect successfully.
sent byte: 1024
实际的情况是什么样的呢?通过命令“tcpdump -i lo”观察数据的传送。从以下数据可以看出,服务器程序实际上并没有与客户端程序建立连接,而且数据传输也没有真正完成。

总结

客户端connect成功返回时,并不表示与服务端的连接已经真正建立。Send发送数据成功返回也不表示服务器端已经成功接收了。编程时应该注意到这两点。

第二篇文章的内容(完)

回到第三篇文章:

On the other hand, if the client first waits for data from the server and the server never reduces the backlog, then the end result is that on the client side, the connection is in state ESTABLISHED, while on the server side, the connection is considered CLOSED. This means that we end up with a half-open connection!

另一个问题是,是否所有的SYN都会加到SYN的队列。Linux的做法是不会,因为ESTABLISHED队列满了,会导致SYN队列也满了,还不进来。

LInux将两个队列的阈值分开的好处,文中描述为如下:

The implementation in Linux effectively separates these two concerns:

the application is only responsible for tuning the backlog such that it can callaccept fast enough to avoid filling the accept queue);

a system administrator can then tune/proc/sys/net/ipv4/tcp_max_syn_backlog based on traffic characteristics.

(完)

listen函数里面backlog的意义以及各种情况的更多相关文章

  1. tcp/ip协议listen函数中backlog參数的含义

    listen函数的定义例如以下所看到的: #include <sys/socket.h> int accept(int sockfd, struct sockaddr * restrict ...

  2. listen()函数中backlog参数分析

    实例分析1 将服务器端的listen函数backlog设置为2,用20个客户端与服务器建立连接,查看连接的建立情况. 服务器代码: #include <stdio.h> #include& ...

  3. tcp/ip协议listen函数中backlog参数的含义与php-fpm的502 Bad Gateway

    To understand the backlog argument, we must realize that for a given listening socket, the kernel ma ...

  4. listen的参数backlog的意义

    实验环境:Ubuntu16.04,内核版本:4.4.0-59-generic   根据man listen得到的解释如下:   backlog参数定义了存放pending状态(挂起.护着搁置)的连接的 ...

  5. Socket编程:listen()函数英文翻译

    作者:C语言达人 链接:https://zhuanlan.zhihu.com/p/24951131 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 本篇翻译的list ...

  6. linux tcp listen函数的参数backlog

    1 listen函数(http://man7.org/linux/man-pages/man2/listen.2.html) int listen(int sockfd, int backlog); ...

  7. 深入探索 Linux listen() 函数 backlog 的含义

    1:listen()回顾以及问题引入 2:正确的解释 3:实验验证 1:listen()回顾以及问题引入 listen()函数是网络编程中用来使服务器端开始监听端口的系统调用,首先来回顾下listen ...

  8. Listen第二个参数的意义

    今天主要回顾下listen的第二个参数的意义. 话说现在现在都是用框架写业务代码.真的很少在去关注最基本的socket函数的意义了.该忘得都忘得差不多了.~~~  要慢慢捡起来.  主要是在看redi ...

  9. socket编程listen函数限制连接数的解决方案

    函数原型: int listen(int sockfd, int backlog); 当服务器编程时,经常需要限制客户端的连接个数,下面为问题分析以及解决办法: 下面只讨论TCP  UDP不做讨论(很 ...

随机推荐

  1. 深入理解linux网络技术-P179

    上锁 net_device结构的组织一节可知,dev_base列表以及dev_name_head和dev_name_index两张hash表由dev_base_list锁保护.然而,该锁只用于对列表和 ...

  2. Dev之ChartControl控件(一)

    ChartControl控件主要包括Chart Title,Legend,Annotations,Diagram,Series五部分:如图: 1.  用RangeControl控件控制ChartCon ...

  3. Mysql笔记3数据库基本操作

    1 创建数据库 create database 数据名称 default character set 编码; 2查看常用的编码校验规则 mysql> show character set; 3删 ...

  4. L6,Percy Buttons

    expressions: knock at敲打 knock off 碰掉,I knock the vase off the table 下班,He always knocks off six o'cl ...

  5. ImageLoader的使用

    显示本地图片 //ImageLoader使用前必须初始化 ImageLoader imageLoader = ImageLoader.getInstance(); imageLoader.init(I ...

  6. 手机号码抽奖系统(JS)

    <html><head><title>手机号码抽奖</title><meta http-equiv="Content-Type" ...

  7. JSP标签编程--简单标签

    javax.servlet.jsp.tagext里的类SimpleTagSupport 使用SimpleTagSupport类一网打尽以往复杂的标签开发,直接使用doTag()方法 java文件: p ...

  8. Linux 下安装配置 JDK1.7

    目录[-] 1.下载JDK 2.解压安装 3.配置环境变量 4.配置默认JDK(一般情况下这一步都可以省略) 5.测试 1.下载JDK Linux操作系统是:Centos6.5-x64 目前最新的JD ...

  9. 货物搬运(move)

    货物搬运(move) 题目描述 天地无情人有情,一方有难八方支援!汶川大地震发生后,灾区最紧缺的是救灾帐篷,全国各地支援的帐篷正紧急向灾区运送.假设围绕纹川县有环行排列的n个救灾帐篷的存储点,每个存储 ...

  10. Android------自定义ListView详解

    引自:http://www.cnblogs.com/phonegap/archive/2011/04/28/2535732.html 在这里我就对自定义ListView进行讲解下吧,直入真题吧,首先我 ...