1 .TCP三次握手(重点)
1.1 TCP报文字段详细说明
1. 【源端口】 ---字段说明(占用16bit,即2个字节),表示网络访问来源处的端口号,即指定了发送端的端口。
2. 【目的端口】---字段说明(占用16bit,即2个字节):表示网络访问目的处的端口号,即指定了接受段的端口号。
说明:由上面可以看出,源端口和目标端口都是占用了16bit/2字节,因此也可以通过计算得知源目标端口范围是2的16次方=65536。
3. 【序列号】---字段说明(占用32bit,即4字节):每一个TCP报文段都会有一个序号,序号字段的值其实是本报文段所发送的数据的第一个字节的序号。这是因为TCP是面向连接的可靠服务,其每一个字节都会对应一个序号,通过序号来确保服务的可靠性和有序性。标识数据包传输的顺序,便于数据包拆分后,进行重新组装。
4. 【确认号】---字段说明(占用32bit,即4字节),确认号是期望收到对方的下一个报文段的数据的第一个字节的序号。简单理解就是发送端发送一个seq序列号x,接收端需要回复一个确认号x+1;并发送一个序列号Y,发送端接收一个seq序列号Y,接收端需要回复一个确认号y+1。
5. 【数据偏移】---字段说明(占用4bit):其实他本质上就是“首部长度”,因为“数据偏移”是指TCP报文段的数据部分的起始处距离TCP报文段的起始处的距离,数据偏移总共占用4bit,因此最大能表示的数值为15,而数据偏移的单位是“4字节”。
置位概念:根据TCP的包头字段,存在三个重要的标识ACK SYN FIN
-
ACK:位数字为1,表示确认收到发送请求,表示确认位。
-
SYN :位数字为1,表达式建立TCP连接。
-
FIN:数字为1,表示断开TCP连接。
-
TCP三次握手建立过程简单说明:
1) 由主机A发送建立TCP连接的请求报文,其中报文中包含seq序列号,是由发送端随机生成的,并且还将报文中SYN字段置位1,表示需要建立TCP连接请求。
2) 主机B会回复A 发送的TCP连接请求报文,其中包含seq序列号,也是由回复段随机生成的,并且将回复报文的SYN字段置1,而且会产生ACK验证字段,ack验证字段数值是在A发过来的seq序列号基础上加1进行回复;并且还会回复ack确认控制字段,以便A收到信息时,知晓自己的TCP建立请求已得到确认。
3) A端收到B端发送的TCP建立请求后,会使自己的原有序列号加1进行再次发送序列号,并且再次回复ACK验证请求,在B段发送过来的seq基础上加1进行回复;同时也会回复ack确认控制字段以便B收到信息时,知晓自己的TCP建立请求已经得到了确认。
1.3 TCP三次握手状态转换说明:
-
首先,建立连接之前的服务器和客户端的状态都为CLOSED。
-
服务器创建socket后开始监听,变为LISTEN状态。
-
客户端请求建立连接,向服务器发送SYN报文,客户端的状态变为SYN_SENT。
-
服务端收到客户端的报文后向客户端发送ACK和SYN报文,此时服务器的状态变为SYN_RCVD。
-
然后,客户端收到ACK,SYN,就向服务器发送ACK,客户端状态变为ESTABLISHED。
-
服务器收到客户端的ACK后也变为ESTABLISHED。
此时3次握手完成,连接建立。
2 TCP四次挥手过程(重点记忆)
2.1 TCP四次挥手状态转换简单说明:
由于tcp连接时全双工的,断开连接会比建立连接麻烦点。
-
客户端先向服务器发送FIN报文,请求断开连接,其状态变为FIN_WAIT1。
-
服务端收到FIN后向客户端发送ACK,服务器状态变为CLOSE_AWIT。
-
客户端收到ACK后就进入FIN_WAIT2的状态,此时连接已经断开了一半,如果服务器还有数据要发送给客户端,就会继续发送。
-
直到发送完了,就发送FIN报文,此时服务器就进入LAST_ACK状态。
-
客户端收到服务器的FIN后,马上发送ACK给服务器,此时客户端进入TIME_WAIT状态,再过了2MSL时间后进入CLOSED状态,服务器收到客户端的ACK就进入CLOSED状态。
1. 2MSL介绍
主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime
(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。
MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒,因而,TIME_WAIT状态一般维持在1-4分钟。
2. time_wait状态作用说明
TIME_WAIT状态存在的理由:
1)可靠地实现TCP全双工连接的终止
在进行关闭连接四路握手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN。
因此客户端必须维护状态信息允许它重发最终的ACK。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误(在java中会抛出connectionreset的SocketException)。
因而,要实现TCP全双工连接的正常终止,必须处理终止序列四个分节中任何一个分节的丢失情况,主动关闭的客户端必须维持状态信息进入TIME_WAIT状态。
2)允许老的重复分节在网络中消逝
TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后 也会被送到最终目的地,这个原来的迷途分节就称为lost duplicate。
在关闭一个TCP连接后,马上又重新建立起一个相同的IP地址和端口之间的TCP连接,后一个连接被称为前一个连接的化身 (incarnation),那么有可能出现这种情况,前一个连接的迷途重复分组在前一个连接终止后出现,从而被误解成从属于新的化身。
为了避免这个情况,TCP不允许处于TIME_WAIT状态的连接启动一个新的化身,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个TCP连接的时候,来自连接先前化身的重复分组已经在网络中消逝。
图1-1 TCP11种状态集转换图