1.TCP报文
TCP报文是TCP层传输的数据单元,也叫报文段。
(1) 端口号:用来标识同一台计算机的不同的应用进程。
TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一一条TCP连接。
- 源端口:源端口和IP地址的作用是标识报文的返回地址。
- 目的端口:端口指接受计算机上的应用程序接口。
(2) 序列号与确认号:是TCP可靠传输的关键部分。序号是报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序列号。举例:一个报文段的序号为300,此报文数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。确认号ack,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志位1时才有效。比如建立连接时,SYN报文的ACK标志位置0。
(3) 数据偏移:由于首部可能含有可选项内容,因此TCP报头的长度时不确定的,报头不包含任何任选字段则长度位20字节,4位首都长度字段能表示的最大值位1111转化为10进制位15,15*32/8 = 60,故报头最大长度位60字节。报首长度也叫数据偏移,是因为部首长度实际上指示了数据去在报文段中的起始偏移值。
(4) 保留: 为将来定义新的用途保留,现在一半置0。
(5) 标志位:一共6个,每一个标志位表示一个控制功能。
- URG: 紧急指针标志,为1时表示,紧急指针有效,为0则忽略紧急指针。
- ACK:
acknowledgement
确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。 - PSH: push标志,为1表示是带有push标志的数据,指示接收方在接受到该报文段后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。
- RST: 重置连接标志,用于重置由于主机崩溃或其它原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。
- SYN:
synchronize
同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应带捎带一个确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。 - FIN:
finish
标志,用于释放连接,为1时表示已经没有数据发送了,即关闭本方数据流。
(6) 窗口:滑动窗口大小,用来告知发送端接收端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小是一个16bit位字段,因此窗口大小最大为65535。
(7) 校验和: 奇偶校验,此校验和是对整个的TCP报文段,包括TCP头部和TCP数据,以16位字进行计算所得。由发送端计算和存储,并由接收端进行验证。
(8) 紧急指针:只有当URG标志置1时紧急指针才有效。紧急指针式一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。
(9) 选项: 最常见的可选字段是最长报文大小,又称为MSS,每个连接方通常都在通信的第一个报文段(位建立连接而设置SYN标志位1的那个段)中指明这个选项,它表示本端能接收的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
(10) 数据部分: TCP报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文端仅有TCP首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文端。
2.三次握手
1)什么是三次握手
三次握手
:其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
三次握手的作用
:建立起一个安全可靠的连接
2)三次握手的过程
刚开始的时候,客户端处于Closed
的状态,服务端处于Listen
状态。
第一次握手
:客户端给服务端发送一个SYN报文
,并指明客户端的初始化序列号
ISN(Initialization sequence number)。首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗一个序号。
第二次握手
:服务器端收到客户端的SYN报文
之后,会给客户端发送一个SYN加ACK
的报文,同时还会初始化自己的序列号
ISN,并把客户端的序列号加1作为确认号ack
的值,表示自己已经收到了客户端的SYN报文
。在确认报文段中,SYN=1,ACK=1,确认号ack=x+1,序列号seq=y;
第三次握手
:客户端收到服务器端SYN报文
后,会发送一个ACK报文
,同时把服务器端的的序列号加1作为ack的值,表示已经收到了服务端的SYN报文
。确认报文段中ACK=1,确认号ack=y+1,序列号seq=x+1(初始为seq=x,第二报文段所以要加1),ACK 报文段可以携带数据,不携带数据则不消耗序号。
3)为什么两次不行?
- 只进行两次握手,不能确保客户端和服务器端都具有接收和发送能力的能力。两次握手之后,只能确认服务端有接收的能力,不能确认服务器端具有发送能力。
- 如果是两次握手,还会出现下面的这种情况:如果客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。重传的请求收到了,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释以后到某个时间才到达服务器,此时服务端误认为客户端又发出一次新的请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务器端发出确认,就建立新的连接了,此时客户端忽略服务器发来的确认,也不发送数据,则服务器一直等待客户端发送数据,浪费资源。
4)SYN洪泛攻击
SYN洪泛攻击
发生在OSI第四层(传输层)
,这种方式利用TCP协议的特性,就是三次握手,攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP连接就处于挂起的状态,也就是所谓的半连接的状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。这样更加浪费服务器的资源,攻击者就对服务器发送非常大量的这种TCP连接,由于每一个都没办法完成三次握手,所以在服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机,就无法为正常用户提供服务了。
3.四次挥手
1)四次挥手的过程
开始双方都处于ESTABLISHED
状态,假设
是客户端先发起关闭请求。
第一次挥手
:客户端会发送一个FIN报文
,报文中会指定一个序列号。此时客户端处于FIN_WAIT_1
状态。即发送连接释放报文段(FIN=1,序列号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT_1终止等待1状态,等待服务器确认。
- 第二次挥手:服务端收到
FIN报文
之后,会发送ACK报文
,且把客户端的序列号seq值加1作为ACK报文
的确认号
值,表明已经收到客户端的报文了,此时服务器端处于CLOSE_WAIT
状态。即服务端收到连接释放报文段后即发送确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态 ,客户端到服务器端的连接释放。客户端收到服务器端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务器端发出的连接释放报文段。
第三次挥手
:如果服务器端也想断开连接了,和客户端的第一次挥手一样,发给FIN报文
,且指定一个序列号。此时服务器处于LAST_ACK
的状态。即服务器端没有要向客户端发送的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
第四次挥手
:客户端收到FIN报文
后,一样发送一个ACK报文
作为应答,且把服务器的序列号值+1作为自己ACK报文的序列号的值,此时客户端处于TIME_WAIT
状态。需要过一阵子以确保服务器收到自己的ACK报文
才会进入CLOSED状态
,服务器收到ACK报文
之后,就处于关闭连接了,处于CLOSED状态
。即客户端收到服务器的连接释放报文段后,对此发出确认报文(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT时间等待状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
MSL
2)为什需要四次挥手呢?
因为服务器端可能只有未发送完的数据,所以只能先发送一个ACK报文告诉客户端,你发送的FIN报文我收到了,待服务器端将数据发送完毕后,再发送FIN报文。