目录
引言
udp,tcp协议都属于传输层协议,在tcp/ip四层网络模型下,传输层通过端口向应用层提供数据,向下数据添加报头发送给网络层,向下交付。
1.udp协议
1.1 udp报文格式

端口是什么:
TCP 端口本质上是一种虚拟的数据结构,用于标识网络通信中的特定服务或进程。端口号是一个 16 位的无符号整数,取值范围是从 0 到 65535。IP 地址标识了网络中的主机,而端口号则标识了主机上的特定应用程序或服务,其核心作用是实现多路复用功能,使得一个 IP 地址可以同时运行多个网络服务或应用程序。
udp报头4个字段:四个字段均为16比特
源端口号:记录发送主机端口号,用于标记主机进程。
目的端口号:记录接受方主机端口号,用于标记主机进程。
udp报文长短:一位表示一个字节,用于标记整个报文(报头+数据)的长度,报文最大为 2^16字节。
校验和:用于检验报文在网络传输中的差错检查
1.2 udp的特点
无连接:
udp无连接是指只需要通过ip地址及端口号就能和网络上的主机进行通信。
不可靠:
udp没有确认机制,拥塞控制,连接机制,发送的报文在网络中丢了,目的主机也不知道,源主机也不会给应用层发送任何错误信息。
面向数据报:
udp面向数据报,本质就是一次性发送的数据,在结束时必须一次性读取。例如向目的主机发送一条100字节的报文,接收方在接受时必须一次性将100个字节读取到不能循环读取,一次读一点数据。
1.3基于udp的应用层协议
DNS(域名系统):将域名(如www.baidu.com)解析为 IP 地址,是互联网访问的基础。
DHCP(动态主机配置协议):为局域网设备自动分配 IP 地址、子网掩码、网关等网络配置信息。
TFTP(简单文件传输协议):用于小型文件传输(如路由器固件升级、嵌入式设备文件同步)。
NTP(网络时间协议):实现网络设备间的时间同步(如服务器、路由器、终端设备)
2.tcp协议
tcp协议(传输控制协议):提供可靠的传输。
使用tcp协议在网络传输的整个过程:

使用tcp协议报文在网络中通信的过程是什么?
- 在应用层定义通信的结构化数据
- 使用特定的规则,序列化结构化数据,形成一个字符串,或二进制流等格式
- 通过套接字创建连接
- 通过系统调用write,send等将应用层报文从应用层拷贝到操作系统,及传输层tcp发送缓冲区中,在添加tcp报头封装成tcp报文,向下交付,网络层,数据链路层继续封装报文
- 通过物理层,将报文传送到目的主机的网卡中,一层层向上解包,将字符串解包放在tcp接收缓冲区中
- 用户通过系统调用read,recv等将数据读到应用层
- 将数据根据分隔符等特殊符号反序列化,形成结构化数据,一次通信完成
2.1 tcp报文格式

2.2 tcp报头字段
- 源端口,目的端口号:16比特,表⽰数据是从哪个进程来, 到哪个进程去;
- 序号:32比特,用于报文的按序到达,对报文编号,接收方可以通过序号确认报文是否按序到达,当前报文段中第一个字节的数据编号。
- 确认序号:表示该序号前的报文全部到达。用于滑动窗口,和确认应答机制。在滑动窗口中,是滑动窗口的start,在确认应答中接收方发送带有确认序号的ack报文,提供可靠传输。
- 首部长度:4比特,一位表示4字节。所以报头的最大长度为(2^4-1)*4=60字节。
- 标记位:6比特
- 窗口大小:16比特,告诉对方自己的目前接受缓冲区的剩余容量。目的是为了流量控制。
- 校验和:16比特,发送端填充, 校验算法. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP⾸部, 也包含TCP数据部分。
- urg紧急指针:16比特,在URG标志位为1时,在数据中的偏移量,记录需要紧急传输的数据的位置。
- 选项:窗口大小16位太小,需要扩容时,使用。
- 标志位:6比特,每一位表示一个含义
2.3 TCP确认应答(ACK)

tcp提供可靠传输,确认应答就是其中一种策略,发送端通过序号来标记发送的数据多少,例如发送1~100个字节的数据,发送端发送的报文序号就是1。
发送缓冲区其实是一个个sk_buff的结构体通过双向链表管理起来,因为tcp是面向字节流的,可以把缓冲区看作一个有序的数组

接收端接收到数据时,会给发送端发送一个ack应答报文(这个报文是将标志位ACK至1),确认序号填为101,表示前100字节数据已经收到,下次传送数据从101位置开始穿。
注意:ack确认报文只有发送端关心,发送端在特定时间没有收到ack应答报文,会重传数据。
2.4超时重传
超时重传顾名思义就是发送端超过特定时间没有应答报文,会重新发送该条报文。产生这种情况有两种情况:
1.发送报文在网络中因为网络原因丢包

2.接收端发送的应答报文因为网络原因丢包

无论是哪种情况,发送端并不关心,超过规定时间,就会重传,因此主机B会收到很多重复数据. 那么TCP协议需要能够识别出那些包是重复的包, 并且把重复的丢弃掉。
这时候我们可以利⽤前⾯提到的序列号, 就可以很容易做到去重的效果
- 最理想的情况下, 找到⼀个最⼩的时间, 保证 "确认应答⼀定能在这个时间内返回".
- 但是这个时间的⻓短, 随着⽹络环境的不同, 是有差异的.
- 如果超时时间设的太⻓, 会影响整体的重传效率;
- 如果超时时间设的太短, 有可能会频繁发送重复的包;
- Linux中(BSD Unix和Windows也是如此), 超时以500ms为⼀个单位进⾏控制, 每次判定超时重发
- 的超时时间都是500ms的整数倍.
- 如果重发⼀次之后, 仍然得不到应答, 等待 2*500ms 后再进⾏重传.
- 如果仍然得不到应答, 等待 4*500ms 进⾏重传. 依次类推, 以指数形式递增.
- 累计到⼀定的重传次数, TCP认为⽹络或者对端主机出现异常, 强制关闭连接.
2.5连接管理机制(三次握手,四次挥手)
tcp可靠传输,在通信时,需要创建连接,结束通信时要释放连接,三次握手建立连接,四次挥手释放连接。
2.5.1 三次握手,四次挥手
需要注意的是标志位并不是只传一个标志位,而是一个裸的tcp报文,将标志位置为1.

三次握手:
- 主机A发送一个请求创建连接报文SYN
- 主机B收到A请求,需要确认应答,所以需要发一个应答报文ack,由于tcp是全双工的,所以主机B也需要向主机A请求创建连接,所以也需要发一个SYN报文,将两个报文合并成一个,就是捎带应答(将报文的SYN,ACK都置为1),报文既有确认应答消息,有向主机A请求连接。
- 主机A收到B应答和请求,回复一个应答报文给主机B

四次挥手:
- 主机A发FIN结束报文
- 主机B收到,确认应答报文ACK
- 主机B发送FIN结束报文
- 主机A收到,确认应答报文ACK
2.5.2 为什么三握手,四挥手
为什么要三次握手,而不是四次握手?
三次握手的设计旨在确保通信双方能够建立可靠的连接,同时避免资源浪费和历史连接干扰。
我们创建连接时,肯定想要花费最小的成本,所以主机B设计的时捎带应答回复SYN-ACK。只需要三次握手,最小次数保证双方通信可靠。
那为什么不是两次握手呢,成本更低?可靠连接,需要确认主机A,B都成正常的收,发信息。而两次握手无法保证主机B正常收消息。
为什么要四次挥手,而不是三次挥手?
四次挥手由 TCP 的全双工特性决定,需独立关闭两个方向的数据流。
- 独立关闭双向连接:一方发送 FIN 表示不再发送数据,但仍可接收数据。需另一方确认 FIN 后再发送自己的 FIN。
- 处理剩余数据:被动关闭方可能需发送剩余数据,延迟发送 FIN。
- TIME_WAIT 状态:主动关闭方会等待 2MSL(最大报文生存时间),确保最后一个 ACK 到达,并处理网络中延迟的旧报文。
若合并第二次和第三次挥手(即服务端 FIN 与 ACK 一起发送),可能因剩余数据未发送完毕导致问题。
2.6滑动窗口
如果一次就发一个报文,等收到应答,在发下一条报文,这样效率是不是有点低,那么tcp是如何提高效率的呢?滑动窗口,滑动窗口允许发送方在未收到确认前连续发送多个报文段。窗口大小由接收方通告的可用缓冲区空间和网络拥塞状况共同决定。动态调整窗口大小实现流量控制与拥塞控制平衡

2.6.1滑动窗口流程
- 窗⼝⼤⼩指的是⽆需等待确认应答⽽可以继续发送数据的最⼤值. 上图的窗⼝⼤⼩就是4000个字 节(四个段).
- 发送前四个段的时候, 不需要等待任何ACK, 直接发送;
- 收到第⼀个ACK后, 滑动窗⼝向后移动, 继续发送第五个段的数据; 依次类推;
- 操作系统内核为了维护这个滑动窗⼝, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答;
- 只有确认应答过的数据, 才能从缓冲区删掉;
- 窗⼝越⼤, 则⽹络的吞吐率就越⾼;
如何确定窗口大小?
对方主机发送应答报文时会将主机的接受缓冲区目前容量记录在报头的窗口大小中,拥塞窗口大小由主机自行记录,完整的 TCP 窗口大小是 “拥塞窗口(cwnd)” 和 “接收窗口(rwnd)” 中的较小值
为什么不将滑动窗口的数据封装成一个报文,而是分段发送?
数据链路层无法承载这么大的报文。
2.6.2丢包处理
在滑动窗口中传输过程丢包有四种种情况:主机B收到报文应答丢了,窗口最左侧丢包,窗口中间丢包,窗口最右边丢报
主机B收到报文应答丢了如何处理?

最左侧丢包如何处理?
要解决丢包问题,明确报文中确认序号代表的意义尤其重要:确认序号代表着该序号前的数据报文已经全部收到

- 当某⼀段报⽂段丢失之后, 接收端会持续发送丢失报文段对应序号的确认报文
- 如果发送端主机连续三次收到了同样⼀个 "1" 这样的应答, 就会将对应的数据 1~100重新发送;
- 这个时候接收端收到了 1~100数据 之后, 再次返回的ACK就是401了(因为101~400)接收端其实之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中;
窗口中间丢包,窗口最右边丢报如何处理?
这种两种情况其实也可以想象成最左侧丢包问题

窗口最左边确认收到,中间丢包,接收端会持续发送丢失报文段对应序号的确认报文。发送端连续收到三次该重复 ACK 后,会触发快重传,直接重传 201 - 300 字节。
2.7拥塞控制
TCP 拥塞控制的核心是通过动态调整发送速率,避免网络链路因数据过多发生拥塞,保证网络整体传输效率。
2.7.1 核心目标
- 防止发送方发送速率超过网络链路的承载能力。
- 在网络拥塞时快速降速,拥塞缓解后逐步提速,平衡吞吐量与稳定性。
2.7.2 关键算法流程
- 慢启动(Slow Start):连接初始时,发送窗口按指数级增长(每收到一轮 ACK,窗口大小翻倍),快速试探网络承载上限。
- 拥塞避免(Congestion Avoidance):当窗口大小达到 “慢启动阈值(ssthresh)”,切换为线性增长(每轮 ACK 仅增加 1 个 MSS),平稳提升速率。
- 拥塞发生时的处理:
- 超时重传:判定为严重拥塞,ssthresh 设为当前窗口的一半,窗口重置为 1,重新进入慢启动。
- 快速重传(收到 3 个重复 ACK):判定为轻微拥塞,ssthresh 减半,直接进入拥塞避免阶段(窗口不重置)。
- 快速恢复(Fast Recovery):配合快速重传使用,窗口先调整为新的 ssthresh,之后每收到一个重复 ACK,窗口加 1,加速恢复传输效率。
2.7流量控制
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送 端继续发送, 就会造成丢包, 继⽽引起丢包重传等等⼀系列连锁反应.因此TCP⽀持根据接收端的处理能⼒, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);
- 接收端将⾃⼰可以接收的缓冲区剩余空间⼤⼩放⼊ TCP ⾸部中的 "窗⼝⼤⼩" 字段, 通过ACK端通知发送端;
- 窗⼝⼤⼩字段越⼤, 说明⽹络的吞吐量越⾼;
- 接收端⼀旦发现⾃⼰的缓冲区快满了, 就会将窗⼝⼤⼩设置成⼀个更⼩的值通知给发送端; 发送端接受到这个窗⼝之后, 就会减慢⾃⼰的发送速度;
- 如果接收端缓冲区满了, 就会将窗⼝置为0; 这时发送⽅不再发送数据, 但是需要定期发送⼀个窗⼝探测数据段, 使接收端把窗⼝⼤⼩告诉发送端.

1931

被折叠的 条评论
为什么被折叠?



