TCP协议报文格式和三次握手,四次挥手

这里写图片描述


源端口和目的端口: 用来表示发送主机的进程和接收主机的进程,实现TCP复用和分用

序号: TCP是面向字节流的,TCP连接中的每个字节都按序编号,序号字段又叫报文段序号,指的是当前报文段的第一个字节的序号,比如一报文段的序号字段为301,数据有100字节,则序号为301,下一个报文段应该从401开始,序号为401

确认号:期望收到下一个报文段的第一个字节序号,比如A发送一个报文段序号为501,数据长度为200,则当B接收到501-700报文段,则希望下一次接收的数据序号为701。

注意: 确认号 = N,表示到N-1为止的所有数据都正确收到

数据偏移:占4个比特位,最大能表示的数字为1111(15),它的单位是4字节,这个字段实际上指出TCP首部长度,一般为0101,也就是5 * 4 = 20字节,最大为15 * 4 = 60字节,这也是TCP最大的首部长度(意味着选项和填充字段最大为60 - 20 = 40字节)

保留:占6位,以后使用,现在为0

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述



TCP的建立和释放连接

在了解完TCP的报文格式,下一个重点就是,TCP的建立和释放连接,书上一般形象称为:三次握手,四次挥手

我们知道TCP是面向连接的,概括来说有三个过程:

  1. 建立连接

  2. 传输数据

  3. 释放连接

TCP连接的建立是采用客户服务器方式,主动发起连接请求的应用进程称为客户端,被动等待连接建立的成为服务器。

TCP的连接建立

连接建立如下图:

这里写图片描述

对于服务器而言,刚开始,它建立套接字,执行绑定,监听函数之后处于listen状态,等待客户端发出请求,如果有则响应。

对于客户端,A发送一个连接请求报文段,其中将首部中的SYN=1,同时选择一个初始序号seq=x,TCP规定SYN报文段(即SYN=1的报文段)不能携带数据,不过还是要消耗一个序号,此时TCP客户端处于SYN-SENT状态。

B接受到连接请求报文段,如果同意则发送确认报文,在报文中将SYN=1,ACK=1,确认号设置为x+1,注意它也会为自己选择一个初始序号seq=y,当然这个报文端也不携带数据但是消耗一个序号,此时TCP服务器端出于SYN-RCVD状态。

最后客户端收到B的确认还需要给出确认,这个确认报文段ACK=1,确认号ack=y+1,同时发送自己的序号seq=x+1,TCP规定,ACK报文段可携带数据,如果不携带数据数据则不消耗序号。这时,TCP连接已经建立,A进入established状态。

当B接收到A确认后,也会进入established状态。

以上就是三次握手的过程。那么为什么是三次握手?两次握手行不行?四次握手呢?我在知乎看到一个有意思的图,可以帮我们理解这个问题:

q

为什么不是四次握手?很简单,因为三次握手就可以保证连接的正确建立,多一次握手浪费了网络资源。那么两次握手为什么不能保证连接的正确建立呢?

谢希仁一书中讲到:主要是为了防止已失效的连接请求报文段突然又传到了B造成错误。

什么叫已失效的连接请求报文段?我们知道,网路的环境是异常复杂的,报文的传输是可能有滞留性的,也就是说,假如A发出一个连接请求报文,由于在网络某个结点滞留太久,A以为丢失报文段了就重发一个新的连接请求报文段,然而第一个报文段并没有丢失经过一段时间都到达了B,这本来已失效了,但是B以为A又发出一次连接请求,于是B分配资源建立连接。

然而A认为第一个已经失效了,不会理会B的确认,也不会发送数据,而B还在傻傻的等着A发送数据,这样子B的资源就被浪费了。

因此,采用三次握手才会防止以上现象发生。B只有在三次握手后才真正分配资源建立连接,如果收不到确认也就不会建立连接。

了解SYN攻击:

一、TCP握手协议
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据,在上述过程中,还有一些重要的概念:

未连接队列:在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。
Backlog参数:表示未连接队列的最大容纳数目。

SYN-ACK 重传次数 服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。

半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。

二、SYN攻击原理

SYN攻击属于DOS攻击的一种,它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。SYN攻击除了能影响主机外,还可以危害路由器、防火墙等网络系统,事实上SYN攻击并不管目标是什么系统,只要这些系统打开TCP服务就可以实施。从上图可看到,服务器接收到连接请求(syn=j),将此信息加入未连接队列,并发送请求包给客户(syn=k,ack=j+1),此时进入SYN_RECV状态。当服务器未收到客户端的确认包时,重发请求包,一直到超时,才将此条目从未连接队列删除。配合IP欺骗,SYN攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。

TCP的连接释放

这里写图片描述

数据传输结束后,通信双方都可以释放连接。A的应用进程首先发送一个请求释放报文段,并停止发送数据,这个报文段将FIN=1,序号设为seq=u,此时A的应用进程进入FIN-wait-1状态。

B接收到释放报文段即发送确认,确认号为ack=u+1,这报文段自己的序号为seq=v,然后B进入Close-wait状态。此时,TCP连接处于半连接状态,也就是说A到B这个连接已经释放了,但是B如果要发送数据,A仍要接收,这个状态可能要持续一会儿。

当B没有要发送的数据,就释放连接,此时发送的报文段必须使FIN=1,因此中间可能发送一些数据,所以seq=w,同时还必须重复上次已经发送的确认好ack=u+1。

最后A在收到B的连接释放报文,发出确认报文,将ACK=1,确认号为ack=w+1,而自己序号为seq=w+1。

这里写图片描述

为什么A在Time-Wait必须等待两个MSL时间?

这里写图片描述

发布了96 篇原创文章 · 获赞 119 · 访问量 17万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章