【Linux】网络--传输层--TCP协议基础

个人主页~


TCP协议基础

一、TCP协议格式

TCP(传输控制协议)报文结构是网络通信中重要的基础概念,用于实现可靠的数据传输

  • 源端口与目的端口

    • 作用:标识通信的两端进程(范围:0~65535)
    • 示例:HTTP默认使用80端口,HTTPS使用443端口
  • 序号

    • 作用:标记本报文段中数据的第一个字节在整个数据流中的位置,用于保证数据有序传输
    • 特点:SYN标志位为1时,序号为初始序号(ISN),后续序号递增
  • 确认序号

    • 作用:期望收到的下一个字节的序号,表示已成功接收该序号之前的数据
    • 规则:确认号 = 已接收数据的最后一个字节序号 + 1
  • 首部长度

    • 作用:指示TCP头部的长度(以4字节为单位),最大值为60字节(默认20字节)
    • 原因:由于选项字段的存在,头部长度可能变化
  • 标志位

    用来区分TCP报文的类型

    • URG:紧急指针有效,通知接收方优先处理紧急数据
    • ACK:确认号是否有效
    • PSH:通知接收方立即将数据提交给上层应用,即从TCP缓冲区读走
    • RST :重置连接,用于异常中断
    • SYN :同步序号,用于请求建立连接
    • FIN :终止连接,用于断开连接
  • 窗口大小

    • 作用:告知发送方当前接收方的可用缓冲区大小,用于流量控制
    • 单位:字节数,范围0~65535(通过窗口扩大因子可扩展)
  • 校验和

    • 作用:验证TCP报文段(包括头部和数据)在传输过程中是否损坏
    • 计算范围:TCP头部、数据部分,以及伪首部(包含IP地址和协议号)
  • 紧急指针

    • 作用 :当URG标志位为1时,若当前段起始序列号为seq,紧急指针为ptr,则紧急数据的范围就是seqseq + ptr - 1
    • 注意:紧急数据会被识别并提前处理,但紧急数据是TCP中的一种特殊机制,实际中较少使用
  • 选项与填充

    • 常见选项
      • 最大段长度:协商每次传输的最大数据量
      • 时间戳选项:用于计算往返时间和防止序号回绕
    • 填充:确保头部长度为4字节的整数倍
  • 数据部分

    • 内容:封装上层协议(如HTTP、FTP)的数据
    • 注意:TCP头部不含长度字段,数据长度通过IP头部的总长度减去IP头部长度和TCP头部长度计算得出

TCP与UDP的对比

特性 TCP UDP
连接性 面向连接(需三次握手) 无连接(直接发送)
可靠性 可靠(重传、校验) 不可靠(尽力而为)
首部开销 20~60字节(含选项) 8字节
适用场景 文件传输、HTTP等 视频流、DNS查询等

通过以上结构,TCP能够实现可靠、有序、流量可控的数据传输,是互联网核心协议之一

二、TCP协议机制

  • TCP拥有发送缓冲区和接收缓冲区两个缓冲区,发送信息的流程是:
    • 写入缓冲区:应用程序需要发送信息时,将信息写入用户缓冲区
    • 写入内核 :调用wirte函数,将信息从用户缓冲区复制到发送缓冲区
    • 发送数据:通过网卡和内核TCP模块处理将数据存入另一用户的接受缓冲区
    • 写入用户区 :调用read函数,将信息从接收缓冲区拷贝到用户缓冲区中
    • 应用程序获取数据:应用程序从用户缓冲区读取数据

这里发送和接收的数据就是上面我们提到的协议格式下的报文

三、确认应答机制

TCP确认应答机制是确保数据可靠传输的核心机制之一,也是区别于UDP的核心特点之一,在保证可靠性的同时,尽可能优化传输效率

  • 基本概念

    • 作用:接收方通过发送确认消息,告知发送方数据已成功接收,避免数据丢失
    • 可靠性保证 :发送方在超时未收到确认消息 时,会重传 数据,叫做超时重传
  • 工作流程

    • 序号

      • 每个TCP报文段都会携带一个序号,标识该段数据在数据流中的位置
    • 确认号

      • 接收方通过确认消息返回确认号,表示下一个期望接收的数据序号
      • 规则 :确认号 = 已成功接收的最后一个字节序号 + 1
        • 示例:若接收方成功接收序号1000~1999的数据段,确认号为2000,表示期望接收后续数据
    • 确认应答机制

      • 单次确认:发送方发送数据后,等待接收方的确认消息
      • 批量确认 :滑动窗口技术允许发送方连续发送多个数据段,接收方只需确认最后一个连续收到的序号,也叫累积确认
  • 确认类型

    • 累积确认

      • 特点:接收方仅确认最后一个连续收到的数据段,忽略中间丢失的段
      • 优点:实现简单,减少确认消息数量
      • 缺点 :若中间某个段丢失,发送方需重传后续所有段,这也叫做线头阻塞
    • 选择性确认

      • 机制:接收方通过选择性确认选项告知发送方哪些段已接收,哪些段丢失
      • 优点:发送方仅重传丢失的段,避免冗余重传
      • 适用场景:高带宽延迟网络,如卫星链路
  • 优化策略

    • 延迟确认

      • 机制:接收方延迟发送确认消息(通常最多200ms),合并多个确认以减少网络流量
      • 适用场景:批量数据传输,如文件下载
    • 确认应答压缩

      • 机制:在高速网络中,减少冗余确认消息的发送频率
  • 示例说明

    • 发送方发送数据段:序号1000(1000字节) → 序号2000(1000字节) → 序号3000(1000字节),接收方收到序号1000和3000的段:
      • 发送确认应答 2000(累积确认,仅确认连续段),那序号2000和序号3000的数据段都会重传
      • 若支持选择性确认,额外告知序号3000已接收,发送方根据确认应答和选择性确认,仅重传序号2000的段

这个确认应答呢我有一个小技巧来记忆,发送方发送数据段之后,比如说发送了序号1000,它代表着1000~1999,那我下一个是不是就要要2000了,那么我们确认应答发送的就是2000

四、捎带应答

我们将捎带应答这个解释过程简化为两张图,黑色斜线表示通信双方,正常情况下如下图所示,左边给右边发送一个报文,右边要给左边一个应答,表示已经收到数据,当然这里的应答也是严格按照TCP报文结构来的,发送的也是一个完整的TCP报文(至少有报头),之后右边再给左边发送报文,左边再给右边发送一个应答

但是这样的效率会很低,在正常情况下,双方不会这样进行通信,而是将应答和要发送的TCP数据整合成一条报文,此时发送的这条报文既是应答又是数据,减少开支

五、三次握手和四次挥手

1、应用层行为

这边我们举一个客户端和服务端的例子

  • 三次握手
    • 服务端应用层行为(服务器初始化 ):服务端是要先开启的,应用层通过调用socket分配一个文件描述符,然后调用bind函数将这个文件描述符与服务器地址端口绑定,然后调用listen函数进入监听状态,然后调用accept函数阻塞等待客户端的连接,此时服务端开启完毕
    • 客户端应用层行为(建立连接 ):客户端后开启,应用层通过调用socket分配一个文件描述符,然后调用connect函数向服务器发起将文件描述符与服务器地址端口连接请求,connect函数会发出SYN段并阻塞等待服务器应答(第一次握手)
    • 服务器收到客户端SYN ,会应答一个SYN-ACK段表示同意建立连接(第二次握手)
    • 客户端收到SYN-ACK 后会从connect函数返回,同时应答一个ACK段(第三次握手)
  • 数据传输
    • 建立连接后,TCP协议会提供全双工的通信服务,即同一条连接同一时刻,通信双方可以同时写同时读
    • 服务器从accept函数返回后立刻调用read函数,读socket就和读管道一样,没有数据就阻塞等待
    • 这时客户端调用write发送请求给服务器,服务器收到后从read返回,对客户端的请求进行处理,在此期间客户端调用read函数阻塞等待服务器的应答
    • 服务器调用write函数将处理结果发回客户端,再次调用read函数阻塞等待下一条请求
    • 客户端收到后从read函数返回,发送下一条请求
    • 以①~⑤循环
  • 四次挥手
    • 客户端调用close关闭连接,此时客户端会向服务器发送FIN段(第一次挥手)
    • 服务器收到FIN 后,回应一个ACK ,同时read返回0(第二次挥手)
    • read返回之后,服务器就知道客户端关闭了连接,也调用close关闭连接,这个时候服务器会向客户端发送一个FIN(第三次挥手)
    • 客户端收到FIN ,返回一个ACK给服务器(第四次挥手)

2、三次握手---建立连接

三次握手的机制就是建立在捎带应答上的,捎带应答不仅是通信时的一种策略,并且是建立连接时的策略

三次握手也可以是四次握手,理由和上面一样,这里的第二次握手本来也是两条消息合并发送而已

  • 对于客户端来说,当我们将ACK 发出了,我们就认为连接已经建立成功了,此时客户端的状态就是上上图的ESTABLISHED,建立描述该连接的客户端属性结构体就被建立了,我们TCP协议对于连接的管理当然也是先描述后组织的,此时客户端连接的属性结构体就通过指针被队列组织管理了

  • 对于服务器来说,在开启监听状态LISTEN 后,收到建立连接报文SYN ,会对客户端进行确认并请求建立连接ACK+SYN ,然后在收到客户端确认报文ACK之后建立描述该连接的服务器属性结构体,然后这个结构体也会被管理起来

3、四次挥手---断开连接

  • 对于客户端来说,当没有数据要读取或发送的时候,发送结束报文FIN ,进入等待状态1,FIN_WAIT1 ,然后一直等待,在接收到服务器的应答ACK 后进入等待状态2,FIN_WAIT2 ,然后一直等待,在收到服务器FIN 报文时,发送应答ACK 并转为TIME_WAIT 状态,等待一个2MSL(报文最大生存时间)的时间,然后进入CLOSED状态

  • 对于服务器来说,在接收到客户端发来的结束报文FIN 之后,如果自己也没有啥要发给客户端的,那么发送应答ACK 并转为等待状态CLOSE_WAIT ,处理之前的数据,处理完后向客户端发送结束报文FIN ,并转为最终回应状态LAST_ACK ,在接收到客户端的ACK的报文后,关闭连接


今日分享就到这里了~

相关推荐
凯尔萨厮2 分钟前
Hibernate(学习笔记)
笔记·学习·hibernate
lunzi_08262 分钟前
【学习笔记】《Python编程 从入门到实践》第5章:if语句、条件测试与列表处理实战
笔记·python·学习
fanged10 分钟前
蓝牙学习3(简易蓝牙控制)(TODO)
笔记
SXJR11 分钟前
langchain4j是如何保证tools或者funcation call不出错的
java·网络·数据库·ai·语言模型
仙俊红14 分钟前
rocketmq学习
大数据·学习·rocketmq
CairBin15 分钟前
SideSail——Ubuntu 26.04(GNOME 50)侧边栏插件,支持设备信息剪贴板和米家设备简单控制
linux·ubuntu
子一!!18 分钟前
spring基础学习
java·学习·spring
howard200519 分钟前
3.4 Linux目录操作
linux·目录操作
Sagittarius_A*22 分钟前
H3CSE 高性能园区网:NQA 网络质量分析详解
网络
m0_7308011322 分钟前
ospf实验作业
网络