TCP为什么采用三次握手,而不是两次握手?
防止两次握手情况下已失效的连接请求报文段突然由传送到服务器端,而产生错误。如:客户端C向服务端S发出TCP连接请求,第一个连接请求报文在网络的某个结点长时间滞留,C超时后认为报文丢失,于是重传一次连接请求,B收到后建立连接。数据传输完毕后双方断开来连接。而此时,前一个滞留在网络中的连接请求到达服务端S,而S认为C又发来连接请求,此时若是使用“三次握手”,则B向A返回确认报文段,由于是一次失效的请求,因此C不予理睬,建立连接失败。若采用“两次握手”,则这种情况下S认为传输连接已经建立,并一直等待A传输数据,而此时A并无连接请求,因此不予理睬,这样就造成了B的资源白白浪费了。
C发送连接请求报文给S,因为延时,C没收到响应,重发连接请求,这次连接建立成功,然后 之前的连接建立请求到达S,如果是三次握手,客户端已建立连接,会忽略服务端的连接响应,如果是两次握手,那么会认为连接连接成功,这时序列号又重刚开始的 序列号开始发送(之前成功建立的连接之后,序列号已经不是初始的序列号了,序列号错乱)。
TCP最后一次握手报文为什么要等待2MSL(最长报文段寿命)的时间?
1. 为了保证C发送的最后一个报文段能够到达S。如果C不等待2MSL,若C返回的最后确认报文段丢失,则S不能进入正常 关闭状态,而C此时已经关闭了,也不能重传。
2. 防止出现“已失效的报文段”去骚扰服务器。
2MSL( Maximum Segment LifeTime)
以应对最坏的情况发生,这个最坏情况是:
去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)。
这恰恰就是2MSL( Maximum Segment LifeTime)。
概念:MSL是报文在网络中最长生存时间,这是一个工程值(经验值),不同的系统中可能不同。
场景:
1. A发出ACK后,等待一段时间T,确保如果B重传FIN自己一定能收到
分析:
1. ACK从A到B最多经过1MSL,超过这个时间B会重发FIN
2. B重发的FIN最多经过1MSL到达A
结论:如果B重发了FIN,且网络没有故障(重发的FIN被丢弃或错误转发),那么A一定能在2MSL之内收到该FIN,因此A只需要等待2MSL。
SYN = 1,ACK = 0 表示这是一个连接请求报文
SYN = 1,ACK = 1 表示这是一个连接接收报文。
ack = N 表示期望收到对方的下一个报文段的数据的第一个字节的序号。若ack=N,则表明序号N-1为止的所有数据已正确收到。
只有ACK = 1 时 ack 才有效。
seq = x,表明本报文段所发送的数据的第一个字节序号是x.
FIN=1 表明此报文段的发送方的数据已发送完毕,并释放传输连接
————————————————————————————————————————————————————————
TCP报文字段:
1,源端口和目的端口 各占2字节。端口是运输层和应用层的接口
2,序号字段seq 占4个字节。
3,确认号字段ack 占4个字节
4,确认位ACK 在连接建立后所有传送的报文段必须把ACK置为1
5,同步位SYN SYN=1表明这是一个连接请求或连接接收报文
6,终止位FIN FIN=1 表明此报文段的发送方的数据已发送完毕,并释放传输连接