断开连接
目的:是为了把对端的信息,从数据结构中给删除/释放掉。
四次挥手
不管是服务器还是客户端都可以主动进行
中间的两次不能合并,因为可能触发的时机是不同的
三次握手和四次挥手的区别?
相似:
1、都是通信双方各自给对方发起一个syn/fin,各自给对方返回ack。
2、传输顺序:syn/ack/syn/ack fin/ack/fin/ack
不同:
1、三次握手的中间两次肯定可以合并
四次挥手的中间两次不一定可以合并
2、三次握手,必须是客户端主动发起的
四次挥手,客户端和服务器都可以主动发起
TCP状态转换过程
滑动窗口
要保证可靠性的前提,来提升传输效率
ACK丢包
这个是没什么影响的,只要其他高序号返回ack就可以,高序号返回,就代表着前面的所有数据都已经接收到了
数据丢包
这个是接收方会多次返回ack索要丢包数据,要求重传重传后,返回正常的接收序号最大值就可以
⭐TCP有个接收缓冲区,专门放这些接收的序号,会进行排序,很容易就发现哪个数据丢失了
应用:
滑动窗口
有很多数据的情况下,使用滑动窗口进行传输,判定的标准是看连续有多个ack索要同一个数据。
普通传输
在数据比较少的情况下,判定丢包的标准是达到超时时间还没有ack到达。
流量控制
按照接收方的接收缓冲区剩余的空间大小,作为ack中窗口大小的值,下一步发送放就会根据这个数值来调整自己的窗口大小。
⭐如果接收方的缓冲区满了,通过ack的窗口大小值,发送发就会停止发送,隔一段时间后,会重新发送一个窗口探测包
拥塞控制
动态平衡,限制发送方发送数据的速率
这里的操作是把发送发到接收方中间的路径看成一个整体,按照某个窗口的大小发送数据,出现丢包,就视为中间路径拥塞,就减小窗口的大小,如果没有丢包,就视为中间路径不拥塞,增大窗口的大小。
拥塞窗口的变化
窗口的大小:
看流量控制和拥塞控制哪个的窗口小,谁的窗口小就用谁的。
延时应答
⭐基于滑动窗口,在允许的范围内,让窗口尽可能大,提升效率。
如果我们延时ack确认应答,那么接收方的应用程序就会多消耗一些缓冲区的数据,这样缓冲区剩余的空间就会变大,那么发送方的窗口就会变大,这样就提示效率了。
捎带应答
基于延时应答,尽可能把能合并的数据包进行合并,从而提升效率。
⭐延时应答+捎带应答可能会使四次挥手中的两次返回合二为一。
面向字节流
粘包问题
因为是字节流,所以应用层程序就会不固定每次消耗多少字节的数据,从而有粘包问题的发生。
解决方法:
1、通过特殊符号,作为分隔符。
2、指出包的长度,在包开始的位置,加一个特殊的空间来表示数据的长度。
⭐TCP面向字节流,接收缓冲区是队列
⭐UDP面向数据报,接收缓冲区是链表
异常情况
1、有一方进程奔溃
进程崩溃和正常关机没有区别,都会触发四次挥手,回收文件资源,关闭文件。
2、有一方关机
强制终止所有的进程,触发四次挥手,但不一定能完成,因为系统要关机了,但也会在关机前放出第一个fin,接收方就会返回ack+fin,但自己关机了,对方就会进入超时重传,最终会单方面删除连接信息。
3、有一方断电
(a)如果断电的是接收方,发送方发现没有ack了,就会超时重传,还没有回复就会RST“复位“连接,重置也不行,就会单方面删除连接信息。
(b)如果断电的是发送发,一段时间后接收方就会发一个'心跳包',如果没有回复就会RST'复位',最后单方面删除连接信息。
4、网络断开
情况就会上面3一样。
⭐UDP相比于TCP最大的优点就是:传输效率高
TCP:可靠传输,低效率
UDP:无可靠性,高效率
KCP:低可靠性,较高效率