先看了这篇:

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. 深入解析FileInputStream和FileOutputStream

    http://swiftlet.net/archives/1363 FileInputStream和FileOutputStream类属于字节类,可以操作任意类型的文件.在数据流的处理过程中,有两种情 ...

  2. js自写字符串 append 方法

    function stringbuilder(){ this.arr = new Array(); this.append=function(str) { this.arr.push(str); } ...

  3. EDA 事件驱动框架

    事件代表过去发生的事件,事件既是技术架构概念,也是业务概念.以事件为驱动的编程模型称为事件驱动架构EDA. EDA是一种以事件为媒介,实现组件或服务之间最大松耦合的方式.传统面向接口编程是以接口为媒介 ...

  4. posix信号量(sem_t)

    引言 信号量分为三种:posix有名信号量(使用Posix IPC名字标识,至少具有随内核的持续性)/posix基于内存的信号量(共享内存,随进程的持续性)/System V 信号量(内核) 有了互斥 ...

  5. YII2 随笔 视图最佳实践

    yii\base\Controller::render(): 渲染一个 视图名 并使用一个 布局 返回到渲染结果. yii\base\Controller::renderPartial(): 渲染一个 ...

  6. Entity Framework 6新功能Logging/Store Procedure

    摘要 在Entity Framework6中有两个新的功能,DB Loggin和Stored Procedure的映射 Entity Framework 6已经从Beta版本来到了RC1版本,我们可以 ...

  7. Android面试经验1

    1,java基本数据类型. Byte.short.int.long.float.double.char.boolean. 1         2       2     2      4       ...

  8. redmine配置邮件

    作为一个项目管理平台,必须能够通知项目成员有关项目和任务的各种状态变化.这也是一种典型的观察者模式.开发人员可以跟踪某个任务,当任务状态.备注.文档.优先级等变化时开发人员就可以得到通知. 对于新配置 ...

  9. CASpringAnimation

    iOS9新出现的 /** Subclass for mass-spring animations. */ @interface CASpringAnimation : CABasicAnimation ...

  10. (转)初识suse——linux

    Linux这种系统很奇怪,差不多每种不同的版本,它所使用的安装等一些重要命令皆有所变化.假若,你要熟练掌握一种OS,那么如果安装软件/应用,那是入门的第一步.   安装命令中: RedHat.Cent ...