前言:
这个是之前看王道视频,做的笔记,整理一下直接搬上来吧,还是挺全面的,后续有需要再补充(这个真的是自己一个字一个字手打打出来的! 如果觉得不错,可以点个赞~)
传输层:
传输层对收到的报文段进行差错检错,网络层对头部进行差错检测,校验和
网络层是不可靠交付,udp也是不保证可靠交付的,这个时候谁保证可靠交付呢?需要由应用层来保证可靠交付**(比如一个例子,HTTP3.0用的是UDP,然后上层用了一个XX协议,可以保证可靠传输,其实就是靠上层来保证可靠传输的)**
可以提供复用和分用,提供差错检测功能
寻址与端口,对应的是 服务器端使用的端口和用户端使用的端口
1.UDP部分
udp是直接在传输层封装的,如果数据量过大,网络层还要进行分装,那么网络层效率会降低。 如果数据量小,ip数据包的首部会很大,也会降低网络层的效率,因为我们希望首部的信息尽可能的少,所含的数据部分应该尽量多; 适合一次性传输少量数据的网络应用; 无拥塞控制,适合一些实时应用,用恒定的速率发送,不允许很多的延迟,首部字段8个字节
检验和是检验整个udp数据包是否有错,错就丢弃,首部字段和数据字段
校验的时候 要加上一个伪首部,包括源ip地址和目标ip地址,以及0 和17 还有udp的长度
伪首部+首部+数据部分采用二进制反码求和,再把和求反码放入检验和字段中,然后去掉伪首部,开始发送
接收端:
填上伪首部,然后求和反码,如果全为1就是无差错的,否则就丢弃,或者交给应用层
2.TCP部分
tcp是面向字节流的,每次传送一部分字节,首部20个字节大小
注意 这里面的窗口字段 反应的是自己 可以接受的窗口大小,允许对方发送的数据量大小(16位,2个字节 65536) ,根据这个接收方的窗口大小 来限制自己的发送窗口,发送缓存大小
网络层是 提供最大努力交付,不可靠传输,因此上层传输层就需要担负起可靠传输的职能
1.tcp实现可靠传输的机制
校验,序号,确认,重传
**校验:**添加伪首部,通过二进制反码 来校验
**序号:**按照字节为单位,编上序号,面向字节流为单位,但是在发送的时候将这些字节组合成报文段,然后把报文段发送出去,大小不定,取决于链路层的MTU; 一个字节占用一个序号
**确认:**一个报文段 只有在接受段告诉发送端确认收到了,发送端才会把发送端缓存里的字段清除; 返回一个确认报文段,累计确认的方式(也可以捎带确认),确认报文段确认号字段为4的话,发送端就知道 4前面的字段都接收到了; 如果丢失了一段,那确认报文段还是为已经确认字段的下一个字段序号,发送端会重传
确认机制和重传机制 是密切相关的
**重传:**超时重传和冗余确认重传,TCP在发送方在规定的时间内没有接收到确认就要重传已发送的报文段,超时重传(重传时间的时间规定会复杂一些,可能经过的是高速的局域网,也可能是低速的局域网,路径不一样,时间就会不一样,过长或者过短都会有问题),重传时间采用的是一种自适应的算法,动态的去改变重传时间RTTS(加权平均往返时间,将前面发送的时间 ,发送到确认为止的时间),这种办法也有可能会等很久;
冗余ACK(快速重传),冗余确认的方式 : 每当比期望序号大的失序报文段到达时,发送一个冗余ACK,指明下一个期待的字节序列号,如果发送方收到了3个冗余的ACK报文段(总共4个)就会判定前面某个报文段丢失,会重传,也叫快速重传机制
2.TCP的流量控制
滑动窗口机制实现流量控制,让发送方速率慢一点;
通信过程中,接收方根据自己接受缓存的大小,动态的调整发送方的窗口大小,即接收窗口(设置确认报文段里的窗口字段来将接收窗口大小通知给发送方),发送方的发送窗口大小取决于接收窗口和拥塞窗口(cwnd)的最小值
接收方在确认或者传数据的时候带上那个窗口大小,就可以告诉发送方自己接收的最大窗口是多少,从而发送方可以调整发送窗口的大小
接收窗口和发送窗口是动态变化的
在将接收窗口设置为0以后,当接收端的缓存处理完毕,向发送端发送一个报文段,告诉发送端可以继续发送了,但是!! 这个时候这个报文段丢失了怎么办? 发送端和接收端都会卡着等待对方发送信息过来。 TCP为每一个连接设有一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就会启动一个持续计时器; 时间到期以后,就会发送一个零窗口探测报文段,接收方收到探测报文段时,给出现在的窗口值!!! 即使通知丢失了,发送端也会发送一个探测报文段,如果窗口还是0 那么收到通知以后,重置持续计时器。 可以打破死锁的局面
3.拥塞控制的几种方法
慢启动,拥塞避免,快重传和快恢复,滑动窗口
产生拥塞的条件:对于资源需求的总和 > 可用资源
防止过多的数据注入到网络中!全局性问题
拥塞控制和流量控制的区别? 两个都是控制发送方发送的流量大小
拥塞控制是很多发送方, 一个接收方, 流量控制是一个发送方一个接收方,接收方知道自己要控制的发送方是哪一个
拥塞控制是发送的时候发生了堵塞,发送的数据一直到不了接收方;而流量控制是发送方的发送速率过快,导致接收端的接收窗口不够
慢开始,拥塞避免,快重传和快恢复,滑动窗口
慢开始和拥塞避免搭配使用
拥塞窗口是发送方根据自己估算的网络拥塞程度而设置的窗口值,反应网络当前容量。 是发送方来设置的, 接收窗口是接收方去设置的
慢开始和拥塞避免(很重要,自己当时吃亏了)
这部分要多看看,一个报文段长度! 下面的单位是一个RTT 传输轮次
快重传和快恢复
**快重传(冗余ACK)**可以在超时计时器到期之前快速的执行重传的过程,省下了很多等待时间
快恢复是 之前是只要发生了拥塞,就会马上降为初始值,从拥塞窗口为1开始,执行慢开始的算法; 但是快重传和快恢复里, 不是等待第一个报文段丢失, 而是出现3个冗余ACK以后 就开始快恢复,而且这个窗口不用降为1,而是降低到新的门限值(出现了三个重复确认的拥塞窗口大小 /2 ),然后继续+1 +1 的发送
快恢复就是不用降低到1,直接降低到新的门限值那里 然后使用拥塞避免算法!!
一定要懂!!
3.TCP和UDP的区别,及各自的应用
UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信),比如: QQ 语音、 QQ 视频 、直播等等
TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。
4.TCP的三次握手和四次挥手
1.三次握手
简单总结就是:为了防止 A发送数据过程中,卡了很久,最后又到了,如果只是两次握手,那么B误认为 A要连接,白白等待 浪费资源时间
还有一个原因:
** 三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。**
第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常
所以三次握手就能确认双发收发功能都正常,缺一不可。
2.四次挥手
5.一些常见的问题
1.为什么要等2MSL时间,而不是MSL?
**第一,**保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
要取这两种情况等待时间的最大值,以应对最坏的情况发生,这个最坏情况是:
去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)。
这恰恰就是2MSL( Maximum Segment Life)。
等待2MSL时间,A就可以放心地释放TCP占用的资源、端口号,此时可以使用该端口号连接任何服务器。
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
-
确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
-
等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
2.客户端有大量的time wait出现怎么办?(见另外一篇博客)
3.建立了很多长连接,但是Server 的处理能力不行,该怎么处理? 有什么应对方法?
4.使用心跳,如果心跳丢包了怎么办?心跳机制该如何设置?