浅析TCP协议中的3次握手和4次挥手
我们都知道TCP协议很稳健很安全,虽然相对UDP来说传输速度不怎么样的快,但是TCP协议提供可靠性也是他为什么是主流协议的原
因
我们今天就是来
瞧瞧它的可靠性是怎么什么原理,让我们也学习学习.
首先我们明白TCP可靠性基于7个方面:
1.TCP提供请求问答机制. *今天的重点*
2.TCP保证数据的按序到达.
3.TCP提供丢包重传机制.
4.TCP面向链接保证可靠性.
5.TCP拥有众多的定时器(例如超时重传定时器).
6.TCP进行流量控制.
7.TCP逻辑上有网络避免拥挤算法.
接下来我们开始真正的了解TCP协议的结构和机制,首先我们了解TCP协议段格式,再然后我们来进入我们今天的硬菜大主题,TCP协
议
的三次握手和四
次挥手,了解它的原理,明白TCP协议的通信过程。。。。
TCP协议段格式
TCP协议段格式:
16位源端口号:标识发送报文的计算机端口或进程。一个 TCP 报文段必须包括源端口号,使目的主机知道应该向何处发送确认报文。
16位目的端口号:标识接收报文的目的主机的端口或进程
32位序号: 用于标识每个报文段,使目的主机可确认已收到指定报文段中的数据。当源主机用于多个报文段发送一个报文时,即使
这
些报文到达目
的主
机的顺序不一样,序列号也可以使目的主机按顺序排列它们。在 SYN 标志未置位时,该字段指示了用户数据
区中第
一个字节的序
号;在 SYN
标志置位
时,该字段指示的是初始发送的序列号。
32位确认序号:目的主机返回确认号,使源主机知道某个或几个报文段已被接收。如果 ACK 控制位被设置为 1,则该字段有效。确
认号
等于顺序接收到
的最后一个报文段的序号加 1,这也是目的主机希望下次接收的报文段的序号值。返回确认号后,计算机认为
已接收到
小于该确认号的所有数据。
4位首部长度: TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远,即首部长度。
保留位:由跟在数据偏移字段后的 6 位构成, 全部为 0 。
URG:此位置 1,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送
ACK:仅当 ACK = 1 时确认号字段才有效,TCP 规定,在连接建立后所有传达的报文段都必须把 ACK 置 1。
PSH:当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情
况下,
TCP 就可以使
用推送(push)操作,这时,发送方 TCP 把 PSH 置 1 ,并立即创建一个报文段发送出去,接收方收到
PSH = 1 的报文
段,就尽快地(即“推送”向
前)交付给接收应用进程,而不再等到整个缓存都填满后再向上交付。
RST:置1时重建连接。如果接收到RST位时候,通常发生了某些错误。
SYN:仅在三次握手建立 TCP 连接时有效。当 SYN = 1而 ACK = 0时,表明这是一个连接请求报文段,对方若同意建立连接,则应
在相
应
的报文段中使
用 SYN = 1和ACK = 1。因此SYN置1就表示这是一个连接请求或连接接受报文。
FIN:用来释放一个连接。当 FIN = 1时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接。
16位窗口大小:此字段用来进行流量控制,这个值是本机期望一次接收的字节数,即发送数据的窗口大小。
16位校验和:源主机和目的主机根据 TCP 报文段以及伪报头的内容计算校验和。在伪报头中存放着来自 IP 报头以及 TCP 报文段
长度信
息。与 UDP
一样,伪报头并不在网络中传输,并且在校验和中包含伪报头的目的是为了防止目的主机错误地接收存在路
由的错误数据报。
16位紧急指针:仅在 URG = 1 时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据),即指出了紧
急数据
的末尾在报文
中的位置,注意:即使窗口为零时也可发送紧急数据。
如果 URG 为 1 ,则紧急指针标志着紧急数据的结束。其值是紧急数据最后 1 字节的序号,表示报文段序号的偏移量。例如,如
果报文段
的序号
是
1000,前 8 个字节都是紧急数据,那么紧急指针就是 8 。紧急指针一般用途是使用户可中止进程。
三次握手基本流程
基本过程:
第一次握手:客户端将SYN设置为1,表示要建立一个新的连接,并随机产生一个序列值Seq=M,并将该数据包发给服务器客户端
进入
FIN_SEND状态;
第二次握手:服务器收到数据包后由标志位SYN=1知道客户端要建立一个连接,服务器将确认ACK和SYN都置为1,ack=M+1并随机
产生
一个Seq=N,并
将该数据包发给客户端,服务器进入SYN_RCVD状态;
第三次握手:客户端收到确认后,检查ack是否为M+1,ACK是否为1,服务器有时候不同意建立一个连接(有可能达到了服务
器建立客户
端的上线),
那
么这里的ACK=0,表示无效,如果正确,则建立成功,客户端和服务器都进入ESTABLISHED
状态,完成
三次握手,随
后服务器和客户端之间就开始传
输数据了!
这就是三次握手!!!!
可能这里就会有人疑惑了,为什么是三次握手而不是两次呢? 按道理讲两次握手其实是可以的进行传输的,但是为什么三次?
举个例子,这里建立连接的过程是利用客户服务器模式,假设主机A为客户端,主机B为服务器端。
采用三次握手是为了防止失效的连接请求报文段突然又传送到主机B,因而产生主机B的资源浪费。失效的连接请求报文段是指
:主
机A发出的连
接请
求后没有收到主机B的回复确认,于是经过一段时间后,主机A又重新向主机B发送连接请求,且建立成功,
顺序完
成数据传输。考虑这样一种特殊情
况,主机A第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到主机B,
主机B以为
是主机A又发起的新连接,于是主机B同意连接,并
向主机A发回确认,但是此时主机A根本不会理会,主机B就一直在
等待主机A发送
数据,导致主机B的资源浪费。我们考虑一下最特殊的情况,就是主
机A发了无数个请求,主机B也确认了无数遍
,然后当B主机确认
后是有代价的他会开辟一段空间等待主机A往那里面填数据.但是A主机就是不发数据.
这样就是造成严重的资
源占用.这样很容易被别
人抓住这个问题攻击你,所以三次握手的重要性一下就突出来了.
但是TCP的三次握手真的就那么坚不可摧吗?
SYN攻击->在第二次握手之后,收到客户端的ACK之前的TCP连接属于半连接(half-open-connect),此时服务器处于
SYN_RECV状
态,当收到客户端
的ACK后才是establish状态,SYN攻击就是客户端在短时间内伪造大量的不存在的地址,并向服务
器不断的发送
SYN包,服务器恢复确认包,并等待
客户端的恢复,因为那些IP是不存在的,所以服务器需要不断的重发直至超时,
这些伪造的SYN
包占用未连接队列,导致正常请求的SYN请求队列满
而被丢弃,从而引起系统的瘫痪和拥塞。SYN攻击是一种典型
的DDOS攻击,检测
的方式也十分简单:即当服务器上有大量的半连接状态的源IP地址是
随机的,那说明该机器遭受SYN攻击了。
四次挥手的基本过程
基本过程:
第一次挥手:客户端发起一个FIN和一个Seq=M,要求关闭客户端到服务器之间的数据传递,客户端进入FIN_WAIT1状态;
第二次挥手:服务器收到FIN后,发送一个ACK=1,和ack=M+1表示知道了,进入CLOSE_WAIT状态;
第三次挥手:当服务器的数据传递完后,再发送一个FIN和一个Seq=N来确定断开连接,等待最后一个ACK的到来;
第四次挥手:此时一直等待的客户端接收到FIN信号表示服务器也要断开了,没数据传送了,变发送一个ACK和ack=N+1,主动断
开了
然
后服务器也就被动断开了;
这就是4次挥手的基本过程! 有木有觉得突然就很清晰,之前一直觉得好难哈哈.
现在有一个问题,讲道理我们3次握手就建立了连接,但是我断开的时候用了4次挥手,这不符合物理守恒定律啊,这是为什么?
这是因为服务器在listen的状态下,收到建立连接请求的SYN报文后,把SYN和ACK放在一个报文里发送给客户端。而关闭连接时
,由
于TCP属于全双
工工作方式,它把FIN和ACK分了两次发,也就是在客户端请求断开时,服务器可以立即中断,也可以把自己
要发给客
户端的数据发送完以后在发送
FIN被动中断。主要是看服务器还有没有数据要发送,如果服务器也是将FIN和ACK直接
一起发给客户
端,那么也就是三次挥手了!!
最后一个问题为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?
TCP的可靠性会根据请求问答机制,四次挥手的时候,最后一条报文是否到达是不可靠的,也就是我们都已经同意关闭连接
了,
服务器已经向客户端
发送了FIN,这时候服务器就等着收到最后一个ACK然后断开连接,
但是客户端发送的最后一条报
文完全是有
可能没有发送到服务器的,服务器有段
时间没有收到客户端发送回来的ACK,它肯定会重新发送一次FIN,如果这
个时候客户端发
送完ACK就直接
切为CLOSED的状态,肯定就收不到服务器发
过来的FIN了
,所以
TIME_WAIT状态多等2MSL的作
用就是重新发送可能
丢失的
最后一个ACK报文,完成断开连接.