参考博客:https://blog.youkuaiyun.com/qq_38950316/article/details/81087809
三次握手
各个字段的作用:
字段 | 作用 |
---|---|
序列号seq | 用来标记数据段的顺序每发送一次序列号加一 |
确认号ack | 只指期望收到对方下一个报文的第一个数据字节的序号 |
确认ACK | 仅当ACK=1的时候确认号才有效,否则无效 |
同步SYN | 连接建立时用于同步序号 |
终止FIN | 用来释放一个连接,FIN=1表示此报文段的发送方的数据已经发送完毕,要求释放运输连接 |
对字段的个人理解
- seq其实就是每次发送数据的序号,每发一次加1;
- ack意思是我希望你下次发给我的序号(seq)是多少,也就是当前的seq+1;
- SYN表示的是请求连接或者接收报文,只有在连接过程中SYN=1;
握手的过程
- 第一次握手:客户端向服务端发送一个含有同步序列号SYN和seq的数据段,向服务端请求建立连接;告诉服务端“我想连接你,如果你允许,你下次就用确认号为ack=seq+1的数据段来回应我”
- 第二次握手:服务端收到客户端的请求,用一个确认ack=seq+1、同步序列号SYN标志位、和服务端的序列号seq=y的数据段响应客户端,告诉客户端“我已经收到了你的请求,你可以传输数据了,你下次要用确认号ack=y+1来回应我”;
- 第三次握手:客户端收到数据段,再发送一个确认应答“我已经收到了你的回复,我现在要开始传数据了”;
四次挥手:
第一次:客户端完成数据传输,将控制位FIN置1,序列号为u(上一次数据序列号+1),发送给服务器提出停止TCP连接的请求;(数据传输完了可以停止了吗?)然后进入FIN_WAIT1状态;
第二次:服务端收到FIN后对其作出相应(你得请求我收到了,但是我还没有准备好,请继续等我的消息),服务器进入CLOSE-WAIT状态(半关闭状态),这时候客户端收到消息就进入了FIN_WAIT2状态继续等待。
第三次:服务端准备就绪,给客户端发送(我已经准备好了,准备关闭连接);
第四次:客户端怕服务端不知道要关闭就送ACK后进入TIME_WAIT状态,服务端收到后立即进入CLOSE状态,而客户端在等待2msl后依然没有收到回复,则证明服务端已正常关闭,客户端接下来也关闭。
为什么连接的时候是三次握手,关闭的时候确是四次?
因为连接的时候,服务端收到请求后直接以SYN+ACK报文来回应,说明你可以连接了;
断开的时候服务端要做好准备,得先回应一个ACK说我知道了等我准备好了再告诉你,然后等服务端准备好之后又发送FIN表示我已经准备好释放连接了。所以断开的时候服务端比在连接的时候多发了一次。
为什么TIME_WAIT状态需要经过2MSL(最大报文时间)才能返回CLOSE状态?
因为有可能client发送的最后一个ACK会丢失,如果server没有收到这个ACK则不断地发送FIN字段,假设server没有收到,ACK发送过去最长MSL时长,FIN回应过来最长MSL时长,如果等到MSL+MSL=2MSL还还没有收到FIN就说明server没有发送FIN,他已经收到了ACK,所以要等待2MSL再关闭。