先看了这篇:

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. db2导入表结构和表数据

    http://www.cnblogs.com/kfarvid/archive/2010/12/15/1906776.html   db2的博文 -bash-3.2$ db2 connect to ca ...

  2. hdu 3345 War Chess

    War Chess Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Sub ...

  3. Mysql主从备份、主主备份

    简单介绍mysql双机,多机异地热备简单原理实战. 双机热备的概念简单说一下,就是要保持两个数据库的状态自动同步.对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一致. 这样做 ...

  4. HDU - 2502 Subway

    题目链接:http://poj.org/problem?id=2502 分析: 告诉一些地铁线路,从起点到终点,中途可以步行,可以坐地铁,找一条最短的路 主要是把图建立好,然后直接dijkstra或者 ...

  5. js 判断网页类型

    <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>标题页</title ...

  6. Chapter 1 First Sight——15

    The red-haired woman looked up. "Can I help you?" 红头发的女人抬头看了一眼说,有什么我能帮助你的吗? "I'm Isab ...

  7. MaterialDrawer的使用

    这是一个MaterialDesign风格的侧滑,在github上下载压缩包,按照github上的方式引入依赖,然后打开压缩包里面的例子程序,对照着APK看,即可知道怎么实现的(好像说了一堆废话..)

  8. nginx 504 Gateway Time-out 解决办法

    今天用PHP执行一个非常耗时的文件[ps:自己有用,大概3分钟] 但是执行到一分钟后显示 nginx 504 Gateway Time-out 于是修改php-ini.php中的max_executi ...

  9. 数的计数(number)

    数的计数(number) 题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数n),先输入一个自然数n(n≤1000),然后对此自然数按照如下方法进行处理: (1)不作任何处理: (2)在它的 ...

  10. 小红的难题<递推>

    题意:五个数:N,x,y,A,B;N是台阶总数,x,y是每步可以走x或者y步,但是一定要走到A,B台阶上. 思路:学长给的题解,递推,稍微优化一点. >重点在递推 #include<cst ...