【Linux网络编程】TCP的三次握手、四次挥手

TCP是传输层的主机对主机控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接。
三次握手

三次握手是俩台主机建立连接的过程,建立之前的初始状态是:client处于connect状态,server处于listen的状态。

  • 第一次握手:client主动发起SYN(syn = x)报文 ,此时client进入SYN_SENT状态,等待server确认。
  • 第二次握手:server收到SYN报文后对其进行确认(ack = x + 1),并发送自己的SYN报文(syn =y),此时server进去了SYN_RECV状态。
  • 第三次握手:cliet收到server的SYN+ACK包,向服务器发送确认包ACK(ack = y + 1 ),此包发送完毕,client&server都进入ESTABLISHED状态,完成三次握手。

————————————————————————————————————

四次挥手

四次挥手是俩台主机断开连接的过程,断开连接之前,俩台主机进行数据交互。客户端执行到close()时,发生四次挥手过程。

  • 第一次挥手:client向server发送请求断开连接的FIN(seq = x +2)报文,用来关闭client到server的数据传送,也就是client告诉server:我已经不会再给你发数据了(当然,在FIN报文之前发送出去的数据,如果没有收到对应的ack确认报文,client依然会重发这些数据)但是,此时client还可以接受数据(TCP是全双工通信)。
  • 第二次挥手:server收到client的请求断开连接的FIN报文后,发送ACK(ack = x + 3)进行确认,此时server进入CLOSE_WAIT状态。client进入FIN_WAIT2状态。
  • 第三次挥手:server向client发送自己的FIN报文(seq = y + 1),此时,server进入LAST_ACK状态。
  • 第四次挥手:client收到server发送的FIN报文后,求其发送ACK(ack = y + 2)进行最后的确认,此时client进入到CLOSE_WAIT状态。

三次握手,四次挥手示意图如下:
在这里插入图片描述

三次挥手哪个阶段容易出现攻击?

SYN_FLOOD攻击出现在第二阶段,客户端伪造大量的第一次连接SYN同步报文,使得服务器耗费资源去维护客户端信息,并进行确认,短时间内大量的SYN报文涌向服务器,造成服务器资源被耗尽,最终导致正常的客户段得不到响应而失败。

为什么要三次握手,俩次握手可以吗?
显然是不可以的,下面用反证法解释其不可以的缘由:

谢希仁版《计算机网络》描述了这样一个例子:“已失效的连接请求报文段”的产生在
这样一种情况下:client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采 用“三次握手”,那么只要 server发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server发送数据。但 server却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用“三次握手”的方法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。”。主要目的防止 server端一直等待,浪费资源。

TIME_WAIT存在的意义?
TIME_WAIT 状态是:主动关闭方收到被动关闭方的 FIN 报文段并且将 ACK 报文
段发出后的一种状态。

  • 保证迟来的报文段能被识别并丢弃。
  • 保证可靠的终止 TCP 连接。保证对端能收到最后的一个 ACK,如果 ACK 丢失,在TIME_WAIT状态本端还可以接受到对端重传的FIN报文段并重新发送ACK。 所以 TIME_WAIT 的存在时间为 2MSL。

TIME_WAIT 和 CLOSE_WAIT 有什么区别?

  • CLOSE_WAIT 是被动关闭方在接收到主动关闭方的关闭请求(FIN 报文段)并且将 ACK发送出去后所处的状态,这种状态表示:收到了主动关闭方的关闭请求,但是本端还没有完成工作,还未关闭。
  • TIME_WAIT 状态是主动关闭的一端在本端已经关闭的前期下,收到对端的关闭请 求(FIN 报文段)并且将 ACK发送出去后所处的状态,这种状态表示:双方都已经完成工作,只是为了确保迟来的数据报能被是被并丢弃,可靠的终止 TCP 连接。

TCP的报头是怎样的?
图片内容来源于《Linux高性能服务器编程》

32位序号( seq) :一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。假设主机A和主机B进行TCP通信,A发送给B的第-一个TCP报文段中,序号值被系统初始化为某个随机值ISN (Initial SequenceNumber,初始序号值)。那么在该传输方向上(从A到B),后续的TCP报文段中序号值将被系统设置成ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如,某个TCP报文段传送的数据是字节流中的第1025 ~ 2048 字节,那么该报文段的号值就是ISN+1025. 另外-一个传输方向(从B到A)的TCP报文段的序号值也具有相同的含义。
32位确认号(ACK) :用作对另- .方发送来的TCP报文段的响应。其值是收到的TCP报文段的序号值加1.假设主机A和主机B进行TCP通信,那么A发送出的TCP报文段不仅携带自己的序号,而且包含对B发送来的TCP报文段的确认号。反之,B发送出的TCP报文段也同时携带自己的序号和对A发送来的报文段的确认号。
四位头部长度:15个4字节,最大60个字节,固定部分20个字节,选项部分最多40个字节。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章