1.TCP的三次握手和四次挥手是干什么的?
我们知道TCP是有连接的,在进行网络通信之前,需要建立连接,而三次握手就是建立连接的过程,四次挥手就是完成断开连接。
2.三次握手的流程,意义是什么?
流程:
要弄清楚,三次握手流程,就需要知道TCP数据报报头的标志位含义
下面这张图就是TCP数据报的格式:
图中红色部分就是标志位,在建立连接时候会起重要作用。

下面这张图就是三次握手的流程的简图:

在TCP数据报报头的图示中,我们可以看到ACK和SYN,这些都被称为标志位。
++当客户端给服务器发送连接请求的时候,客户端会给服务器传一个不含有业务数据的数据报(也就是只有报头,没有报文)++
------>客户端给服务器发起连接请求,客户端操作系统内核自动生成并发送SYN 报文段(同步报文段),负责告诉服务器,需要建立连接了,请你保存我的信息...
------>服务器操作系统内核 收到以后,就会给客户端返回一个ACK(确认报文段), 告诉客户端我收到你的请求了,然后也发送一个SYN报文,告诉客户端你也需要存一下我的信息...
------>客户端这边收到之后,就会再给服务器发送一个ACK,告诉服务器,我也收到你的请求了,连接建立...
思考1:
a. 那就会有疑惑了,按照上面的流程,应该是四次握手呀,为什么是三次捏**?**
++因为SYN和ACK都是由操作系统内核处理的,完全可以同一时间一起传输出去,反而呢,单独发送的话,还会增加开销++
所以实际情况其实是下面这张图:

意义:
我们先说意义,再举个简单例子,更容易说明三次握手的意义:
a. 三次握手可以验证通信链路是否通畅
b. 可以确认通信双方的接收和发送的能力是否ok
c. 通信双方协商++关键信息++(TCP在建立连接的时候,是需要协商关键信息的,之后解释)
例子:
比如两个好朋友A和B打电话商量去哪里吃东西,怎么样俩人才能确定电话确实接通了呢?
A给B先说,喂?在吗?我们去吃海底捞吗?(这里的海底捞,就代表关键信息)
B听到A的声音了,此时B就知道A的那边说话过来没问题(表示A这边发送能力OK的),然后就会回,在的在的,好呀好呀
A就会听到B回复的声音(表示B的发送和接收能力OK的),此时A就知道B的接收和声音传达都没问题,那他还要让B也知道一下这个情况,所以A会给B回复,ok就这么决定了(表示A的发送和接收能力OK的)
思考2:
那么关于"通信双方协商++关键信息++"中的关键信息,到底是啥?
就是TCP数据的起始序号。
++为啥要协商起始序号捏?++
我们知道TCP传输数据的时候,针对载荷部分会按照字节进行编号,在建立连接之后,传输的第一个数据报的数据的第一个字节编号,并不是直接0/1直接开始排的,而是有挺大差别的,为什么这么做呢?其实就是为了应对丢包问题。
假想一种情况:

那么我们肯定是不要那条迟来的数据了,所以上一次的数据的序号和这一次重启的序号就会进行判断,当相差很大的时候,我们就可以判断出,这并不是我客户端要接收的数据。
再聊一下TCP的关键状态:
LISTEN 和ESTABLISH

LISTEN: 在new ServerSocket的时候,就代表进入了LISTEN状态,表示监听绑定的端口(++绝对只在服务器出现,客户端是不可能出现的,因为LISTEN的含义是等待别人来连接我,我不主动去找别人++)
ESTABLISH: 代表连接已经建立完成,客户端和服务器已经可以进行通信了。
3.四次挥手的流程,意义是什么?
流程:
和三次握手一样,操作系统内核也会发送对应的报文,完成挥手断开连接
下面的是四次挥手的流程的简图:

++FIN:结束报文段,告诉对面我这边数据发完了,要关闭连接++
客户端先发FIN,表示要关闭连接
------>服务器发送ACK表示收到
------>服务器发送FIN表示我这边也要关闭连接了
------>客户端发送ACK,表示收到,断开连接
意义:
挥手的目的很简单,就是为了释放资源,之前保存的信息都不用,连接断开了,自然就要释放之前保存的信息
TCP挥手时的关键状态:

CLOSE_WAIT: 可以理解成wait close,++等待应用程序调用close关闭连接++,在客户端发送FIN的时候,服务器就会发送一个ACK,同时进入CLOSE_WAIT状态
TIME_WAIT: ++等待连接彻底释放++
思考:
按理来说,客户端发送了ACK之后,连接应该就马上释放了,为什么会有等待彻底释放捏?
当然也是为了应对丢包问题~
当客户端发送了ACK后,发生了丢包,那么在等待了一段时间后服务器就会出现**超时重传,重新给客户端发送一个FIN,**如果你客户端这边直接释放了连接,那么传过来的FIN就没办法处理了。
那么TIME_WAIT会等多久呢?++2*MSL(网络上任意两点之间,传输消耗的最大时间)++
4.一定是三次握手,四次挥手吗?
关于三次握手,我们已经说明了情况,其实是可以四次握手滴,但是完全没得必要,还会消耗多余的资源,直接内核一次完成ACK和SYN发送就行。
四次挥手呢?大部分情况都是四次挥手...
这就要牵扯到握手和挥手的区别,握手都是由操作系统内核完成的,而挥手中,服务器的ACK发送是由内核即时发 ,但是服务器内核发送FIN,是需要应用程序区调用close之后才能发送的 ,此时,在调用close之前可能会有一些操作,比如读数据、写日志、处理逻辑、释放资源,这++二者的时机搭不上++,自然也就没法同步发送...
也可能有些特殊情况,比如++TCP的延迟应答机制++ 出现的情况,ACK延时应答的同时,++close()同时被调用++
有不对的地方或者细节问题,欢迎指出,谢谢观看