三次握手:在osi七层参考模型的第四层即传输层中的TCP (Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节 流的传输层通信协议。
简单介绍:
源端:用来标识发送该TCP报文段的应用进程。
目的端口:标识接收该TCP报文段的应用进程。
序号SEQ: 指出本TCP报文段数据载荷的第一个字节的序号,记录发送的次数。
确认号:举例若确认号=n,则表明到序号n-1为止的所有数据都已正确接收,期望接收序号为n的数据。
确认标志位ACK:取值为1时确认号字段才有效;取值为0时确认号字段无效。TCP规定,在连接建立后所有传送的TCP报文段都必须把ACK置1。
窗口:流控:流量多少的控制。
同步序列号SYN: 在TCP连接建立时用来同步序号。终止序列号FIN: 用来释放TCP连接。
复位序列号RST: 用来复位TCP连接。
校验:对暗号。占16比特,检查范围包括TCP报文段的首部和数据载荷两部分。
紧急指针:作用例如:传输文件中断时做标签方便下次传输。占16比特,以字节为单位,用来指明紧急数据的长度。
传输控制块:tcp连接表,指向发送和接收缓存指针,指向重传队列的指针,当前发送和接受的序号
举例:
client:主动发起TCP连接建立的应用进程
server:被动等待TCP连接建立的应用进程
client:A(客户端)—server:B(服务端)
第一次握手:最初两端的TCP进程都处于关闭状态(closed)。
A进程是首先创建传输控制块,然后A打算建立;
B进程是首先创建传输控制块,用来存储TCP连接中的一些重要信息。之后准备接受A端的连接请求,此时TCP服务器进程就要监听状态(LISTEN)等待A端连接请求。
TCP连接时向B端发送TCP连接请求报文段,并进入同步已发送状态(SYN-SENT)。此时syn=1,表明这是一个tcp连接请求报文段;seq=x,作为A所选择的初始序号。
第二次握手:B端接受到TCP连接请求文段后,且同意连接建立,则发送确认报文段ack.此时syn=ack=1,表明这是一个TCP连接请求。swq=y,作为B端进程所选择的初始序号。ack=x+1,是对A所选择的初始序号seq的确认。
第三次握手:A收到TCP连接请求确认报文段后,还要向B发送一个TCP 确认报文段并进入连接已建立状态(SYN-SENT)。
- ACK=1,表明这是一个普通的TCP确认报文段 。
- seq =x+1,这是因为A发送的第一个TCP报文段的序号为x,并且不携带数据,因此第二个报文段的序号为x +1。
- ack=y + 1,这是对B所选择的初始序号的确认。
采用三报文握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。
“两报文握手”建立连接为什么不行?
假设TCP客户进程发出一个TCP连接请求报文段,但该报文段在某些网络节点长时间滞留了,这必然会造成该报文段的超时重传。则会出现重传的报文段被TCP服务器进程正常接收,TCP服务器进程给TCP客户进程发送一个TCP连接请求确认报文段,并进入连接已建立状态。他们可以相互传输数据,之后可以通过四报文挥手来释放连接,TCP双方都进入了关闭状态。一段时间后,之前滞留在网络中的那个失效的TCP连接请求报文段到达了TCP服务器进程,TCP 服务器进程会误认为这是TCP客户进程又发起了一个新的TCP连接请求,于是给TCP客户进程发送TCP连接请求确认报文段并进入连接已建立状态。该报文段到达TCP客户进程,由于TCP客户进程并没有发起新的TCP连接请求,并且处于关闭状态,因此不会理会该报文段。但TCP服务器进程已进入了连接已建立状态,他认为新的TCP连接已建立好了,并一直等待TCP客户进程发来数据。这将白白浪费TCP服务器进程所在主机的很多资源。
综上所述,采用三报文握手,而不是两报文握手来建立TCP连接,是为了防止已失效的连接请求报文段突然又传送到了TCP服务器进程因而导致错误。并确认对方已经收到了序列号起始值的必经步骤。如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。
举个例子:假设你有一个喜欢的异性
你:我要追你了,你准备好了吗?
他(她):我准备好了,你要怎么做。
你:好的....(你的数据即你的行动)
你不能已经开始行动了,但是她并不知道你是因为喜欢并且想和她在一起而做出的举动。因为这样有可能演变成舔狗。(即浪费客户端大量资源)
四次挥手:
A——B第一次fin(请求断开)
B——A第二次(ack)确认断开/二三次断开发送的ack、seq相同
B——A第三次(fin)发送断开
A——B第四次(ack)确认断开
形象点就是:
客户端说:服务器,我要断开你了!
服务器说:好的!让我传完数据!
数据传输结束后
服务器说:客户端,我要断开你了!
客户端说:好的!
这就表现出了四次挥手,和三次握手不同的是,结束的时候,可能仍然有数据在进行传输,tcp为了保证数据传输的完整性,断开连接会在数据传输结束之后再进行,因此这里也体现出一次挥手。
那么为什么是四次不是三次?
TCP 是可以双向传输数据的,也就是全双工协议。
所以双方都可以主动断开连接,断开连接后主机中的「资源」将被释放
你可以看到,每个方向都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手。
- 关闭连接时,客户端向服务端发送
FIN
时,仅仅表示客户端不再发送数据了但是还能接收数据。 - 服务器收到客户端的
FIN
报文时,先回一个ACK
应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送FIN
报文给客户端来表示同意现在关闭连接。
从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK
和 FIN
一般都会分开发送,从而比三次握手导致多了一次。
如果一定要三次可以吗?
可以的。因为服务器端收到客户端的FIN
后,服务器端同时也要关闭连接,这样就可以把ACK
和FIN
合并到一起发送,节省了一个包,变成了“三次挥手”。