161310 cient端收到synack后,根据ack值,使用SACK算法,只重传最后一个ack内容。

Server端收到数据包,由于accept队列仍然是满的,所以server端处理也只是标记acked,然后返回。

162884 client端等待几秒后,没有收到对应的ack,认为之前的数据包也丢失,所以重传之前的内容数据包。

Server端收到数据包,由于accept队列仍然是满的,所以server端处理也只是标记acked,然后返回。

164828 client端等待一段时间后,认为连接不可用,于是发送FIN、ACK给server端。Client端的状态变为FIN_WAIT1,等待一段时间后,client端将看不到该链接。

164829 server端收到ACK后,此时cgi程序处理完一个请求,从accept队列中取走一个连接,此时accept队列中有了空闲,server端将请求的连接放到accept队列中。

这样cgi所在的服务器上显示该链接是established的,但是nginx(client端)所在的服务器上已经没有该链接了。

之后,当cgi程序从accept队列中取到该连接后,调用read去读取sock中的内容,但是由于client端早就退出了,所以read就会block那里了。

问题解决

或许你会认为在164829中,server端不应该建立连接,这是内核的bug。但是内核是按照RFC来实现的,在3次握手的过程中,是不会判断FIN标志位的,只会处理SYN、ACK、RST这三种标志位。

从应用层的角度来考虑解决问题的方法,那就是使用非阻塞的方式read,或者使用select超时方式read;亦或者nginx中关闭连接的时候使用RST方式,而不是FIN方式。

附录1

when I use linux TCP socket, and find there is a bug in function sk_acceptq_is_full():

When a new SYN comes, TCP module first checks its validation. If valid,send SYN,ACK to the client and add the sock

to the syn hash table.

Next time if received the valid ACK for SYN,ACK from the client. server will accept this connection and increase the

sk->sk_ack_backlog -- which is done in function tcp_check_req().

We check wether acceptq is full in function tcp_v4_syn_recv_sock().

Consider an example:

After listen(sockfd, 1) system call, sk->sk_max_ack_backlog is set to

As we know, sk->sk_ack_backlog is initialized to 0. Assuming accept() system call is not invoked now

1. 1st connection comes. invoke sk_acceptq_is_full(). sk->sk_ack_backlog=0 sk->sk_max_ack_backlog=1, function return 0 accept this connection. Increase the sk->sk_ack_backlog

2. 2nd connection comes. invoke sk_acceptq_is_full(). sk->sk_ack_backlog=1 sk->sk_max_ack_backlog=1, function return 0 accept this connection. Increase the sk->sk_ack_backlog

3. 3rd connection comes. invoke sk_acceptq_is_full(). sk->sk_ack_backlog=2 sk->sk_max_ack_backlog=1, function return 1. Refuse this connection.I think it has bugs. after listen system call. sk->sk_max_ack_backlog=1

but now it can accept 2 connections.

linux accept过程,Linux协议栈accept和syn队列问题相关推荐

  1. linux系统启动过程(三)

    Linux 系统启动过程 linux启动时我们会看到许多启动信息. Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立终端 ...

  2. 深入理解Linux启动过程 0号进程,1号进程

    深入理解Linux启动过程 Linux系统的启动过程由很多阶段组成,这篇博客从初始化引导程序到第一个用户空间应用程序探索Linux启动进程. 我们先从Linux启动的顶层视图开始分析,以便能有一个整体 ...

  3. 嵌入式Linux系统启动过程

    一个嵌入式 Linux 系统从软件角度看可以分为四个部分:引导加载程序(Bootloader), Linux 内核,文件系统,应用程序. 当系统首次引导时,或系统被重置时,处理器会执行一个位于Flas ...

  4. linux系统的启动过程 5个步骤,第5章 Linux系统启动过程.ppt

    <第5章 Linux系统启动过程.ppt>由会员分享,可在线阅读,更多相关<第5章 Linux系统启动过程.ppt(26页珍藏版)>请在人人文库网上搜索. 1.第5章 Linu ...

  5. BootLoader、Linux Kernel(linux内核)、RootFile(根文件系统)

    这3部分是怎么相互协作来构成这个系统的呢? 各自有什么用呢? 三者有什么联系? 怎么联系? 系统的执行流程又是怎么样的呢? 搞清楚这个问题你对整个系统的运行就很清楚了,对于下一步制作这个linux系统 ...

  6. Linux accept tcp,Linux TCP accept without SYN|ACK

    问题 I'm trying to write a TCP transparent proxy to run on Linux. I want to, upon receipt of an incomi ...

  7. linux accept 队列,[译] TCP的SYN队列和Accept队列

    关于两个队列 46323_all-1.jpeg 首先我们必须明白,处于"LISTENING"状态的TCP socket,有两个独立的队列: SYN队列(SYN Queue) Acc ...

  8. linux协议栈劫持,Linux系统优化之TCP协议栈优化-基本篇1

    因为在做爬虫分布式系统的过程中,涉及到了一些linux系统优化方面的知识,所以来总结一下,我们会对linux的不同模块做相关的基本优化,这篇文章主要讲述的是关于tcp协议栈的参数优化. 1.机器环境 ...

  9. 输入网址后发生了什么没有listen(accept)能建立连接吗SYN洪水

    网络复习一 键入网址到网页显示,期间发生了什么 一.HTTP 二.DNS 域名系统 三.TCP 四.IP 五.MAC 六.网卡 七.交换机 八.路由器 sk_buff 网卡上有数据如何得知? 网络中如 ...

最新文章

  1. linux 挂载u盘区别不到,linux系统下为什么不能挂载U盘
  2. RWMutex的一道面试题
  3. html页面返回json数据为空,在Html页面中,展示出Json格式数据,且保持缩进格式...
  4. 前端根据设计图精确开发 (攻具)
  5. 【2017-12-06】c#基础-分支语句and循环语句
  6. Charlotte:不会被检测到的Shellcode启动器
  7. 生成drl文件_Allegro生成Gerber文件的方法
  8. Who is in me? -- Freeware on Windows
  9. FlashFXP注册码、密钥
  10. STM32+ADS1110
  11. 小程序源代码 古诗词
  12. 如何写PRD文档[最全版]
  13. iOS 真机调试 Bundle Identifier
  14. D - New Year Snowmen(优先队列+贪心)
  15. ios 应用和电脑共享文件夹_无需软件,在ios和Win之间实现高速文件共享
  16. [计算几何]Last Stardust
  17. android6.0在状态栏添加一键截屏
  18. android studio 安装教程
  19. Python常见主流框架简介
  20. 儿童护眼灯怎么选?儿童护眼灯品牌排行榜

热门文章

  1. .net core DI 注册 Lazy 类型
  2. .Net 4.X 提前用上 .Net Core 的配置模式以及热重载配置
  3. [翻译]编写高性能 .NET 代码 第一章:工具介绍 -- Visual Studio
  4. .NET的一点历史故事:招兵买马和聚义山林
  5. .Net基础体系和跨框架开发普及
  6. mysql索引有哪些了解_Mysql索引(简单了解)
  7. c 连接mysql怎么增删改_C++ API方式连接mysql数据库实现增删改查
  8. [转]浅谈CMD和win powershell的区别
  9. C# RichTextBox 实现循环查找关键字
  10. 【Microstation】第一章:Microstation三维模型构建概述