tcp首尾及总结

一、TIME_WAIT和CLOSE_WAIT

1. TIME_WAIT 状态

1.1 什么是 TIME_WAIT?
  • 定义TIME_WAIT 是 TCP 连接关闭时的一个状态,出现在主动关闭连接的一方(即先发送 FIN 包的一方)。

  • 触发条件 :在 TCP 四次挥手的最后阶段,主动关闭方在收到对方的 ACK 后,会进入 TIME_WAIT 状态。

  • 持续时间2 * MSL(Maximum Segment Lifetime,报文最大生存时间),默认约 60 秒(Linux)。

1.2 为什么需要 TIME_WAIT?
  • 确保最后的 ACK 可靠到达 :如果最后的 ACK 丢失,对方会重发 FIN,此时处于 TIME_WAIT 的一方可以重新发送 ACK

  • 防止旧报文干扰新连接 :旧连接的延迟报文可能被误认为属于新连接(例如相同四元组的连接)。TIME_WAIT 会等待足够时间让网络中残留的旧报文消失。

1.3 TIME_WAIT 导致 bind 失败的原因
  • 问题场景 :在高并发短连接的服务端(如 HTTP 短连接),主动关闭方(服务端)会积累大量 TIME_WAIT 状态的连接。

  • 资源耗尽 :每个 TIME_WAIT 连接会占用一个本地端口。当可用端口耗尽时,新连接无法绑定端口,导致 bind() 失败(错误:Address already in use)。

1.4 解决方法
  • (1) 允许端口重用

    修改内核参数,允许 TIME_WAIT 端口被新连接复用:

    bash 复制代码
    # 修改 /etc/sysctl.conf
    net.ipv4.tcp_tw_reuse = 1    # 允许复用 TIME_WAIT 端口(仅对客户端有效)
    net.ipv4.tcp_tw_recycle = 0  # 谨慎使用,可能影响 NAT 环境
  • (2) 调整 TIME_WAIT 超时时间

    缩短 TIME_WAIT 的持续时间(默认 60 秒):

    bash 复制代码
    net.ipv4.tcp_fin_timeout = 30  # 缩短到 30 秒
  • (3) 增加端口范围

    扩大本地端口池范围:

    bash 复制代码
    net.ipv4.ip_local_port_range = 10000 65000
  • (4) 服务端避免主动关闭连接

    如果是服务端,尽量让客户端主动关闭连接(例如 HTTP 协议中,服务端设置 Connection: close 后由客户端关闭)。


2. CLOSE_WAIT 状态

2.1 什么是 CLOSE_WAIT?
  • 定义CLOSE_WAIT 是被动关闭连接的一方(即收到 FIN 包的一方)所处的状态。

  • 触发条件 :当对方发送 FIN 包关闭连接时,本地会进入 CLOSE_WAIT 状态,等待应用程序处理完数据后发送 FIN 包。

2.2 为什么会出现大量 CLOSE_WAIT?
  • 根本原因 :应用程序未正确关闭连接。

    例如:服务端收到客户端的 FIN 后,进入 CLOSE_WAIT 状态,但代码未调用 close()shutdown() 发送 FIN

  • 风险 :大量 CLOSE_WAIT 连接会占用文件描述符,导致资源泄漏。

2.3 解决方法
  • (1) 检查代码逻辑

    确保所有连接在使用完毕后正确关闭:

    python 复制代码
    # 示例代码(Python)
    try:
        conn, addr = server_socket.accept()
        # 处理数据...
    finally:
        conn.close()  # 必须显式关闭!
  • (2) 设置超时机制

    为连接设置超时,避免长时间卡在 CLOSE_WAIT

    bash 复制代码
    # 内核参数(全局)
    net.ipv4.tcp_keepalive_time = 600  # 600 秒无活动后发送探测包

3. 总结

状态 角色 原因 解决方法
TIME_WAIT 主动关闭方 确保连接彻底关闭 端口复用、调整内核参数
CLOSE_WAIT 被动关闭方 应用程序未关闭连接 检查代码、显式调用 close()

关键点

  • TIME_WAIT 是协议设计的保护机制,不要试图完全消除它,而是优化其影响。

  • CLOSE_WAIT 是程序 BUG,必须通过代码修复!


二、TCP 滑动窗口和流量控制

  • 1.基本概念
    • TCP 滑动窗口是 TCP 协议用于实现流量控制和提高传输效率的一种机制。它允许发送方在收到接收方的确认之前,连续发送多个数据段,而不必每发送一个数据段就等待确认。窗口的大小表示发送方可以在未收到确认的情况下发送的数据量。
  • 2.工作原理
    • 窗口大小的确定:发送方和接收方在建立 TCP 连接时,会在双方的 TCP 报头中协商窗口大小。这个窗口大小会根据网络状况和接收方的处理能力等因素动态调整。
    • 数据发送与滑动:发送方在发送数据时,会维护一个发送窗口。窗口内的数据是可以被发送方发送出去的数据。当发送方发送了窗口内的数据后,只要没有收到接收方的确认,就不能再发送超过窗口大小的数据。当发送方收到接收方对窗口内某部分数据的确认后,窗口会向前滑动,允许发送方发送更多的数据。
    • 举例说明:假设发送方的窗口大小为 3,初始时窗口内包含序号为 1、2、3 的数据段。发送方发送这三个数据段后,窗口就不能再滑动,直到收到接收方的确认。如果接收方成功收到了序号为 1 的数据段并发送了确认,那么发送方的窗口就会向前滑动一个位置,此时窗口内包含序号为 2、3、4 的数据段,发送方就可以发送序号为 4 的数据段了。
TCP 流量控制
  • 1.基本概念
    • 流量控制是 TCP 协议为了防止发送方发送数据过快,导致接收方无法及时处理而产生数据丢失或拥塞的一种机制。它通过让接收方控制发送方的发送速度来实现。
  • 2.实现方式
    • 利用滑动窗口实现:接收方通过在 TCP 报头中的窗口字段,告诉发送方自己当前能够接收的数据量,即接收窗口大小。发送方根据接收方反馈的接收窗口大小来调整自己的发送窗口大小,从而控制发送数据的速度。
    • 动态调整窗口大小:接收方会根据自己的缓存空间和处理能力动态调整接收窗口的大小。当接收方的缓存空间快满时,它会减小接收窗口大小,通知发送方减慢发送速度;当接收方处理完一些数据,缓存空间有空闲时,它会增大接收窗口大小,允许发送方发送更多的数据。
    • 举例说明:如果接收方的缓存空间为 1000 字节,当前已经接收了 500 字节的数据还未处理,那么它会将接收窗口大小设置为 500 字节,并在发送给发送方的确认报文中告知发送方。发送方收到这个确认报文后,就会将自己的发送窗口大小调整为 500 字节,只发送 500 字节的数据,直到收到接收方新的确认报文和窗口大小信息。

滑动窗口与流量控制的关系
  • 滑动窗口是实现流量控制的具体手段,而流量控制是滑动窗口机制的主要目的之一。通过滑动窗口的动态调整,TCP 协议能够实现高效、可靠的数据传输,同时避免网络拥塞和数据丢失,确保数据传输的稳定性和效率。

滑动窗口
基本概念

在《图解 TCP/IP》中提到,TCP 滑动窗口是一种流量控制机制,允许发送方在未收到接收方确认时,连续发送多个数据段,以此提高数据传输效率。滑动窗口就像一个可以在数据序列上滑动的窗口,窗口内的数据是可以被发送的。

窗口的构成与工作机制
  • 窗口大小:窗口大小代表了发送方在未收到确认的情况下能够发送的数据量。它由接收方告知发送方,通过 TCP 报头中的 "窗口大小" 字段来传递。例如,接收方告知发送方窗口大小为 500 字节,那么发送方最多可以连续发送 500 字节的数据而无需等待确认。
  • 窗口滑动:当发送方发送了窗口内的数据后,若收到接收方对部分数据的确认,窗口就会向前滑动,允许发送方继续发送后续的数据。比如,发送方窗口内包含序号为 1 - 500 的字节数据,发送完后收到接收方对序号 1 - 100 字节数据的确认,此时窗口就会向前滑动 100 个字节,变为包含序号 101 - 600 的字节数据,发送方可以接着发送这部分数据。
图解tcp/ip示例理解

书中通常会用形象的图示来展示滑动窗口的工作过程。假设发送方和接收方建立连接后,接收方通告窗口大小为 4 个数据段。发送方依次发送数据段 1、2、3、4,在未收到确认前,窗口停留在这 4 个数据段上。当收到接收方对数据段 1 的确认后,窗口向前滑动一个位置,发送方可以发送数据段 5。

TCP 流量控制
基本原理

TCP 流量控制的核心目标是防止发送方发送数据过快,导致接收方因处理不及而出现数据丢失。《图解 TCP/IP》强调,这主要通过接收方动态调整窗口大小来实现。接收方会根据自身的缓存空间和处理能力,在 TCP 报头中告知发送方当前能够接收的数据量。

动态调整窗口大小
  • 窗口减小:当接收方的缓存空间接近满时,它会减小通告给发送方的窗口大小。例如,接收方原本通告窗口大小为 1000 字节,随着缓存逐渐被填满,它将窗口大小减小到 200 字节,发送方收到这个信息后,就会相应地减少发送数据的量。
  • 窗口增大:当接收方处理完部分数据,缓存空间有空闲时,会增大窗口大小。比如接收方处理完 500 字节的数据后,将窗口大小从 200 字节增大到 700 字节,发送方就可以发送更多的数据。
结合滑动窗口实现流量控制

滑动窗口是实现流量控制的具体手段。发送方根据接收方通告的窗口大小来调整自己的发送窗口,从而控制发送数据的速度。例如,接收方通告窗口大小为 300 字节,发送方的发送窗口就限制在 300 字节以内,只能发送这个范围内的数据。当接收方的窗口大小发生变化时,发送方的发送窗口也会相应调整,确保数据的发送速度与接收方的处理能力相匹配。

滑动窗口和流量控制的意义

《图解 TCP/IP》指出,滑动窗口和流量控制机制使得 TCP 能够在不同性能的设备和网络环境下实现高效、可靠的数据传输。通过动态调整窗口大小,避免了数据的堆积和丢失,提高了网络资源的利用率,保证了通信的稳定性和效率。


ctp总结

1. TCP 基础概念

协议定义与作用

TCP 是一种面向连接的、可靠的、基于字节流的传输层通信协议。它主要负责在应用程序之间提供可靠的数据传输服务,确保数据在传输过程中不丢失、不重复且按序到达。

与 UDP 的对比
  • 连接性:TCP 是面向连接的,通信前需要建立连接;UDP 是无连接的,无需建立连接即可发送数据。
  • 可靠性:TCP 提供可靠传输,通过确认机制、重传机制等保证数据准确到达;UDP 不保证可靠性,数据可能丢失、重复或乱序。
  • 传输效率:由于 TCP 需要建立连接、维护状态和进行错误处理,其传输效率相对较低;UDP 开销小,传输效率高。
  • 应用场景:TCP 适用于对数据准确性要求高的场景,如文件传输、网页浏览等;UDP 适用于对实时性要求高、对少量数据丢失不太敏感的场景,如视频流、音频流等。

2. TCP 报文格式

源端口和目的端口
  • 各占 16 位,用于标识发送方和接收方的应用程序。源端口是发送方应用程序使用的端口,目的端口是接收方应用程序监听的端口。
序号
  • 占 32 位,用于标识 TCP 发送的字节流中每个字节的编号。发送方在发送数据时,会为每个字节分配一个序号,接收方可以根据序号对数据进行排序和确认。
确认号
  • 占 32 位,是期望收到对方下一个报文段的第一个数据字节的序号。表示接收方已经正确收到了该序号之前的数据,希望接下来收到该序号对应的数据。
首部长度
  • 占 4 位,指示 TCP 首部的长度,单位是 32 位字(即 4 字节)。由于 TCP 首部可能包含可选字段,首部长度不固定,通过该字段可以确定首部的实际长度。
保留位
  • 占 6 位,目前保留未用,为未来的扩展预留。
控制位
  • 包括 URG(紧急指针有效)、ACK(确认号有效)、PSH(推送数据)、RST(重置连接)、SYN(同步序号,用于建立连接)、FIN(终止连接)等标志位,用于控制 TCP 连接的建立、数据传输和关闭等操作。
窗口大小
  • 占 16 位,用于流量控制,指示接收方当前的接收窗口大小,即接收方允许发送方发送的数据量。
校验和
  • 占 16 位,用于检验 TCP 报文段在传输过程中是否发生错误。发送方计算校验和并填充到该字段,接收方重新计算校验和并与接收到的校验和进行比较,若不一致则认为报文段有错误。
紧急指针
  • 占 16 位,只有当 URG 标志位为 1 时有效,指示紧急数据在报文段中的位置。

3. TCP 连接建立与关闭

三次握手(建立连接)
  • 客户端向服务器发送 SYN 包:客户端向服务器发送一个 TCP 报文段,其中 SYN 标志位设置为 1,同时选择一个初始序号(ISN),表示客户端希望建立连接。
  • 服务器回应 SYN + ACK 包:服务器收到客户端的 SYN 包后,向客户端发送一个包含 SYN 和 ACK 标志位都为 1 的报文段。SYN 表示服务器同意建立连接,并选择自己的初始序号;ACK 表示对客户端 SYN 包的确认,确认号为客户端的初始序号加 1。
  • 客户端发送 ACK 包:客户端收到服务器的 SYN + ACK 包后,向服务器发送一个 ACK 标志位为 1 的报文段,确认号为服务器的初始序号加 1,表示客户端确认连接建立。
四次挥手(关闭连接)
  • 客户端发送 FIN 包:客户端完成数据发送后,向服务器发送一个 FIN 标志位为 1 的报文段,表示客户端不再发送数据,请求关闭连接。
  • 服务器回应 ACK 包:服务器收到客户端的 FIN 包后,向客户端发送一个 ACK 标志位为 1 的报文段,确认号为客户端的序号加 1,表示服务器已经收到客户端的关闭请求。
  • 服务器发送 FIN 包:服务器完成数据发送后,向客户端发送一个 FIN 标志位为 1 的报文段,表示服务器也不再发送数据,请求关闭连接。
  • 客户端回应 ACK 包:客户端收到服务器的 FIN 包后,向服务器发送一个 ACK 标志位为 1 的报文段,确认号为服务器的序号加 1,表示客户端已经收到服务器的关闭请求,连接正式关闭。

4. TCP 可靠传输机制

确认机制
  • 接收方收到数据后,会向发送方发送确认报文,确认号表示期望收到的下一个字节的序号。发送方根据确认号来判断哪些数据已经被正确接收。
重传机制
  • 超时重传:发送方发送数据后,会启动一个定时器。如果在定时器超时之前没有收到接收方的确认,发送方会重新发送该数据。
  • 快速重传:当发送方连续收到 3 个重复的确认时,认为有一个数据段丢失,立即重传该数据段,而不必等待超时。
滑动窗口机制
  • 发送方和接收方分别维护一个发送窗口和接收窗口。发送窗口表示发送方在未收到确认的情况下可以发送的数据范围,接收窗口表示接收方能够接收的数据范围。通过窗口的滑动,实现高效的数据传输和流量控制。

5. TCP 流量控制

基本原理
  • 流量控制是为了防止发送方发送数据过快,导致接收方无法及时处理而产生数据丢失。接收方通过在 TCP 报头中的窗口字段告知发送方自己当前的接收窗口大小,发送方根据该窗口大小调整自己的发送速度。
动态调整(滑动窗口)
  • 接收方会根据自身的缓存空间和处理能力动态调整接收窗口大小。当缓存空间快满时,减小窗口通知发送方减慢速度;当处理完数据,缓存有空闲时,增大窗口允许发送更多数据。

6. TCP 拥塞控制

拥塞概念
  • 拥塞是指网络中出现过多的数据,导致网络性能下降,如延迟增加、吞吐量降低等。
主要算法
  • 慢开始:初始时发送方拥塞窗口(cwnd)设为较小值(通常为 1 个 MSS,最大段大小),每收到一个确认,cwnd 就增加 1 个 MSS。当 cwnd 达到慢开始门限(ssthresh)时,进入拥塞避免阶段。
  • 拥塞避免:每经过一个往返时延(RTT),cwnd 只增加 1 个 MSS,使拥塞窗口缓慢增长。
  • 快重传:当发送方连续收到 3 个重复确认时,认为有一个数据段丢失,立即重传该数据段,而不必等待超时重传。
  • 快恢复:执行快重传后,将 ssthresh 减半,cwnd 设为 ssthresh,然后进入拥塞避免阶段。

7. TCP 其他特性

延迟应答
  • 接收方收到数据后,不立即发送确认,而是等待一段时间。这样做可以在等待期间,如果有更多的数据到达,在一个确认中确认更多的数据,提高传输效率。但有时间和数据量的限制。
捎带应答
  • 当接收方有数据要发送给发送方时,将对之前收到数据的确认信息放在自己要发送的数据的 TCP 报头中,一起发送给发送方,减少网络中的报文数量。
面向字节流
  • TCP 将应用层交付的数据看作无结构的字节流进行传输,发送方将数据拆分成多个 TCP 报文段发送,接收方将接收到的报文段重新组装成完整的字节流交付给应用层。

8. TCP 异常处理

客户端异常关闭
  • 客户端突然断电、崩溃等异常关闭,没有正常发送 FIN 包。服务器继续发送数据,一段时间后未收到确认,会触发超时重传。多次重传失败后,服务器会关闭连接。
服务器异常关闭
  • 服务器异常关闭,客户端可能还在发送数据。客户端发送的数据得不到确认,触发超时重传。若服务器一直未响应,客户端最终会关闭连接。
网络中断
  • 在数据传输过程中,网络突然中断。发送方和接收方都无法收到对方的报文。发送方会不断重传数据,当重传次数达到上限或超时时间过长,会关闭连接。网络恢复后,若双方都未关闭连接,可继续正常通信。
相关推荐
livefan1 小时前
油田安全系统:守护能源生命线的坚固壁垒
网络·安全
Christal_pyy3 小时前
树莓派4基于Debian GNU/Linux 12 (Bookworm)添加多个静态ipv4网络
linux·网络·debian
csbDD4 小时前
2025年网络安全(黑客技术)三个月自学手册
linux·网络·python·安全·web安全
荔枝荷包蛋6665 小时前
【Linux】HTTP:Cookie 和 Session 详解
网络·网络协议·http
EasyNVR5 小时前
EasyRTC智能硬件:实时畅联、沉浸互动、消音护航
运维·服务器·网络·安全·音视频·webrtc·p2p
劉煥平CHN5 小时前
RabbitMQ的脑裂(网络分区)问题
网络·分布式·rabbitmq
阿湯哥6 小时前
越权漏洞及其修复方法
网络·安全·web安全
遥遥远方 近在咫尺6 小时前
HTTPS原理
网络协议·https
编程星空6 小时前
HTTP 和 HTTPS 的区别
网络协议·http·https
Natsuagin7 小时前
轻松美化双系统启动界面与同步时间设置(Windows + Ubuntu)
linux·windows·ubuntu·grub