文章目录
TCP协议
机制:
- 点对点方式
- 一个发送方,一个接收方
- 传输可靠的、按序的字节流机制
- 流水线机制
- TCP拥塞控制和流量控制机制来设置窗口尺寸
- 发送方与接收方都能够缓存
- 全双工(full-duplex)
- 同一连接中能够传输双向数据流
- 面向连接
- 通信双方在发送数据之前必须建立连接
- 连接状态只在连接的两端中维护
- 在沿途节点中不维护
-
序列号:
- 表示本报文段所发送数据的第一个字节的编号。
- 在 TCP 连接中所传送的字节流的每一个字节都会按顺序编号。
- 建立TCP连接时,双方随机选择序列号
-
ACK确认号:表示接收方希望收到发送方下一个报文段的第一个字节数据的编号(序列号),也就是告诉发送方:我希望你(指发送方)下次发送给我的 TCP 报文段的序列号字段的值是这个确认号。
- 累计确认:该序列号之前的所有字节均已被正确接收到
-
TCP连接包括
- 两台主机上的缓存
- 连接状态变量
- socket等
TCP可靠数据传输
- TCP将IP层提供的不可靠服务转变为可靠的数据传输服务
- 使用流水线机制
- 累计确认机制
- 单一重传定时器(SR协议中发送方只重传那些没收到ACK的分组并且为每个分组设置定时器)
- TCP触发重传的事件
- 超时
- 收到重复ACK
设置定时器的超时时间:TimeoutInterval=EstimatedRTT+4*DevRTT
- EstimatedRTT的测量
- RTT(Round Trip Time,在此前HTTP连接中有涉及到):从客户端发送一个很小的数据包到服务器并返回所经历的时间,但是RTT是变化的
- SampleRTT:测量从段发出去到收到ACK的事件(忽略重传)
- EstimatedRTT:测量多个SampleRTT,求平均值形成RTT的估计值EstimatedRTT
- RTT变化值(DevRTT):SampleRTT与EstimatedRTT的差值
- 因此超过时间为:TimeoutInterval=EstimatedRTT+4*DevRTT
TCP发送方事件
- 从应用层收到数据
- 创建Segment
- 序列号时Segment第一个字节的编号
- 开启计时器
- 设置超时时间TimeOutInterval
- 超时
- 重传引起超时的Segment
- 重启定时器
- 收到ACK
- 如果确认此前未确认的Segment
- 更新SendBase
- 如果窗口中还有未被确认的分组
- 重新启动定时器
- 如果确认此前未确认的Segment
TCP重传机制
- 超时重传
在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据
-
两种情况发生超时重传:
- 数据包丢失
- 确认应答丢失
-
超时触发重传存在的问题是,超时周期可能相对较长。
- 快速重传(Fast Retransmit)
- 在定时器超时之前即进行重传
- 该机制来解决超时重发的时间等待,它不以时间为驱动,而是以数据驱动重传。
- 但是它依然面临着另外一个问题:就是重传的时候,是重传之前的一个,还是重传所有的问题。
- SACK选择性确认( Selective Acknowledgment)
- 这种方式需要在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将缓存的地址发送给发送方,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。
TCP连接管理
一个TCP连接由一个4元组构成,它们分别是两个IP地址和两个端口号。
更准确地说,一个TCP连接是由一对端点或套接字构成,其中通信的每一端都由一对(IP地址,端口号)所唯一标识。
一个TCP连接通常分为3个阶段:连接建立、数据传输(连接已建立)、连接释放,上图描述一次TCP连接的建立和关闭过程。
连接过程:
- 客户端发送一个SYN报文段(即一个在TCP头部的SYN位字段置位的TCP/IP数据包),并指明自己想要连接的端口号和它的客户端初始序列号(记为ISN©)。
- 服务器接收到客户端发送的SYN报文段后,也发送自己的SYN报文段作为响应,并包含了服务器的初始序列号ISN(s)。为了确认客户端的SYN,服务器将客户端SYN报文段中包含的ISN©数值加1后作为返回的ACK数值。因此,每发送一个SYN,序列号就会自动加1。
- 客户端接收到服务器发送的SYN报文段后,为了确认服务器的SYN,客户端将ISN(s)的数值加1后作为返回的ACK数值。
- 至此,连接被建立,以上过程也被称为三次握手。TCP通信可进入数据传输阶段。
关闭过程:
- 连接的主动关闭者(此例中是客户端)发送一个FIN位字段置位的TCP/IP数据包指明希望断开连接及接收者希望看到的自己当前序列号K。FIN报文段还包含了一个ACK段用于确认对方最近一次发来的数据L。
- 连接的被动关闭者(此例中是服务器)将K的数值加1作为响应的ACK值,以表明它已经成功接收到主动关闭着发送的FIN。被动发送者将身份转变为主动关闭者,发送自己的FIN报文段,序列号为L,ACK为K+1。
- 当前的主动关闭者(此时是客户端)发送一个FIN位字段置位的TCP/IP数据包指明希望断开连接,FIN报文段序列号为L,ACK为K+1。
- 当前的被动关闭者(此时是服务器)接收到信息后,将L加1后作为ACK,将K作为Seq,回应给主动关闭者,以确认上一个FIN。
- 至此,连接被关闭。