TCP数据包格式:
TCP数据包中没有标识数据大小的字段,这个字段定义在IP首部中了。
TCP首部长度最小是20字节,最大是60字节,首部长度就定了偏移量,标识了TCP首部的大小
TCP流量控制是由连接的每一端通过声明窗口大小来提供的,这个值是16比特,所以最大是65535字节。
校验和覆盖了整个TCP报文段,首部和数据,这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证。
只有当URG标志设置为1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。
最常见的可选字段是 最长报文大小,又称为MSS(Maximun Segment Size)。每个连接方通常都在通信的第一个报文段(SYN包)中指明这个选项,它指明本端所能接收的最大长度的报文段。
比如A的MTU为296字节,也就是以太网可以发送的包的最大大小,而B的MUT是1500字节,那么当双方建立连接时,A发送的SYN包就指明了MSS为256(296-40),而B的SYN包中指明了MSS为1460(1500-40)。此时使用较小一方的MSS,也就是256字节作为数据报文长度。
MSS默认值为536字节
TCP中的标识比特
他们中的多个可以同时被设置为1,含义如下
标志比特 | 含义 |
reserved | 未知 |
nonce | 未知 |
CWR | 流量控制 |
ECN | 拥塞窗口 |
URG | 紧急指针有效 |
ACK | 确认序号有效 |
PSH |
接收方应尽快将这个 报文段交给应用层 |
RST | 重建连接 |
SYN |
同步序号用来发起一个 连接 |
FIN |
发端完成发送任务 |
TCP的状态变迁图
TCP连接的建立,数据传输,以及关闭的过程
状态转换和连接建立关闭的对比图
分成三部分
1.连接的建立过程
2.数据的传输过程
3.连接的关闭过程
连接过程(三次握手)
这是由一个主动,一个被动的过程,客户端主动触发一个连接,服务端接收连接,最初客户端和服务端都处于CLOSED状态。
对于客户端来说,首先会发送一个SYN包,之后TCP状态就变为SYN_SENT,而当客户端收到服务端发来的ack+syn包时,对于客户端来说他已经确定了服务端收到了之前发送的SYN包了,所以客户端的TCP状态就变成了ESTABLISHED.
对于服务端来说,当调用listen()函数之后,就看以监听客户端的发来的SYN包了,当收到SYN包之后,服务端的TCP状态就变为TCP_RCVD,同时客户端还会向服务端发送一个syn+ack包,也就是服务端也要创建连接。最后当客户度收到这个syn+ack包后,最后会再发一个ack包给服务端,也就是TCP状态转换图中SYN-SEND状态指向SYN-RECEVED状态的箭头,也就是客户度最后的确认ack,当服务端收到这个ack后,连接就建立了,这样服务端的TCP状态也变为ESTABLISHED.
同时打开需要四次握手,双方都是主动方,都需要经历SYN_SENT和SYN_RCVD状态,最后变成ESTABLISHED状态。
数据传输过程
只有一种状态ESTABLISHED
关闭过程(四次握手)
这里分为主动关闭和被动关闭,还有双方同时关闭。
客户端发送fin包后,TCP状态就处于FIN_WAIT_1,如果收到服务端发来的ack确认后,状态就变为FIN_WAIT_2。之后客户端会等待服务端发送fin包,也就是等待服务端关闭。当收到服务端发来的fin包后,客户端会发送一个确认,此时客户端的状态就变为TIME_WAIT,等待2ML时间后,状态就变为了CLOSED。
对于服务端来说,收到客户端发来的fin包后,状态就变为CLOSE_WAIT,也就是被动关闭,同时会发送一个ack确认给客户端。之后服务端也会发送一个fin包给客户端,表示关闭连接,之后状态就变成了LAST_ACK,此时服务端会等客户端发送最后一个确认ack,当收到后服务端就会关闭连接,状态就变为CLOSED。
同时关闭是双方都是主动关闭,双方都发送了一个fin包。客户端主动关闭发送fin包后,变成FIN_WAIT_1状态,此时又收到了一个fin包,于是状态变为CLOSING,同时再发送一个确认包ack给对方。而当收到对方对fin包的确认后,状态变成了TIME_WAIT,等待2ML时间后,连接关闭,变为CLOSED状态,对于服务端来说情况是一样的就不在阐述了。
同时关闭的状态图
2MSL等待时间
主动关闭时收到fin包的确认ack后就处于TIME_WAIT状态,此时需要等待2倍的MSL时间(Maximum Segment Lifetime)。他是任何报文段被丢弃前在网络内的最长时间。TCP报文是以IP数据报在网络内传输的,而IP数据报限制生存时间是基于TTL字段,TTL并不是定时器而是基于跳数。
2MSL存在的原因有:
1)确认被动方已经收到了ack,如果对方没有收到ack,则又会发送一个fin,这样一个来回就是2MSL时间了
2)等待足够长的时间让这个连接的报文不会跟后面新建的连接报文混在一起
通过Wireshark抓包分析连接的建立和关闭过程
表达式为:
(ip.dst_host==61.135.169.105 and ip.src_host==192.168.0.100) or (ip.dst_host==192.168.0.100 and ip.src_host==61.135.169.105)
详细看一下连接的建立过程,首先是客户端发送一个SYN包
此时的只有一个序列号,没有确认序列号,序列号是1735627764
另外在可选项中有一个MSS,设置为1460,还有一个SACK。
服务端收到SYN包后,发送SYN+ACK包
此时服务端的序列号是1533877802,同时对客户端的序列号进行了确认,也就是序列号+1,所以ack是1735627765
服务端的MSS设置为1440,所以使用两者中较小的一个MSS,也就是1440字节。
最后客户端回一个ack包给服务端
应答的ack是服务端序列号+1,所以ACK就是1533877803
双方关闭连接的四次握手TCP包都没有数据,包头都是20字节,通过Wireshark的抓图就能看出来,这里就不再描述了。
超时重传
TCP连接第一次发送SYN后经过了3秒都没有收到ACK包,又发了第二个包等了6秒还没收到又发了第三个包。
这里可以看到发送的时间是依次成倍增长的。
《TCP/IP详解》里面超时时间第一次是接近6秒,然后是若干个24秒,这里可能是不同操作系统导致的超时发送时间不同。
如果是连接一个无法ping通的ip地址,出现的结果也是一样的。
连接的半关闭
可以看到,客户端关闭输出流之后,发送一个fin包,服务端也响应了这个fin包做了ack回应,但是之后连接并没有关闭,服务端可以继续发送数据,客户端也可以读取数据并响应ack。
连接的复位
客户端按下ctrl+c后触发了一个RST,导致服务端断开连接
异常终止对程序来说有两个优点:
1.丢弃任何代发数据并立即发送复位报文段
2.RST的接收方会区分另一端执行的是异常关闭还是正常关闭。应用程序使用的API必须提供产生异常关闭
而不是正常关闭的手段
TCP选项SO_LINGER提供了这种异常关闭的能力,如果设置为0,导致连接关闭时进行复位而不是正常的
FIN包。如果设置了这个功能,表示在关闭前会把残留的数据返回给发送方,如果等待指定的时间还没有
完成则关闭。
SO_LINGER的结构体如下:
struct linger { int l_onoff; /* 0 = off, nozero = on */ int l_linger; /* linger time */ };有下列三种情况:
1.设置 l_onoff为0,则该选项关闭,l_linger的值被忽略,等于内核缺省情况,close调用会立即返回给调用者,如果可能将会传输任何未发送的数据;
2.设置 l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
3.设置 l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完且被对方确认,之后进行正常的终止序列(描述字访问计数为0)或(b)延迟时间到。此种情况下,应用程序检查close的返回值是非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。close的成功返回仅告诉我们发送的数据(和FIN)已由对方TCP确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为非阻塞的,它将不等待close完成。
TCP选项
格式如下
kind(1字节) | len(1字节) | 内容 |
kind表示选项的类型
len表示一个类型的选项占多少字节
内容就是该选项的内容
比如MSS选项如下:
kind=2 | len=4 | 最大报文段长度(2字节) |
kind一个字节,len一个字节,MSS内容2个字节,所以len=4。
各种选项类型如下:
kind 类型 | 含义 |
0 | 选项表结束 |
1 |
无操作(用作字节 对其填充) |
2 | 最大报文段长度 |
3 | 窗口扩大因子 |
4-7 | SACK相关 |
8 | 时间戳 |
连接的限制
本地地址 | 远端地址 | 描述 |
local.port | foreign.port |
限制到一个客户进程 |
local.port | *.* |
限制为达到一个本地端口 local的连接 |
*.port | *.* | 接受发往port的所有连接 |
请求连接队列
1)正等待连接请求的一端有一个固定长度的连接队列,该队列的连接已被TCP接受(完成三次握手),但还没有被应用层接受
2)应用层将指明该队列的最大长度,这个值通常被称为积压值(backlog)
3)当一个连接请求(SYN)达到时,TCP使用一个算法,根据当前连接队列中的连接数来确定是否接受这个连接。 backlog说明的是TCP监控的端口已被TCP接受而等待应用层处理的最大连接数。这个值对系统所允许的最大连接数 ,或者服务器锁能处理的并发数无影响。
4)如果对于新的连接请求,该TCP监控的端点的连接队列中海油空间,TCP模块将对SYN进行确认并完成连接的建立。另外客户端主动打开成功但服务端的应用层还不知道这个新连接时,它可能任务服务器进程已经做好准备接受数据了(如果发生这种情况,服务器的TCP仅将接受的数据放入缓冲区)
5)如果对于新的连接请求,连接队列中已没有空间,TCP将不理会接受的SYN,也不发回任何报文(即不发回RST),如 果应用层不能及时接受已被TCP接受的连接,这些连接可能占满整个连接队列,客户端主动打开最终将超时。
参考:
一站式学习Wireshark(一):Wireshark基本用法
一站式学习Wireshark(二):应用Wireshark观察基本网络协议
一站式学习Wireshark(三):应用Wireshark IO图形工具分析数据流
一站式学习Wireshark(四):网络性能排查之TCP重传与重复ACK
相关推荐
TCP连接建立与终止过程剖析,非常详细的讲解了TCP连接建立与终止的所有不同的情况,推荐大家阅读
当服务器收到这个ACK后,也进入ESTABLISHED状态,至此,TCP连接建立完成。 TCP连接的终止则相对复杂,因为需要确保双方都已经知道对方不再发送数据。过程如下: 1. **FIN(结束)**:当一方完成数据传输,想要关闭...
以下是TCP连接建立的详细步骤: 1. 主动方(通常是客户端)向被动方(服务器)发送一个SYN(Synchronize Sequence Numbers)报文段,其中包含一个随机的序列号x。此时,TCP进入SYN_SENT状态。 2. 被动方接收到SYN...
在上述例子中,我们可以看到R1、R2和R3三个路由器之间的TCP连接建立过程。R1路由器配置了access-list 101,允许R2路由器访问R3路由器,但拒绝R3路由器访问R2路由器。我们使用debug ip packet detailed命令来监视报文...
"Window下杀掉TCP连接"这个话题涉及到的是如何管理和终止系统中的TCP(传输控制协议)连接。TCP是互联网协议的一部分,负责在两台设备之间建立可靠的数据传输通道。以下是一些关于在Windows中关闭TCP连接的重要知识...
TCP/IP的三次握手和四次挥手是理解TCP连接建立和终止的关键过程。三次握手指的是在建立连接时,客户端和服务器之间进行的一系列通信步骤,以确认双方的接收和发送能力;四次挥手则是断开TCP连接时双方进行的确认和...
1. **TCP连接建立** - 通常被称为“三次握手”(Three-Way Handshake)。在TCP连接开始时,客户端(Source Port)发送一个SYN(同步序列编号)包给服务器(Destination Port),其中包含了随机生成的初始序列号ISN。...
"018 TCP连接的建立与终止.PDF"详细阐述了三次握手和四次挥手的过程,这是TCP连接建立和终止的标准步骤,确保了数据传输的可靠性和顺序性。"019 TCP的交互数据流.PDF"则讨论了TCP如何通过滑动窗口机制来实现高效的...
然而,操作系统通常会对同一时间可建立的TCP连接数进行限制,这是为了防止资源耗尽和系统崩溃。这个限制可能在某些需要大量并发连接的场景下成为瓶颈,比如大数据抓取、负载测试或分布式计算。"破解TCP连接数限制"这...
这款工具可以帮助用户实时查看所有正在运行的进程与哪些远程主机建立了TCP连接,以及这些连接的状态、端口号等详细信息。在IT行业中,了解和掌握TCPView的使用对于网络故障排查、性能优化以及安全监控都有着重要的...
此外,TCPView还允许用户结束某个连接或终止关联的进程,这对于调试和故障排除非常有用。 压缩包中的文件包含TCPView的用户手册(tcpview.chm)、可执行文件(Tcpview.exe和Tcpvcon.exe),帮助文件(TCPVIEW.HLP)...
### TCP连接建立与终止的深度解析 #### 一、TCP连接建立:三次握手 TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,在计算机网络中广泛使用。TCP连接的建立是通过三次握手来完成的,...
此外,著名的三次握手和四次挥手过程是TCP连接建立和终止的标准流程,它们确保了连接的可靠建立和安全关闭。三次握手防止了旧的数据在新的连接中被误接收,而四次挥手则确保了数据的完全传输和无干扰的断开连接。 ...
TIME_WAIT 状态的存在是为了确保 TCP 连接的可靠终止和允许老的重复分节在网络中消逝。 了解 TCP 连接状态是非常重要的,因为它可以帮助我们更好地理解 TCP 协议的工作机理,并更好地解决网络连接问题。
在实验中,使用Ethereal网络分析软件观察了TCP数据包和连接建立的过程,例如第14个分组展示了TCP数据包的详细信息,包括源端口80(HTTP服务)、目的端口1222、数据长度、确认号等。而TCP连接的建立通过“flow graph...
本实验旨在利用Wireshark这一强大的网络协议分析工具,深入探索TCP连接建立(三次握手)和连接释放(四次挥手)的过程,并通过实际操作加深对TCP协议的理解。 #### 实验原理 TCP协议是一种面向连接的、可靠的、...