TCP的三次握手与四次挥手

TCP协议详解
本文深入解析TCP协议,涵盖其基本概念、报文格式、三次握手与四次挥手的详细流程,探讨为何需要三次握手建立连接及四次挥手断开连接,揭示SYN超时隐患与保活机制。

TCP简介

面向连接的、可靠的基于字节流的传输层通信协议
将应用层的数据流分割成报文段发送给目标节点的TCP层
数据包都有序号,对方收到则发送ACK确认,未收到则重传
使用校验和来校验数据传输过程中是否有误

TCP报文格式

源端口:源端口和IP地址的作用是标识报文的返回地址。
目的端口:指明接收方计算机上的端口
TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。

序号和确认号:是TCP可靠传输的关键部分。序号是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序号。例如:一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。确认号,即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。

数据偏移/首部长度:4bits。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。

保留:为将来定义新的用途保留,现在一般置0。

控制位:URG ACK PSH RST SYN FIN,共6个,每一个标志位表示一个控制功能。
1)URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。
2)ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。
3)PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。
4)RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。
5)SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。
6)FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。

窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,因而窗口大小最大为65535。

校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。

紧急指针:只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。

选项和填充:最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。

数据部分: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

三次握手流程

第一次握手:客户端发送一个SYN包(syn=j)给服务端,同时自身进入SYN_SEND状态,等待服务端确认

第二次握手:服务端收到客户端发送的SYN包,向客户端发送一个确认ACK(ack=j+1)同时发送自己的SYN包(syn=y),即发送一个ACK包和一个SYN包,自身进入SYN_RECV状态

第三次握手:客户端收到服务端发送的SYN+ACK包,向服务端发送一个ACK包(ack=y+1),客户端与服务端进入ESTABLISHED状态,连接建立成功

为什么要三次握手才能建立起连接

为了初始化sequece Number的初始值

首次握手的隐患——SYN超时

问题起因:
服务端收到客户端的SYN,回复ACK+SYN时未收到ACK确认
服务端不断重试直到超时,Linux默认等到63秒才断开连接
第一次2秒每次为前一次的两倍,第五次等待结束后断开连接
针对SYN Flood的防范措施:
SYN队列满后通过tcp_syncookies参数回发SYN Cookie
若为正常连接,客户端会回发SYN Cookie,直到建立连接

建立连接后,客户端出现故障怎么办

保活机制
向对方发送保活探测报文,若未收到回应则继续重试
尝试次数达到保活探测数仍未收到响应则断开连接

四次挥手的流程

双方都可主动关闭连接,我们以客户端主动关闭连接为例:
第一次挥手:客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1状态

第二次挥手:服务端收到FIN收,向客户端发送一个ACK(序号为收到序号+1),服务端进入CLOSE_WAIT状态

第三次挥手:服务端发送一个FIN,用来关闭服务端到客户端的数据传送,服务端进入LAST_ACK状态

第四次挥手:客户端收到FIN后,进入TIME_WAIT状态,同时发送一个ACK给服务端,序号为服务端发送的FIN号+1,服务端接收到后进入CLOSED状态,完成四次挥手,客户端在等待2MSL的时间后进入CLOSED状态

为什么需要TIME_WAIT状态

为了确保有足够的时间让对方收到ACK包
避免新旧连接混淆

为什么需要四次挥手断开连接

因为全双工,发送方和接收方都需要FIN和ACK

服务器出现大量CLOSE_WAIT的原因

客户端一直在请求,但返回给服务端的信息是异常的
对方关闭连接时,我方忙于读和写,没有关闭连接
当出现大量的CLOSE_WAIT时,新的请求无法被处理,极有可能造成服务器的崩溃

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值