计算机网络面试高频(TCP和UDP)
TCP和UDP
1 什么是TCP/IP⭐⭐⭐⭐⭐
TCP/IP 的核心组成
- IP(网际协议)功能:负责网络层的寻址和路由,确保数据报(数据包)从源主机传输到目标主机。特点:无连接:不保证数据可靠传输。尽力而为:数据可能丢失、重复或乱序。使用 IP 地址(如 IPv4、IPv6)标识设备。
- TCP(传输控制协议)功能:运行在传输层,提供面向连接的、可靠的字节流服务。特点:可靠性:通过序列号、确认机制、超时重传等确保数据完整。流量控制:防止发送方淹没接收方。拥塞控制:动态调整传输速率以避免网络拥堵。应用场景:HTTP、HTTPS、FTP、SMTP 等需要可靠传输的场景。
- UDP(用户数据报协议)功能:传输层协议,提供无连接、不可靠但高效的数据传输。特点:轻量级:无需建立连接,延迟低。适用于实时性要求高的场景(如视频流、语音通话)。
TCP/IP 协议栈分层
TCP/IP 采用四层模型,每层负责不同功能:
- 应用层协议:HTTP、HTTPS、DNS、FTP、SMTP 等。作用:为用户提供直接服务(如网页浏览、文件传输)。
- 传输层协议:TCP、UDP。作用:端到端的数据传输,确保可靠性(TCP)或高效性(UDP)。
- 网络层协议:IP、ICMP(网络诊断)、ARP(地址解析)。作用:数据包的路由和寻址。
- 网络接口层协议:以太网、Wi-Fi、PPP 等。作用:物理设备之间的数据传输(硬件层面)。
TCP/IP 的工作流程
- 数据封装:应用层数据逐层添加头部(如 TCP 头、IP 头),形成数据包。
- 路由与传输:IP 根据目标地址选择路径,通过路由器转发数据包。
- 解封装与确认:目标主机逐层剥离头部,TCP 确保数据完整后交付给应用层。
TCP/IP 的重要性
- 跨平台兼容性:所有支持 TCP/IP 的设备均可互联。
- 灵活性:分层设计允许独立改进某一层(如 IPv6 替代 IPv4)。
- 互联网基础:支撑 Web、电子邮件、视频通话等核心服务。
总结
TCP/IP 是互联网的 “神经系统”,通过 IP 实现网络寻址,TCP 保证可靠传输,UDP 提供高效传输。其分层结构和标准化协议使全球设备能够互联互通。
2 TCP有哪些特点?⭐⭐⭐⭐⭐
TCP(传输控制协议)具有以下特点:
面向连接
- 建立连接:在进行数据传输之前,TCP 需要通过 “三次握手” 在客户端和服务器之间建立可靠的连接。具体来说,客户端向服务器发送 SYN 包,服务器收到后返回 SYN + ACK 包,客户端再发送 ACK 包确认,这样连接就建立起来了。
- 断开连接:数据传输结束后,需要通过 “四次挥手” 断开连接,确保双方都知道连接已经终止。客户端发送 FIN 包表示请求关闭连接,服务器收到后返回 ACK 确认,然后服务器也发送 FIN 包表示自己也准备关闭,客户端再返回 ACK 确认。
可靠传输
- 序列号和确认应答:TCP 为每个字节的数据都分配一个序列号,接收方收到数据后会返回确认应答(ACK),告知发送方数据已成功接收。发送方可以根据 ACK 来确认哪些数据已经被正确接收,哪些需要重传。
- 超时重传:如果发送方在一定时间内没有收到某个数据包的 ACK,就会认为该数据包丢失,然后重新发送该数据包。超时时间会根据网络状况动态调整。
- 校验和:TCP 会对每个数据包的数据部分进行校验和计算,并将校验和放在数据包的头部。接收方在收到数据包后会重新计算校验和,如果计算结果与头部的校验和不一致,就说明数据在传输过程中可能被损坏,接收方会要求发送方重传。
- 流量控制:TCP 使用滑动窗口机制进行流量控制。接收方会告知发送方自己的接收窗口大小,发送方只能发送接收窗口内大小的数据,避免接收方缓冲区溢出。随着数据的接收和处理,接收方可以动态调整窗口大小并通知发送方。
- 拥塞控制:TCP 有多种拥塞控制算法,如慢启动、拥塞避免、快速重传和快速恢复。当网络出现拥塞时,TCP 会降低发送速率,避免进一步加重网络拥塞;当网络状况好转时,会逐渐增加发送速率。
面向字节流
- 数据无边界:TCP 将应用层交付的数据看作是无结构的字节流进行传输,发送方将数据不断地写入 TCP 的发送缓冲区,接收方从 TCP 的接收缓冲区中读取数据。应用层不需要关心数据的具体边界,TCP 会负责将字节流正确地传递给对方。
- 顺序交付:TCP 保证数据按照发送的顺序交付给应用层。即使数据包在网络中可能会乱序到达,TCP 也会在接收端对数据包进行重新排序,确保数据的顺序性。
全双工通信
- 双向传输:在一个 TCP 连接中,双方可以同时进行数据的发送和接收。也就是说,客户端和服务器可以在同一时间既发送数据又接收数据,这大大提高了通信的效率。
拥塞控制机制
- 网络感知:TCP 能够感知网络的拥塞情况,并根据拥塞程度动态调整发送速率。这有助于避免网络拥塞的进一步恶化,保证网络的稳定性和公平性。例如,当网络拥塞时,TCP 会降低发送窗口大小,减少发送的数据量;当网络状况改善时,会逐渐增加发送窗口大小,提高发送速率。
3 TCP三次握手⭐⭐⭐⭐⭐
TCP 三次握手是建立可靠连接的核心机制,通过以下三个步骤完成客户端与服务器的通信初始化:
三次握手过程
- 第一次握手:客户端发送 SYN 请求动作:客户端向服务器发送一个带有 SYN(同步)标志的数据包,请求建立连接。内容:随机生成初始序列号(seq = x)。客户端告知服务器自己的接收窗口大小(window size)。服务器响应:服务器收到后进入 SYN_RCVD 状态。
- 第二次握手:服务器确认并同步动作:服务器返回 SYN + ACK 数据包,确认客户端的请求,并同步自身序列号。内容:确认号(ack = x + 1),表示已收到客户端的 SYN 请求。服务器生成自身的初始序列号(seq = y)。服务器也告知客户端自己的接收窗口大小。客户端响应:客户端收到后进入 ESTABLISHED 状态。
- 第三次握手:客户端最终确认动作:客户端发送 ACK 数据包,确认服务器的 SYN 请求。内容:确认号(ack = y + 1),表示已收到服务器的 SYN 响应。序列号(seq = x + 1),开始传输实际数据。服务器响应:服务器收到后进入 ESTABLISHED 状态,连接正式建立。
三次握手的关键作用
- 同步序列号双方通过随机生成的序列号(x 和 y),确保后续数据传输的顺序性和唯一性。
- 验证可达性三次握手确保客户端和服务器都能双向接收数据,避免 “单工” 连接。
- 资源分配服务器在第三次握手后才为连接分配缓冲区等资源,防止被恶意 SYN 请求耗尽资源(SYN 攻击)。
三次握手的示意图
客户端 服务器 │ │ ├─ SYN (seq=x)─────▶ 第一次握手 │ │ 进入 SYN_RCVD ├─ ◀── SYN+ACK───── 第二次握手 │ (ack=x+1, seq=y) │ │ │ 进入 ESTABLISHED ├─ ACK (ack=y+1)──▶ 第三次握手 │ │ 进入 ESTABLISHED │ 数据传输开始 │
4 TCP两次握手可以吗?⭐⭐⭐⭐
第三次握手主要为了防止已失效的连接请求报文段突然又传输到了服务端,导致产生问题。
- 比如客户端A发出连接请求,可能因为网络阻塞原因,A没有收到确认报文,于是A再重传一次连接请求。
- 连接成功,等待数据传输完毕后,就释放了连接。然后A发出的第一个连接请求等到连接释放以后的某个时间才到达服务端B,此时B误认为A又发出一次新的连接请求,于是就向A发出确认报文段。
- 如果不采用三次握手,只要B发出确认,就建立新的连接了,此时A不会响应B的确认且不发送数据,则B一直等待A发送数据,浪费资源。
5 TCP四次挥手⭐⭐⭐⭐
四次挥手的过程
四次挥手的过程如下:
- 客户端发起连接终止(FIN):
客户端(主动关闭方)向服务器发送一个 FIN(Finish)报文段,表示客户端的数据已经发送完毕,希望关闭连接。
客户端进入 FIN_WAIT_1 状态,等待服务器的确认。
- 服务器确认客户端的请求(ACK):
服务器收到客户端的 FIN 请求后,发送一个 ACK 报文段作为确认,确认号是客户端的 SEQ + 1。
服务器进入 CLOSE_WAIT 状态。
- 服务器发送连接终止(FIN):
服务器发送一个 FIN 报文段,表示服务器也已经没有数据要发送了,准备关闭连接。
服务器进入 LAST_ACK 状态,等待客户端的确认。
- 客户端确认服务器的请求(ACK):
客户端收到服务器的 FIN 报文后,发送一个 ACK 报文段作为确认,确认号是服务器的 SEQ + 1。
客户端进入 TIME_WAIT 状态,等待可能存在的延迟的 ACK 报文段。
客户端等待一段时间(通常是 2MSL,最大报文段生存时间)以确保服务器收到了确认,然后进入 CLOSED 状态,连接完全关闭。
四次挥手过程的状态变化:
客户端状态:
FIN_WAIT_1:等待服务器确认关闭连接。
FIN_WAIT_2:等待服务器发送关闭请求。
TIME_WAIT:等待可能延迟的包到达,确保服务器收到确认。
CLOSED:连接完全关闭。
服务器状态:
CLOSE_WAIT:等待应用层关闭连接。
LAST_ACK:等待客户端确认关闭连接。
CLOSED:连接完全关闭。
为什么是四次?
四次挥手的原因是,在 TCP 协议中,连接是全双工的,即每一方向的数据传输是独立的。因此,客户端和服务器需要分别确认各自的数据已经发送完毕,才能安全地关闭连接。
第一步:客户端希望关闭连接,发送 FIN,表示客户端没有数据要发送了。
第二步:服务器收到 FIN 后,发送 ACK,表示确认客户端没有数据要发送了,但服务器可能仍然有数据要发送。
第三步:服务器发送 FIN,表示服务器也没有数据要发送了,准备关闭连接。
第四步:客户端收到服务器的 FIN 后,发送 ACK,确认连接的关闭。
四次挥手与三次握手的区别:
三次握手用于连接的建立,确保双方都准备好开始通信。
四次挥手用于连接的关闭,确保双方都能安全地关闭连接,防止数据丢失。
示例:
客户端 → 服务器: FIN
服务器 → 客户端: ACK(确认收到 FIN)
服务器 → 客户端: FIN
客户端 → 服务器: ACK(确认收到服务器的 FIN)
在四次挥手完成后,TCP 连接会被完全关闭,双方的通信完全结束。
总结:
四次挥手是 TCP 连接断开的标准过程,通过这种方式,双方确保各自的所有数据都已经成功传输,并且在适当的时机安全地关闭连接。
6 TCP的粘包和拆包⭐⭐⭐
TCP是面向流,没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。
为什么会产生粘包和拆包呢?
- 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
- 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
- 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
- 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS。
解决方案:
- 发送端将每个数据包封装为固定长度
- 在数据尾部增加特殊字符进行分割
- 将数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小。
7 说说TCP是如何确保可靠性的呢?⭐⭐⭐
TCP(传输控制协议)通过以下核心机制确保数据传输的可靠性,以下是详细说明:
1. 序列号与确认应答(ACK)
- 序列号:每个字节数据都被标记唯一的序号,用于标识数据顺序。
- ACK 机制:接收方收到数据后,返回确认应答(ACK),告知发送方数据已成功接收。
- 示例:发送方发送序号 1-1000 的数据,接收方收到后返回 ACK=1001,表示期望接收下一个字节。
2. 超时重传(Retransmission)
- 超时机制:发送方启动计时器,若超时未收到 ACK,则重传未确认的数据。
- 动态调整超时时间:根据网络状况动态计算往返时间(RTT),避免频繁重传或等待过久。
- 快速重传:若接收方连续收到多个重复的 ACK(如三次重复 ACK),发送方立即重传丢失的数据,无需等待超时。
3. 流量控制(Flow Control)
- 滑动窗口(Sliding Window):接收方通过窗口大小告知发送方当前可接收的数据量,防止接收方缓冲区溢出。
- 窗口更新:接收方根据处理能力动态调整窗口大小,发送方根据窗口大小控制发送速率。
- 示例:接收方窗口为 1000 字节,发送方最多发送 1000 字节未确认数据,避免过载。
4. 拥塞控制(Congestion Control)
- 慢启动(Slow Start):初始阶段逐步增加发送窗口,探测网络容量。
- 拥塞避免(Congestion Avoidance):达到阈值后,窗口增长放缓,避免网络拥塞。
- 快速恢复(Fast Recovery):检测到丢包后,降低窗口并进入快速恢复阶段,减少性能损失。
5. 数据校验与校验和
- 校验和(Checksum):对数据段进行校验,确保传输过程中数据未被篡改或损坏。
- 丢弃损坏数据:接收方发现校验和错误时,直接丢弃该数据段并等待重传。
6. 连接管理(三次握手与四次挥手)
- 三次握手:建立连接时,双方确认通信能力和初始序列号。
- 四次挥手:关闭连接时,确保所有数据已传输完毕,避免数据丢失。
总结对比(TCP vs UDP)
对比 |
TCP |
UDP |
可靠性 |
可靠(确保数据到达) |
不可靠(尽力而为) |
传输方式 |
面向连接 |
无连接 |
顺序保证 |
有序交付 |
可能乱序 |
流量控制 |
支持 |
不支持 |
拥塞控制 |
支持 |
不支持 |
应用场景 |
文件传输、网页浏览 |
视频流、实时通信 |
8 说下TCP的滑动窗口机制⭐⭐⭐
TCP 滑动窗口机制是实现流量控制和高效数据传输的核心技术,通过动态调整发送方的未确认数据量,平衡网络效率与接收方处理能力。以下是其核心内容:
一、滑动窗口的核心作用
- 流量控制接收方通过窗口大小告知发送方 “最多可以发送多少未确认的数据”,避免接收方缓冲区溢出。
- 提升吞吐量允许发送方连续发送多个数据包(无需等待每个 ACK),充分利用带宽。
二、窗口结构与关键参数
- 窗口左边界:已发送且已确认的数据末尾(
last_ack
)。 - 窗口右边界:左边界 + 窗口大小(
last_ack + window_size
),表示当前允许发送的最大数据位置。 - 窗口大小:由接收方在 ACK 中动态告知(如
window = 4096
字节)。
三、滑动窗口的工作流程
- 发送数据发送方在窗口范围内发送数据(如 seq=1~4096),并启动计时器。
- 接收确认接收方处理数据后,返回 ACK(如ack=2049),表示 seq=2048 及之前的数据已接收。
- 窗口滑动发送方收到 ACK 后,将窗口左边界移动到ack位置(2049),窗口右边界同步后移(2049+4096=6145),允许继续发送新数据(seq=2049~6145)。
四、动态调整窗口大小
- 接收方主动通知接收方根据当前缓冲区剩余空间,在 ACK 中更新窗口大小(如window=2048)。
- 发送方自适应发送方根据网络拥塞情况(如超时重传),可能主动缩小窗口(与拥塞控制结合)。
五、滑动窗口与拥塞控制的关系
- 流量控制:窗口大小由接收方能力决定(避免接收方过载)。
- 拥塞控制:窗口大小由网络拥塞程度决定(避免网络过载)。
- 实际窗口:最终窗口大小取两者最小值(
min(接收窗口, 拥塞窗口)
)。
六、示例说明
初始窗口:左边界=0,右边界=4096(允许发送seq=0~4095) 发送数据:seq=0~4095 → 等待ACK 接收方处理后返回 ACK=2048,窗口=2048 → 新窗口:左边界=2048,右边界=4096(允许发送seq=2048~4095) 发送方继续发送 seq=2048~4095 → 再次等待ACK 若接收方缓冲区已满,下次ACK中窗口可能变
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
该专栏面向嵌入式开发工程师、C++开发工程师,包括C语言、C++,操作系统,ARM架构、RTOS、Linux基础、Linux驱动、Linux系统移植、计算机网络、数据结构与算法、数电基础、模电基础、5篇面试题目、HR面试常见问题汇总和嵌入式面试简历模板等文章。超全的嵌入式软件工程师面试题目和高频知识点总结! 另外,专栏分为两个部分,大家可以各取所好,为了有更好的阅读体验,后面会持续更新!!!