TCP 协议

文章目录

    • 协议格式
    • 1面向连接:
      • 1.1三次握手(建立连接)
      • 1.2包序管理
      • 1.2四次挥手(断开连接)
    • 2可靠传输:
      • 一。保证数据可靠有序的到达对端:
        • 确认应答机制
        • 超时重传机制
      • 二。提高传输效率:
        • 1.提升自身发送数据量
          • 滑动窗口机制 rwnd
            • 滑动窗口丢包了咋办?
          • 快重传机制
        • 2.提升对端接收能力
          • 流量控制机制
          • 延时应答机制
            • 捎带应答机制
        • 3.提升网络转发能力
          • 拥塞控制机制cwnd
            • 拥塞控制的三个阶段:
      • 保活计时器/心跳机制
    • 面向字节流

TCP协议特点:

面向连接:发数据前先建立连接,沟通发送数据的细节。
可靠传输:保证数据高效,有序的到达对方。
面向字节流:数据没有明显的边界,接收方可按任意字节接收。

协议格式

TCP 协议_第1张图片

32位序号:请求方数据的起始序号。
32位确认序号:响应方发送,期望收到的下一个报文段的序号,告诉请求方下一次该发送的报文段序号。
4位首部长度:1111 B*4=60(20字节固定长度+40字节选项)。
16位窗口大小:告诉发送方最多还能接收多少数据。
16位紧急指针:指向紧急数据。(不用在发送和缓冲区停留)
URG: 紧急指针是否有效
ACK: 确认号是否有效
PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段
TCP选项:MSS:最大报文长度该值只包括TCP段的数据部分,一个TCP数据包中一次发送的最大字节数。在三次握手中最后取两者MSS最小值。MSS的默认值是536字节长,一般为1460字节。
注意:udp没有MSS的概念。

MTU:最大传输单元(字节),数据链路层属性,是网卡传输数据帧的限制,取决于传输设备。
MTU>=IP头部 + 传输层头部 + 有效载荷 。MSS受MTU限制,防止报文过大而丢包引发重传。
底层物理接口默认 MTU= 1500 byte,则 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte。

1面向连接:

1.1三次握手(建立连接)

TCP 协议_第2张图片

在发起起连接方调用connect(),后发起连接。
第三次握手的意义在于接送方确定自己的响应被请求方收到,否则状态还是SYN_RCVD.此时响应端的连接处于未完成连接队列,当第三次握手结束后,响应端的状态为ESTABL ISHED,此时的连接就放在了已完成队列,等着accept()来拿。

1.2包序管理

为了可靠传输,方便计算重传,TCP为每个发出的数据报进行了编号。
对于没有有效载荷的包,每次用一个编号就行,对于含有有效载荷是包,每个字节都占一个编号。
通信双发各自维护一套编号。
确认序号ACK = 发送方发送的序号+1(无有效载荷)
确认序号ACK = 发送方发送的序号+数据长度(有有效载荷)
ACK:ACK之前的数据都确认收到了,比如ACK = x+1,说明X+1之前的包都收到了下次可以从X+1开始发送了。
纯ACK包无需确认,也不消耗序号。

1.2四次挥手(断开连接)

TCP 协议_第3张图片

MSL:报文最大生存时间,TCP认为此包在网络上后收到多方ACK的最大时间,若超过这个时间就得重传。
2MSL:丢失ACK+重传FIN的总MSL.

2可靠传输:

一。保证数据可靠有序的到达对端:

确认应答机制

发送方发送的消息需要接收方确认,通过对序号的确认告诉对方期望发送的下一个序号,隐含意义是告诉对方此序号之前的数据都收到了。

超时重传机制

发出一个数据包时,如果发送端在RTO时间内没有收到此数据包的确认包时会触发超时重传机制,重新将此包发出。

TCP发生缓冲区是一段环形队列,在没有收到某个数据的确认之前是不可以被覆盖的,为了防止万一重传时方便重传。

RTO:超时重传时间,根据当时网络环境而动态变化。RTO=2RTT.
RTT:报文往返时间 SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT)
一个平滑的RTT称置为SRTT, alpha是一个平滑因子,取值为0.8或者0.9

二。提高传输效率:

1.提升自身发送数据量

之前建立连接那样,没法一个包都必须确认,效率实在太低。

滑动窗口机制 rwnd

窗口大小指的是无需等待确认应答而可以继续发送数据的最大值. 比如下图的1001-4000。
首次发送窗口内的数据时, 不需要等待任何ACK, 直接发送;
允许tcp将窗口内的数据(多个分组),同时发送,并行传递,暂时不用确认。
当发送端窗口内最早发送送的数据得到确认应答,窗口就可以继续向为发送的区域滑动。
滑动窗口机制很大的提升了TCP的发送效率。
TCP 协议_第4张图片

设滑动窗口最多容纳包序为1001-3001。在这里插入图片描述

如果收到了确认应答且ACK= 2001,则窗口向右移动一个包:2001-4001。
TCP 协议_第5张图片

如果收到了确认应答且ACK= 4001,则窗口向右移动3个包:4001-6001。
TCP 协议_第6张图片

如果:窗口内最左边的数据收到了确认,那么窗口就可以向右滑动以此类推,否则不能滑动,等待其他数据的确认。

滑动窗口丢包了咋办?

在这里插入图片描述

  1. 如果是部分ACK包丢失,没关系
    由于窗口内的数据发送暂时不需要确认。
    当接收方给发送方回复的ACK=2001包丢了,那么当发送方继续发2001-3000后,接收方会继续恢复确认包ACK=3001,隐含意思就是3000极其之前的数据都收到了。
    如果是发送方的数据包丢了:
    发送方发1001-2000的数据包丢了,接收方在收到2001及其之后的包后都会给发送回复ACK=1001而不是当前新收的包(比如,2001-4000),将后续收到的包缓存在接收缓存区。如果发送方连续三次都收到同一个确认的ACK序号(1001),说明从此序号(1001)开始的包丢失了,立刻触发快速重传机制 。发送方立刻重新发送此包,当接收方收到此包后立刻挥发ACK=目前已经连续接收到的最大的包序(4001);
快重传机制

当发送方方连续收到3次同样的ACK包确认序号,在触发超时重传之前立刻重发次包。

2.提升对端接收能力
流量控制机制

问题引入:当发送方发了大量数据时,接收方的TCP接收缓冲区有限。

做法:接收方没发一次数据接收方给应答的时候都带上自己的接收能力,通知发送方控制下次的发送量。

0号窗口通告:给发送说自己堵住了,接收能力为0.
恢复的方法:

  1. 接收方给发送方一个窗口更新通知。
  2. 发送方给接收方一个窗口探测数据包来探测对方的接收能力。
延时应答机制

接收方在应答的时候会在包头带上窗口大小,告诉对方自己的接收能力。
但是接收方并不是立马回应,而是适当托一会,期待应用层进量多取走数据,从而给发送方回应一个更大的窗口大小。

捎带应答机制

和延时应答机制一样,不过不是等待窗口的扩大,而是期望短期还有从接收方发给发送方的数据包,如果有就稍待将ACK置1,这样就可以顺便捎带应答。

3.提升网络转发能力

TCP的流滑动窗口是对收发数据量的控制手段,简称流控,但这只依赖于发送端和接收端(端对端的情况),并没有考虑网络模型4层一下点对点的影响,因此TCP专门为网络转发能力开辟了一个窗口。

拥塞控制机制cwnd

基于对网络转发能力的探测,TCP还维护了庸拥塞窗口cwnd,是由发送方维护的一个状态变量,会根据网络拥塞程度实时变化,对于发送方而言,发送数据量=min(cwnd,rwnd);
发送窗口:取决于接收方的接收能力。
拥塞窗口:取决网络转发能力。

拥塞控制的三个阶段:

少量的丢包是触发超时重传; 大量的丢包认为网络拥塞;

慢启动阶段:开始阶段,先发少量数据试探网络转发能力,窗口大小(发送量)为1个报文段556字节,是以指数能力增长,直到达到阈值(窗口最大值),开始到达拥塞避免阶段。

拥塞避免阶段:发送量继续以线性增长,直到发生拥塞(丢包),到达快恢复阶段。

快恢复阶段: 当发生丢包触发超时重传,每发生一次超时重传,就重新进行慢启动,且阈值变为当前转发发量的一半,窗口大小变为1个报文段。

MSS的默认值是536字节长。因此,所有在互联网上的主机都应该接受的报文段长度是536+20(固定首部长度)=556字节。

保活计时器/心跳机制

  1. 服务端每收到一次响应就重置保活计时器,通常为2小时。
  2. 若2小时已过,服务端就发一个探测报文,并且每隔75秒发送一个,当连续发送10次以后,仍没有收到对端的来信,则服务器端认为客户端出现故障,并会终止连接。

面向字节流

每建立一个连接,系统会创建一个socket,同时在内核中维护一个发送缓冲区和一个接收缓冲区。这两个缓冲区各干各的,互不干扰,读写数据自由匹配。因此也称为全双工

对于发送冲区:调用write()系统调用按照字节进行写入,如果一次写入的数据太多(>MSS),那么先把数据放在缓冲区,然后对数据进行分包发送;如果写入的太少,那么就在缓冲区中等到数据量差不多后择机而发。
对于接收冲区:数据从网卡到达接收缓冲区,通过系统调用read()按照字节进行读取数据。

你可能感兴趣的:(tcp/ip,网络,网络协议)