现象:

以下为其他网站提供,和我遇到的情况一样。

就是服务器老是重复发送 SYN, ACK。

4414.229553  client -> server TCP 62464 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1452 WS=3 TSV=116730231 TSER=0
4414.229633 server -> client  TCP http > 62464 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=2406364374 TSER=116730231 WS=6
4414.263330  client -> server TCP 62464 > http [ACK] Seq=1 Ack=1 Win=524280 Len=0 TSV=116730231 TSER=2406364374
4418.812859 server -> client  TCP http > 62464 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=2406365520 TSER=116730231 WS=6
4418.892176  client -> server TCP [TCP Dup ACK 778#1] 62464 > http [ACK] Seq=1 Ack=1 Win=524280 Len=0 TSV=116730278 TSER=2406365520
4424.812864 server -> client  TCP http > 62464 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=2406367020 TSER=116730278 WS=6
4424.891240  client -> server TCP [TCP Dup ACK 778#2] 62464 > http [ACK] Seq=1 Ack=1 Win=524280 Len=0 TSV=116730337 TSER=2406367020

可能的问题:供参考

OK, I don't have a full answer, but I've learned a lot since this issue first came up. I'll share my insights here.

  • Firstly, the problem was triggered by Google Chrome opening a number of sockets (6 in my tests) to any website you open with it. It does this to kickstart downloading the various elements of a website in parallel. For simple websites that don't have many items, like mine, some of these pre-opened sockets will sit idle. I've read that other modern browsers do this as well.
  • 首先,该问题是在使用Chrome 浏览器通过建立多个socket 连接(我的测试是6个socket连接)打开网页时出现的,它启动并行下载各种网页内容,而简单的网页站点没有很多内容,就行我的站点,其他的预打开的socket 就被闲置。我看了其他的浏览器也都是同样的。
  • The client triggering the connection-tracking problem probably has a broken home-router or something, because the idle sockets tend to disappear without any FIN or RST packets being sent to tear them down.
  • 客户端触发这个连接问题,可能是有一个有问题的家庭路由器或者其他问题,因为这些闲置的socket 会莫名的消失而不发任何的fin 或者RST 包。
  • The repeating of the SYN+ACK packets seems to be normal TCP behaviour, I've been able to witness it on various third-party webservers by running a packet dump and then doing something like telnet www.website.com 80 and not sending any data. It could still be a Linux peculiarity though, as the servers I tested may well all run Linux. This behaviour also happened without any iptables-rules loaded, so it's really kernel-related.
  • 这重复的SYN+ACK 报可能是个正常的行为,我已经通过telnet 其他第三方网站而不发数据(telnet www.website.com 80 ),并抓包验证了它。它可能是linux 系统特有的,我测试的都是在linux 系统上,并且没有任何的防火墙规则设置,因此可能和内核相关。
  • After sending a few SYN+ACK packets without response, the Linux kernel will tear down its side of the connection. iptables connection-tracking doesn't seem to share this logic, so there the connection will remain in the ESTABLISHED state until it times out. The default timeout of this is 5 days (!). I'm planning to reduce this to something more sensible such as a few hours.
  • 发送一些SYN+ACK 包之后,没有回应。这linux 内核将断开它这边的tcp 连接。防火墙连接没有采用这个处理方式,因此它的tcp 连接仍然保持ESTABLISHED 状态一直到超时,默认超时是5 天,我计划减小这个值到一个比较合理的值几个小时。
  • Repeating the SYN+ACKs after receiving ACK is not completely default behaviour, since I didn't see it when I opened a listening port with nc -l ### and connected to that. So it might be a certain TCP option Apache sets on its listening socket. Or it might be something entirely unique to Apache. Most other daemons announce themselves immediately after connection, so they are no valid test cases for this. The connection needs to do a 3-way handshake and then immediately fall idle.
  • 服务器收到ack 后重复发送SYN+ACKs 也不完全是个默认行为,我在用 nc -l 打开一个监听端口,并且连接它,没出现该情况。因此它可能是某个tcp 选项被apache 设置在监听socket。或者一些apache 独特的东西造成的。大多数其他守护程序会立即变成connection 状态。因此这没有有效的测试案例:这连接需要在做一个tcp 三次握手,并且立即空闲。

以上为网上的一些分析,我结合自己的情况。基本可以肯定我的路由器有问题。因为我在配置好端口映射之后,外网可以访问路由器的远程web 管理页面,而空闲一段时间或过一晚上,第二天发现外网的远程web 管理页面无法连接,其他的映射端口也无法连接。内网抓包发现和以上描述的现象。

===============================================================================

咳,刚写完就找到最终答案了:

监听socket 使用了TCP_DEFER_ACCEPT选项。

————————————————————————————————————————————————————————————————

1. 设置TCP_DEFER_ACCEPT

int val = 10;  // time_out

if (setsockopt(sock_descriptor, IPPROTO_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val))== -1)

{

perror("setsockopt");

exit(1);

}

2. TCP_DEFER_ACCEPT的效果

正常的tcp三次握手过程:

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; 

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
设置TCP_DEFER_ACCEPT后
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; 

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,连接并不进入ESTABLISHED状态,而是在第一个真正有数据的包到达后才进入ESTABLISHED,完成连接的建立。
TCP_DEFER_ACCEPT的超时
在第三次握手时候,如果客户段迟迟不发送数据,服务器 连接将一直处于syn_recv状态。此时内核会重传 syn_ack ,重传的次数可以通过 sysctl -w net.ipv4.tcp_synack_retries=3来设置,如果3次重传后,客户端依然没有数据,在等待 设置TCP_DEFER_ACCEPT时候指定的超时时间后(这个时间单位为s,可是测试看来并不精准的执行),系统将回收连接,并不对客户端发出rst或者fin包。
 

服务器重复发送SYN ACK 和 TCP_DEFER_ACCEPT设置的更多相关文章

  1. TCP被动打开 之 第二次握手-发送SYN+ACK

    假定客户端执行主动打开,发送syn包到服务器,服务器执行完该包的第一次握手操作后,调用af_ops->send_synack向客户端发送syn+ack包,该回调实际调用tcp_v4_send_s ...

  2. TCP主动打开 之 第二次握手-接收SYN+ACK

    假设客户端执行主动打开,已经经过第一次握手,即发送SYN包到服务器,状态变为SYN_SENT,服务器收到该包后,回复SYN+ACK包,客户端收到该包,进行主动打开端的第二次握手部分:流程中涉及到的函数 ...

  3. TCP服务器不回复SYN的问题

    个人问题发生环境: 1.TCP服务器是虚拟机,IP地址是192.168.8.12. 2.TCP客户端是宿主机,IP地址是192.168.8.11. 3.从宿主机(192.168.8.11)上启动Soc ...

  4. 韩顺刚-tcp报文头协议详细分析第一包数据:序号是0,发送数据的长度是0,因为没有收到对端的数据,所以确认号是0, Syn的标志位设置成1,这里没有发送的数据,只发送TCP的20个字节的头部

    TCP报文段首部格式 大部分TCP报文头部都是20个字节,有的数据包要加上选项. 上面一行代表4个字节,源端口和目的端口都是2个字节. TCP协议是面向字节流的协议 TCP是一段一段分块的发送数据的 ...

  5. jmeter测试TCP服务器/模拟发送TCP请求 设置16进制发送(转)

    转载留存:http://blog.sina.com.cn/s/blog_46d0362d0102v8ii.html 性能测试需要模拟多种场景,经常受制于资源限制,没办法建立贴近实际部署环境的场景.因而 ...

  6. TCP协议: SYN ACK FIN RST PSH URG 详解

    TCP的三次握手是怎么进行的了:发送端发送一个SYN=1,ACK=0标志的数据包给接收端,请求进行连接,这是第一次握手:接收端收到请求并且允许连接的话,就会发送一个SYN=1,ACK=1标志的数据包给 ...

  7. TCP连接建立系列 — 客户端发送SYN段

    主要内容:客户端调用connect()时的TCP层实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd connect的TCP层实现 SOCK_STRE ...

  8. RabbitMQ,RocketMQ,Kafka 事务性,消息丢失和消息重复发送的处理策略

    消息队列常见问题处理 分布式事务 什么是分布式事务 常见的分布式事务解决方案 基于 MQ 实现的分布式事务 本地消息表-最终一致性 MQ事务-最终一致性 RocketMQ中如何处理事务 Kafka中如 ...

  9. linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查(转载)

    linux系统telnet端口不通能收到SYN但不回SYN+ACK响应问题排查 一:背景:一台机器从公司办公网登录不上且所有tcp端口都telnet不通,但是通过同机房同的其它机器却可以正常访问到出问 ...

随机推荐

  1. Numpy:ndarray数据类型和运算

    Numpy的ndarray:一种多维数组对象 N维数组对象,该对象是一个快速而灵活的大数据集容器,nadarry是一个通用的同构数据多维容器,也就是说,其中的所有元素必须是相同类型的.每个数组都有一个 ...

  2. artTemplate js模板引擎动态给html赋值

    html放到$("#area").append(html);之前,否则文档流获取不到#area <table width="90%" class=&quo ...

  3. SQLdeveloper换成windows主题后不显示的情况

    这几天因为换电脑需要重新安装数据库, 因为换成了64位系统, 原先的oracle数据库也换成了64位, 但是plsql还是要用32位的, 经过深思熟虑也没装, 请教了一个同学改用oracle自带的sq ...

  4. CentOS rpm

    rpm命令是RPM软件包的管理工具.rpm原本是Red Hat Linux发行版专门用来管理Linux各项套件的程序,由于它遵循GPL规则且功能强大方便,因而广受欢迎.逐渐受到其他发行版的采用.RPM ...

  5. 【git】日志提交规范

    我自己总结的规范: feature: 功能添加bugfix: bug修复change: 调整,比如配置,某些方法替换等optimize: 优化过程doc: 文档变更refactor: 重构,功能不变t ...

  6. Employee类

    package demo; import java.time.LocalDate; public class Employee { private String name; private doubl ...

  7. angular2.0学习笔记1.开发环境搭建 (node.js和npm的安装)

    开发环境, 1.安装Node.js®和npm, node 6.9.x 和 npm 3.x.x 以上的版本. 更老的版本可能会出现错误,更新的版本则没问题. 控制台窗口中运行命令 node -v 和 n ...

  8. hdu 5461(2015沈阳网赛 简单暴力) Largest Point

    题目;http://acm.hdu.edu.cn/showproblem.php?pid=5461 题意就是在数组中找出a*t[i]*t[i]+b*t[j]的最大值,特别注意的是这里i和i不能相等,想 ...

  9. iOS.Crash.OniOS8.WhenCall[popToRootViewController]

    系统iOS 8.x, ARC. CrashCase: 在UIViewController中有一个类型为UIScrollView的实例变量scrollView, 点击UIViewController中的 ...

  10. python提取分析表格数据

    #/bin/python3.4# -*- coding: utf-8 -*- import xlrd def open_excel(file="file.xls"): try: d ...