TCP的三次握手与四次挥手
TCP的三次握手与四次挥手
三次握手
第一条: 客户端发送的连接请求报文段, 该报文段特点: 无应用层数据.
SYN=1: SYN = 1时, 代表他是一个连接请求或者连接请求接受
seq=x(随机): seq是报文段第一个字节的序号, 序号为占了32位, (也就是占了4个字节), 序号位是由主机内部随机产生的, 可以从任意随机数开始.
对于确认号ack在这里是没有意义的, 因为在这一条里, 客户端是不会收到服务端发的报文段的. 所以此时确认位ACK = 0.
第二条: 服务端向客户端返回确认报文段, 允许连接, 该报文段特点: 没有应用层数据
SYN=1: 代表连接请求的确认.
ACK=1 / ack=x+1: 大写ACK与小写ack是搭配使用的. 有大写, 定有小写.
确认号ack: 期待对方接下来发送的报文段的第一个字节
x+1是指: 由于第一条没有数据部分, 因此, 序号seq的x就是报文段, 因此服务器端想要收到的下一个字节, 就应该是从x+1开始, 所以ack字段就设为x+1
seq=y(随机): 确认报文段的序号字节.
第三条: 客户端向服务器返回确认的确认, 该报文段特点: 可将预发送数据放到报文段中
SYN=0: 因为在连接请求 / 接受, SYN才 = 1, 其他情况都为0
SYN洪泛攻击:
三次握手只完成两次.
攻击者发送SYN, 当服务器返回ACK后, 该攻击者就不对其进行再确认, 那么这个TCP连接就处于挂起状态 (也就是半连接状态), 服务器收不到再确认, 会重发ACK给攻击者. 这样会浪费服务器的资源. 攻击者对服务器发送非常大量的这种TCP连接, 由于每一个都无法完成3次握手, 所以服务器会因为这些挂起状态而消耗资源(cpu, 内存等), 最后服务器可能死机 , 无法为正常用户提供服务.
解决办法: SYN cookie
四次挥手
第一条: 客户端发送连接释放报文段, 停止发送数据, 主动关闭TCP连接----- 告诉服务器我要断开连接了.
FIN=1: 请求释放连接
seq=u: 表示这样一个报文段第一个字节的序号, 通常这个报文段是没有数据的, 所以这样的序号也可以标示一个报文段.
第二条: 服务器端回送一个确认报文段, 客户到服务器这个方向的连接就释放了(半关闭状态)------回复客户端: 我收到你要断开连接的消息了
半关闭状态是指: 虽然客户端停止了发送数据, 但服务器还可以照样选择发送数据或者不发送数据.
ACK=1: 确认位置为1
seq=v: seq取决于最后一个报文段的最后字节的位置, 比如, 最后一个报文段的最后字节发送到v-1, 则seq=v
ack=u+1: 返回的是对于上一个报文段的确认, 期待客户接下来发送第一个字节为u+1的报文段, 客户端收到这样的报文段也不用给予回复, 因为现在客户端已经结束通话了, 客户端现在需要做的是等待服务器端告诉他: 我也结束了. 然后他俩的通话就正式关闭.
第三条: 服务器发完数据, 就发出连接释放报文段, 主动关闭TCP连接
FIN=1: 只要是连接释放请求, FIN都置为1
ACK=1: 确认位置为1,
ack=u+1: 确认号和第二条一样, 因为客户端在这样一段时间内没有发送任何数据, 所以服务器端所期待的报文段第一字节是相同的.
seq=w: 取决于第二条后, 也就是回复确认之后, 服务器端所发送的数据量的多少
第四条: 客户端回送一个确认报文段, 再等到时间等待计时器设置的2MSL(最长报文段寿命) 后, 连接彻底关闭.
客户端等待2MSL原因: 如果客户端发送的确认报文段没有到达服务器端, 丢失了, 那么收不到确认报文段的服务器就会重传第三条报文段给客户端, 这是客户端重新收到第三条后, 就重新启动2MSL计时器, 最后, 如果客户端与服务端都没发生丢失, 他俩就正常进入到关闭状态, 连接结束.
如果客户端不等待2MSL的时间, 而是在发送确认报文之后直接释放连接, 若第四条报文段丢失了, 客户端就收不到服务器重传的第三条报文段, 客户端也不会发送第四条, 那么服务端就无法正常关闭
冗余ACK
如果发送方收到3个冗余ack, 就会自己判定该冗余ack已经丢失
TCP流量控制 (滑动窗口)
控制发送方的发送速度, 若发送过快, 接受方没来得及接收, 就会产生丢包状态.
滑动窗口: 接收方根据自己接收缓存的大小, 动态调整发送方的发送窗口大小, 即: 接收窗口rwnd (接收方设置确认报文段的窗口字段来将rwnd通知给发送方), 发送方的发送窗口取决于接收窗口rwnd和拥塞窗口cwnd的最小值