TCP / UDP
- OSI七层网络模型
从下往上 : 物理层, 数据链路层,网络层,运输层, 会话层,表示层,应用层
- TCP/ IP
网络协议是什么
- 在计算机网络要做到井井有条的交换数据,就必须遵守一些事先约定好的规则,比如交换数据的格式、是否需要发送一个应答信息。这些规则被称为网络协议。
为什么要对网络协议分层
- 简化问题难度和复杂度。由于各层之间独立,我们可以分割大问题为小问题。
- 灵活性好。当其中一层的技术变化时,只要层间接口关系保持不变,其他层不受影响。
- 易于实现和维护。
- 促进标准化工作。分开后,每层功能可以相对简单地被描述![[OSI.png]]
1、UDP 和 TCP 的特点与区别
用户数据报协议 UDP(User Datagram Protocol)
是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信。
传输控制协议 TCP(Transmission Control Protocol)
是面向连接的,提供可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条 TCP 连接只能是点对点的(一对一)。
TCP拥塞控制是传输控制协议(英语:Transmission Control Protocol,缩写TCP)避免网络拥塞的算法,是互联网上主要的一个拥塞控制措施。它使用一套基于线增积减模式的多样化网络拥塞控制方法(包括慢启动和拥塞窗口等模式)来控制拥塞。[1][2][3][4][5]在互联网上应用中有相当多的具体实现算法。
![[{3B980C8E-4290-4775-9A0E-701F2F915A2F}.png]]![[{C2356D64-8E5C-4E3A-A3A8-E8D6517C3212}.png]]
TCP结构:
序号 :
确认号:
数据偏移:
控制位:八位从左到右分别是 CWR,ECE,URG,ACK,PSH,RST,SYN,FIN。
CWR:CWR 标志与后面的 ECE 标志都用于 IP 首部的 ECN 字段,ECE 标志为 1 时,则通知对方已将拥塞窗口缩小;
ECE:若其值为 1 则会通知对方,从对方到这边的网络有阻塞。在收到数据包的 IP 首部中 ECN 为 1 时将 TCP 首部中的 ECE 设为 1;
URG:该位设为 1,表示包中有需要紧急处理的数据,对于需要紧急处理的数据,与后面的紧急指针有关;
ACK:该位设为 1,确认应答的字段有效,TCP规定除了最初建立连接时的 SYN 包之外该位必须设为 1;
PSH:该位设为 1,表示需要将收到的数据立刻传给上层应用协议,若设为 0,则先将数据进行缓存;
RST:该位设为 1,表示 TCP 连接出现异常必须强制断开连接;
SYN:用于建立连接,该位设为 1,表示希望建立连接,并在其序列号的字段进行序列号初值设定;
FIN:该位设为 1,表示今后不再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位置为 1 的 TCP 段。
每个主机又对对方的 FIN 包进行确认应答之后可以断开连接。不过,主机收到 FIN 设置为 1 的 TCP 段之后不必马上回复一个 FIN 包,而是可以等到缓冲区中的所有数据都因为已成功发送而被自动删除之后再发 FIN 包;
窗口:窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。
TCP三次握手
第一次 从发送方主机 -> 接收方主机
ACK = 0, SYN = 1; 选择一个序列号 Seq = x第二次 从接收方主机 -> 发送方主机
ACK = 1, SYN = 1; 返回Seq = x + 1同时选择一个序列号 ACKnum = y第三次, 从发送方主机 -> 接受方主机
ACK = 1; ACKnum = y + 1
建立连接
使用TCP三次握手的原因
- 确认双方的发送和接收消息的能力是正常的
注意到建立连接一般是 三次握手
TCP的四次挥手
第一次 从发送方 -> 接送方主机
FIN = 1, Seq = x第二次 从接收方 -> 发送方
ACK = 1, ACKnum = x + 1;
中间有一段服务端确认(CLOSEWAIT), 等待 服务端 所有 传输剩下的报文段发送完毕
第三次 从接收方 -> 发送方
FIN = 1, Seq = y第四次 从发送方 -> 接收方
之后是客户端的TIME_WAIT, 等待 2 MSL (报文段最大存活时间)后关闭连接
TCP 短连接和长连接的区别
短连接:Client 向 Server 发送消息,Server 回应 Client,然后一次读写就完成了,这时候双方任何一个都可以发起 close 操作,不过一般都是 Client 先发起 close 操作。短连接一般只会在 Client/Server 间传递一次读写操作。
短连接的优点:管理起来比较简单,建立存在的连接都是有用的连接,不需要额外的控制手段。
长连接:Client 与 Server 完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。
在长连接的应用场景下,Client 端一般不会主动关闭它们之间的连接,Client 与 Server 之间的连接如果一直不关闭的话,随着客户端连接越来越多,Server 压力也越来越大,这时候 Server 端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致 Server 端服务受损;如果条件再允许可以以客户端为颗粒度,限制每个客户端的最大长连接数,从而避免某个客户端连累后端的服务。
粘包和拆包
- 粘包 : 在从 客户端 到 服务端过程中两个包连在一起 叫做粘包
- 拆包 : ————————————————————————-之后还拆分成两个与原来不同的数据段叫做拆包
什么时候发生粘包和拆包?
答案 :1. 在发送的数据超过TCP缓冲区最大空间时候可能发生拆包 2. 发送的数据大于MSS(最大报文长度), 发生拆包 3. 发送的数据小于TCP缓冲区最小空间可能发生粘包 4. 接受数据端应用层没有及时读取缓冲区的数据
粘包拆包解决办法 :
- 消息定长 : 每个数据包固定长度(不够的拿0去填补),这样接收端每次接受的都是固定长度的数据,就可以分开
- 设置消息边界 : 服务端在接受时候, 按照分割边界把消息分割, 如 FTP协议(通过设置一个换行符)
TCP的可靠传输
TCP采用超时重传实现可靠传输 : 当某一个信息发送后在超时时间内没有收到确认就重传这个报文段(从发送到接受的时间是RTT, 可以自己计算)
TCP滑动窗口
TCP发送窗口, 和接受窗口内的数据段都是可接受或者可以发送的,当发送方的某个报文段已经被确认后, 窗口会向右移动一段距离, 更新可以接受和被接受的报文段
TCP的流量控制
TCP通过控制窗口大小实现流量的控制
为了避免发送不出数据, 接收方会时不时发送一个 窗口探测 的数据段(只包含一个字节)来确定最新的窗口大小
TCP的拥塞控制
主要通过四个算法:慢开始,拥塞避免,快重传,快恢复
维护一个拥塞窗口(cwnd),注意道拥塞窗口只是一个状态变量
假设接收方有足够大的接收窗口,窗口的大小为报文段
慢开始和拥塞避免
最开始执行满开始,让cwnd = 1,之后每当接受确认,就倍增 2 4 8 ....再设置一个慢开始门限ssthresh,当慢开始大于这个门限的时候进入拥塞避免,每个轮次让cwnd + 1 1 如果出现了超时,就另慢开始门限 = cwnd / 2,重新开始慢开始快重传和快恢复
接收方每次接收报文都应该对最后一次收到的报文进行确认,例如收到了B1, B2, B4 则在收到B2时候要对B1确认,B4时候要对B2确认 当发送方重复收到3次接收方发来的某个相同的报文的确认时,立即执行快重传(因为这时候知道有报文丢失),在这种情况下是报文段的丢失,不是网络拥塞,所以直接执行快恢复,让慢开始上限(ssthresh)= 拥塞窗口(cwnd) / 2;注意此时直接进入拥塞避免
注意 慢开始和快恢复的慢和快指的是cwnd的设定值,慢开始cwnd设置成1,快开始cwnd设置成ssthresh
