🔥🔥你以为你了解TCP协议?这些你可能不知道的细节才是关键!
引言
在之前的内容中,我们已经详细讲解了TCP面试中最常见的问题,如三次握手和四次挥手等。而今天,我们将继续深入探讨TCP协议的其他方面,比如序列号和TCP Fast Open(TFO)等重要细节问题。这些内容将为你在面试中提供更全面的知识储备。
为什么 SYN/FIN 不包含数据却要消耗⼀个序列号?
SYN/FIN 是 TCP 协议中的标志位,用于建立和关闭连接。它们不包含数据,但需要消耗一个序列号的原因是为了保持 TCP 连接的可靠性。
在 TCP 连接建立时,客户端发送 SYN 包给服务器端,服务器端接收到后发送 SYN+ACK 包给客户端,最后客户端发送 ACK 包确认连接建立。这个过程中,每个包都需要有一个序列号来标识数据的顺序和确认接收。
类似地,在 TCP 连接关闭时,FIN 包被用来表示一端希望关闭连接。发送 FIN 包的一端会等待对方发送 ACK 包来确认关闭,然后再发送 ACK 包进行最终确认。同样,这个过程中的每个包都需要有一个序列号。
通过使用序列号,TCP 协议可以保证数据的可靠传输,确保数据按照正确的顺序到达目标。因此,即使 SYN/FIN 包本身不携带数据,它们仍然需要消耗一个序列号来维护连接的可靠性。

如果在建立或关闭TCP连接时不发送序列号,将会导致连接的可靠性和数据的顺序无法保证。
在建立连接时,发送方的SYN包没有序列号,接收方无法准确地判断数据包的顺序。这可能导致接收方无法正确地响应SYN+ACK包,从而导致连接无法建立。
在关闭连接时,如果不发送序列号,接收方无法准确地确认关闭请求,并且无法确定关闭顺序。这可能导致连接无法成功关闭,或者导致数据丢失或混乱。
什么是半连接队列?什么是SYN Flood攻击?
半连接队列(Half-open connection queue)是指TCP服务器在处理连接请求时,当收到客户端发送的SYN包(同步包)时,会将该连接请求添加到半连接队列中。半连接队列中保存了已收到SYN包但还未完成三次握手的连接请求。
SYN Flood攻击是一种网络攻击方式,它利用TCP协议的漏洞,大量地向目标服务器发送伪造的SYN包,使服务器的半连接队列被耗尽。当服务器的半连接队列被耗尽后,正常的连接请求无法得到处理,导致服务不可用。

在SYN Flood攻击中,攻击者发送大量的伪造源IP地址的SYN包给目标服务器,但攻击者并不真正完成三次握手建立连接,而是让服务器一直等待,从而消耗服务器的资源。由于服务器需要为每个未完成的连接请求分配一些资源,当半连接队列被耗尽时,服务器将无法处理正常的连接请求,导致服务崩溃或变得不可用。
为了防止SYN Flood攻击,服务器可以采取一些防御措施,例如使用防火墙过滤掉伪造源IP的SYN包、增加半连接队列的大小、限制每个IP地址的连接请求数量等。这些措施可以帮助服务器抵御SYN Flood攻击并保持正常的服务运行。
说说TCP快速打开(TFO)的原理
在TCP快速打开(TFO)中,服务器端在收到客户端的初始连接请求(SYN包)时,会生成一个cookie,并将该cookie携带在返回给客户端的SYN-ACK包中。客户端收到SYN-ACK包后,会将服务器返回的cookie缓存在本地。
以下是第一次请求获取cookie值的全过程图:

在后续的连接请求中,客户端可以利用缓存的cookie直接发送给服务器,从而减少握手次数。以下是使用缓存的cookie值开始快速传输数据的流程图示例:

TCP Fast Open的优势

快速打开(TFO)在TCP协议中的一个最显著的优点是可以利用握手去除一个往返 RTT。当服务器收到带有TFO cookie的连接请求时,可以直接使用该cookie进行验证,而无需进行完整的三次握手过程。这样可以极大地减少了连接建立的时间,提高了网络性能和响应速度。
此外,TFO还可以有效地防止SYN-Flood攻击等恶意行为。通过使用TFO技术,服务器可以在接收到带有TFO cookie的连接请求时,直接验证cookie,并将请求放入半连接队列,而不会消耗服务器资源进行完整的三次握手。这样可以有效地减轻服务器的负载,并且只有合法的连接请求才能通过验证,从而防止了SYN-Flood攻击等恶意攻击。
TCP报文中的时间戳有什么作用?

TCP Timestamps Option是由四个主要部分构成的。这四个部分分别是类别(kind)、长度(Length)、发送方时间戳(TS value)和回显时间戳(TS Echo Reply)。其中,发送方时间戳和回显时间戳被认为是该选项中最重要的两个字段。

TCP 的时间戳主要解决两大问题
计算往返时延 RTT(Round-Trip Time)

在启用Timestamps选项之后,由于ACK包中包含了TSval和TSecr,因此无论是正常的确认包还是重传的确认包,都可以通过这两个值来计算出往返时间(RTT)。这样一来,我们可以更准确地估算网络的延迟情况。
防止序列号的回绕问题
TCP的序列号使用32位来表示,因此在传输了232字节的数据之后,序列号会发生溢出并重新开始计数。为了解决这个问题,TCP引入了窗口缩放选项,可以将窗口大小最大扩展到1GB(230),这样在高速网络中,序列号可以在很短的时间内被重复使用,从而更好地支持高速数据传输。

假设我们发送了6个数据包,每个数据包的大小为1GB。在这个过程中,由于序列号的回绕,第5个包的序列号与前面要发送的包序列号完全相同。同时,第2个包由于某些原因延迟导致需要进行重传,直到时间t7才到达。如果没有一些措施进行区分,这个阻塞数据包会导致数据的紊乱。
然而,由于存在Timestamps,我们可以通过TSval和TSecr来区分阻塞数据包与第6个包。通过比较这两个值,我们可以确定数据包的先后顺序,从而避免数据的混乱。因此,Timestamps的存在对于解决这种情况非常重要。
总结
通过本文的讨论,我们对TCP协议的一些重要细节有了更深入的了解。首先,我们了解到为什么SYN/FIN包需要消耗一个序列号,这是为了保证TCP连接的可靠性和数据的顺序。其次,我们探讨了半连接队列和SYN Flood攻击,了解了它们在TCP连接建立和安全性方面的作用。然后,我们学习了TCP快速打开(TFO)的原理和优势,它可以减少连接建立时间,并有效防止恶意攻击。最后,我们了解了TCP报文中的时间戳的作用,它可以帮助计算往返时延和解决序列号回绕问题。通过对这些细节的了解,我们可以更好地理解和应用TCP协议,提高网络性能和安全性。
以上只是一篇关于TCP协议的面试文章的一小部分内容。后续将会提供更多有针对性的面试题,以深入探讨TCP协议的相关细节。
🔥🔥你以为你了解TCP协议?这些你可能不知道的细节才是关键!的更多相关文章
- TCP协议学习总结(中)
很多人都说TCP协议是一个十分复杂的协议,在学习当中,我对协议每一个问题都分解学习后,每一个分解我都能体会和理解它的要点,并不难理解.但我把这些拆分的细节合并后,确认感觉这样一个协议相对“臃肿”但又好 ...
- TCP协议学习
一.TCP参考模型 VS OSI参考模型 二.TCP/IP分层模型的四个协议层分别完成以下的功能 第一层 网络接口层 网络接口层包括用于协作IP数据在已有网络介质上传输的协议.实际上TCP/IP标准 ...
- 【转】TCP协议
TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的.可靠的. 基于IP的传输层协议.TCP在IP报文的协议号是6.TCP是一 ...
- 闲来无事,写个基于TCP协议的Socket通讯Demo
.Net Socket通讯可以使用Socket类,也可以使用 TcpClient. TcpListener 和 UdpClient类.我这里使用的是Socket类,Tcp协议. 程序很简单,一个命令行 ...
- 简单测试nginx1.90做TCP协议负载均衡的功能
最近工作中需要做TCP层面的负载均衡,以前网站用的反向代理nginx只支持应用层的负载均衡,对于TCP协议是无能为力的,需要使用LVS(linux虚拟服务器). LVS的特点是高性能和极复杂的配置.对 ...
- TCP协议
TCP是一个面向连接的协议,在发送数据之前,必须在双方之间建立一条连接. TCP首部 TCP数据封装在IP数据报中 TCP包首部 下面简单说明部分字段的作用: 端口号:通讯双方由IP地址和端口号标识. ...
- TCP协议的三次握手和四次挥手
暂时需要的信息有: ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1 SYN(SYNchronization) : 在连接建立时用来同步序号.当SYN= ...
- TCP协议三次握手和四次挥手
http://www.cnblogs.com/rootq/articles/1377355.html TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对 ...
- ZeroMQ接口函数之 :zmq_tcp – 使用TCP协议的ØMQ网络单播协议
ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq-tcp zmq_tcp(7) ØMQ Manual - ØMQ/4.1.0 Name zmq_t ...
- C#网络编程之---TCP协议的同步通信(二)
上一篇学习日记C#网络编程之--TCP协议(一)中以服务端接受客户端的请求连接结尾既然服务端已经与客户端建立了连接,那么沟通通道已经打通,载满数据的小火车就可以彼此传送和接收了.现在让我们来看看数据的 ...
随机推荐
- 【技术积累】JavaScript中的基础语法【一】
Math对象 JavaScript中的Math对象是一个内置的数学对象,表示对数字进行数学运算的方法和属性的集合. Math对象不是一个构造函数,所以不能使用new关键字来创建一个Math对象的实例. ...
- Int64针对32位架构是按照4字节还是8字节对齐?
作为构建.NET的标准,CLI Spec(ECMA-335)针对基元类型的对齐规则具有如下的描述.按照这个标准,我们是这么理解的:8字节的数据类型(int64.unsigned int64和float ...
- 路由分发admin源码
1. 不使用include方法 1.表象 另一种路由编写方式,不用使用include 引出namespace概念 可以看到如果使用include方法,后面可带上一个参数赋值给namespace 在无n ...
- 2021-7-6 new tcpip
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Ne ...
- 一文了解react中定义样式(css/less/sass)的常用方法
react中通过jsx的语法方式,将html标签和js语法联系在一起,而css的编写方式,没有明确的指定编写方式,目前就有很多不同方法,每个方式各有其优缺点,我们一起来看看常用的定义方式有哪些. 最基 ...
- SpringBoot3文件管理
目录 一.简介 二.工程搭建 1.工程结构 2.依赖管理 三.上传下载 1.配置管理 2.上传下载 四.Excel文件 1.Excel创建 2.Excel读取 3.解析监听 4.导入导出 五.参考源码 ...
- Java基础实现加油站圈存机系统
加油站圈存机系统 对于加油卡而言,圈存是将用户账户中已存入的资金划转到所持的加油卡上后方可使用.通俗一点的说法就是您在网点把钱存入主卡中,再分配到下面的副卡,由于副卡都在使用车辆的驾驶员手中,需要 ...
- 【升职加薪秘籍】我在服务监控方面的实践(8)-elasticsearch 性能监控与分析手段
大家好,我是蓝胖子,之前讲了mysql,redis中间件的监控,今天我们再来看看另一个基础组件elasticsearch,如何对它进行监控,当你思考如何对一个组件进行监控时,四大黄金指标会告诉你答案, ...
- 图解 LeetCode 算法汇总——链表
本文首发公众号:小码A梦 一般数据主要存储的形式主要有两种,一种是数组,一种是链表.数组是用来存储固定大小的同类型元素,存储在内存中是一片连续的空间.而链表就不同于数组.链表中的元素不是存储在内存中可 ...
- 正则表达式快速入门一:正则表达式(regex)基本语法及概念
Regex quickstart :正则表达式快速入门 author: wclsn reference quick start 如果想要了解正则表达式的基本概念且英文ok的话,完全可以从我上面所附网站 ...