1.连接管理
连接指的是通信双方各自保存对方的信息

1.TCP如何建立连接(三次握手handshake)
(1.)第一次握手
网络中通信时,客户端先给服务器发送一个"不包含业务数据的数据包",没有载荷,即syn(SYnchronize Sequence Numbers同步序列)。------一次握手,客户端报文头SYN=1,ACK=0
SYN=1:表示这是客户端请求建立连接的报文
ACK=0:客户端表示这个报文不是用来确认收到数据的,没有确认的含义
;
(2.)第二次握手
服务器给客户端返回一个ack,在向客户端发送一个syn。这两个合并到一起发送给客户端。------二次握手,服务器报文SYN=1,ACK=1
ACK=1:服务器表示这个报文带有确认信息,代表服务器已经确认收到客户端刚才发送的SYN报文
SYN=1:服务器也要同步自己的初始序列号,与客户端建立连接
;
(3.)第三次握手
客户端收到服务器的syn后向服务器返回一个ack------三次握手,客户端报文SYN=0,ACK=1。
SYN=0:不需要再同步序列号
ACK=1:代表客户端确认收到服务端刚才发送的 SYN 报文。
(4.)为啥在第二次握手时要合并?

网络传输有一系列的封装和分用,合并可以提高效率。
(5.)为什么要进行三次握手?
1.验证通信链路是否通畅,这是后续可靠传输的前提
2.验证通信双方的发送能力和接受能力是否正常
3.提前协商好关键的参数,如ISN(Initial Sequence Number)
(6.)TCP三次握手必须是三次吗?四次呢?两次呢?
不是必须三次。
可以是4次。把第二次连接服务器发送的ACK和SYN分两次发送,加起来就是4次。
不可以是2次。如果是两次,服务器无法确认客户端接收数据能力是否正常(服务器无法确认客户端是否成功收到服务器之前发送的SYN报文)。造成服务器半开连接,浪费资源。
(7.)半开连接是什么?
假设只有2次握手:
客户端SYN=1给服务器------》服务器收到,回复SYN+ACK,服务器这边直接把连接设置位已建立,等待客户端发送数据。
但是如果SYN+ACK报文丢包了,客户端根本没收到这个包,客户端连接没建立成功,服务器连接已建立,一直占用内存、端口资源、等待客户端发数据。
此时服务器就是半开连接。
(8.)ISN的作用?ISN是随机值的作用?
ISN的作用是区分旧连接残留的数据包。
ISN是随机值的作用就是确保"ISN区分旧连接残留的数据报"机制正常运行。
那么是如何作用的?
每个TCP连接,两端都会随即生成全新的ISN,
而旧的、延迟滞留的数据包里面的seq序列号是上一次旧连接的ISN基础上生成的,所以收到报文时,内核就可以检查seq序号在不在当前的新的连接的合法序列号内,如果不在,直接丢弃。
所以就需要确保每次TCP连接的ISN不同------》所以ISN是随机值。
如果ISN不变,旧的延迟数据包就会被新连接误当成合法数据,造成严重错误!
(9.)那如果两次的ISN数值很接近,那会出错吗?
如果两次连接的 ISN 数值很接近,也不会直接出错。
TCP 不是简单对比 ISN 是否相等,而是校验报文 seq 序列号是否落在当前连接合法序号窗口。旧包的序列号起点是上一次连接的 ISN,不在新连接合法区间,直接丢弃。
同时 ISN 并不是纯粹无规则随机数,会随时间递增;再加上五元组区分数据包、MSL 等待机制,极大降低新旧连接数据包冲突的概率。只有同时满足多重极端条件,才有可能出现冲突,现实中几乎遇不到。
2.TCP如何断开连接(四次挥手)
断开连接过程中的数据包都是只有报头没有载荷。

**断开连接时客户端和服务器都可以先发送。**这里以客户端先发为例:
(1.)第一次挥手
客户端给服务器发送报文头:FIN(finsh)=1.表示客户端不再发送新的数据,连接还没断,客户端还能接收服务器发来的数据。
(2.)第二次挥手
服务器收到客户端的断开请求,向客户端返回一个ACK=1,表示:服务器告诉客户端:我收到了你刚才发送的关闭请求。
(3.)第三次挥手
服务器继续向客户端发送一个FIN=1,表示:服务器不再发送数据
(4.)第四次挥手
客户端向服务器发送ACK=1,表示:客户端告诉服务器:我收到了你关闭的请求。
服务器一旦收到这个ACK后,就立即关闭socket,连接彻底断开。
客户端一旦发出这个ACK之后,就进入TIME_WAIT状态,等待2MSL,等待结束后客户端才彻底断开。如果这个ACK丢包,服务器重传FIN,等待客户端重发ACK。
(5.)四次挥手能合并位3次挥手吗?
即把第二次挥手和第三次挥手合并。不一定。
因为服务器发送ACK和FIN有时间间隔。
ACK的返回时机是由内核控制的,在服务器收到ACK之后就立即触发。
FIN的返回时机是由应用程序控制的。在应用程序调用socket.close后,才会触发FIN。
所以ACK与FIN之间的时间间隔是不确定的。
如果时间间隔很短,那就可以合并;如果时间间隔很长,那就不可以合并。