计算机网络tcp (tcp协议的主要功能)

传输控制协议(Transmission Control Protocol ,TCP):Internet传输层协议,提供面向连接、可靠、有序、字节流传输服务。

TCP协议的特点

  • TCP是面向连接的运输层协议:先建立连接,再传输数据,最后释放连接
  • 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的
  • TCP提供可靠交付的服务:通过TCP传输的数据,无差错、不丢失、不重复、按序到达
  • TCP提供全双工服务:TCP连接双方都设有发送缓存、接收缓存用来临时存放双向通信的数据。TCP在合适的时候将数据发送或应用程序在合适的时候读取数据
  • 面向字节流:流入到进程或从进程流出的字节序列,TCP把应用程序交下来的数据看成一连串的无结构的字节流

全双工(Full Duplex):是通讯传输的一个术语。通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时(瞬时)进行信号的双向传输,即A→B的同时B→A,是瞬时同步的。TCP是典型的全双工模式。

单工:就是在只允许一方向另一方传送信息,而不能反向传送 ,例如单行道。

半双工(Half Duplex):所谓半双工就是指一个时间段内只有一个动作发生,举个简单例子,一条窄窄的马路,同时只能有一辆车通过,当目前有两辆车对开,这种情况下就只能一辆先过,等到头儿后另一辆再开,这个例子就形象的说明了半双工的原理。早期的对讲机、以及早期集线器等设备都是基于半双工的产品。随着技术的不断进步,半双工会逐渐退出历史舞台。

TCP报文段结构

计算机网络tcpip协议在哪,怎么查看计算机的tcp和ip协议参数

TCP报文段结构

由图可知TCP报文结构由首部+数据部分组成,其中首部由固定首部、可选项、填充位组成

1、源端口号与目的端口号:各占16位也就是2个字节,共4个字节32位;主要是实现复用和分解应用层的数据。什么是传输层的复用与分解请参考之前的文章《计算机网络|传输层的复用与分解》。

2、序号字段:占32位,网络中传输的数据是按照字节流的形式,这个序号就是对应用层中的数据的每个字节进行的编号;

3、确认序号字段:期望从对方手中接收数据的字节序号,即该序号对应的字节尚未收到;

4、首部长度字段:占4位。指出TCP段的首部长度,以4字节为计算单位;

5、保留字段:占6位。保留为今后使用,目前使用0填充;

6、URG、ACK、PSH、RST、SYN、FIN:为标志位字段;各占1位,取值为0或1;

  • 紧急URG=1,表示紧急指针有效,它告诉系统此报文段有紧急数据,应尽快传送。
  • 确认ACK=1,确认序号字段有效;ACK=0时,确认序号字段无效。
  • 推送PSH=1,尽快将报文段中的数据交付接收应用进程,不要等缓存满了再交付。
  • 复位RST=1,TCP连接出现严重差错,释放连接,再重新建立TCP连接。
  • 同步SYN=1,该TCP报文段是一个建立新连接请求控制段或者同意建立新连接的确认段。
  • 终止FIN=1,TCP报文段的发送端数据已经发送完毕,请求释放连接。

7、接收窗口字段:占16位。向对方通告我方接收窗口的大小,主要用于流量控制。

8、校验和字段:占16位,计算方法与UDP校验和的计算方法相同,TCP协议号是6。具体的计算方式请参考之前的文章《计算机网络|UDP协议》

9、紧急指针字段:占16位。URG=1时,才有效。指出在本TCP报文段中紧急数据共有多少个字节。

10、选项字段:该字段长度可变,最短为0字节,最长为40字节。

11、填充字段:取值全为0,目的是为了整个首部长度是4字节的整倍数。

TCP链接管理

TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN+ACK,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接。

TCP的三次握手:

计算机网络tcpip协议在哪,怎么查看计算机的tcp和ip协议参数

TCP的三次握手

上图画出了TCP连接建立的过程。假定图中左端是客户A,右端是服务器B,一开始时,两端都处于CLOSED(关闭)状态。图中的方框分别是端点所处的状态。

1、服务器进程准备好接受外来的连接,这通常是通过调用socket,bind,listen这三个函数来完成,我们称之为被动打开(passive open)。然后服务器进程就处于LISTEN状态,等待客户的连接请求。

2、第一次握手,客户通过调用connect向服务器发出连接请求报文段(SYN=1,seq=x),客户端进入SYN_SEND(同步发送)状态。

  • SYN=1:建立连接请求控制段
  • seq=x:表示传输的报文段的第1个数据字节的序列号是x,此序列号代表整个报文段的序号。

3、第二次握手,服务器收到客户端连接请求后, 服务器发送确认报文段(SYN=1,ACK=1,seq=y, ack_seq=x+1),此时TCP服务器进入SYN-RCVD(同步收到)状态。

  • SYN=1:同意建立新连接的确认段
  • ack_seq=x+1:表示已经收到了序列号为x的报文段,准备接收序列号为x+1的报文段。
  • seq=y:服务器告诉客户确认报文段的序列号是y。

4、第三次握手,客户端在收到服务器的确认后,还要向服务器给出确认报文(ACK=1,seq=x+1,ack_seq=y+1)此时,客户端进入ESTABLISHED(建立连接)状态;第三次握手可携带数据。

  • seq=x+1:客户此次的报文段的序列号是x+1。
  • ack_seq=y+1:客户期望接收服务器序列号为y+1的报文段。

5、服务器收到客户的ACK后,也进入ESTABLISHED状态。在上述的建立连接的过程中,前后发送了三个报文段,因此TCP建立连接的过程也称之为次握手(three-way handshake)。

一道面试题,为什么TCP建立连接是三次握手,而不是两次握手?

当客户端接收到应答响应时,就会进入estabished状态,而服务器端只有收到客户端的连接请求后才会进入estabished状态。此时如果网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便超时重发请求,如果服务端正确接收并确认应答,双方便开始通信,通信结束后释放连接。此时,如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源。简单回答就是服务器在进入estabished状态时,他必须要确保客户端具有发送、接受数据的能力,二者缺一不可;同样的客户端在进入estabished状态时,他也必须确保服务器具有接受、发送数据的能力。

TCP的四次挥手:

数据传输结束后,通信的双方可以释放连接。数据传输结束后的客户A和服务器B都处于ESTABLISHED状态,然后进入释放连接的过程。

计算机网络tcpip协议在哪,怎么查看计算机的tcp和ip协议参数

TCP的四次挥手

1、第一次挥手,A的应用进程先发出释放连接报文段,并停止发送数据,主动关闭TCP连接。A把连接释放报文段首部FIN置1,其序号为seq = u。这时客户端进入FIN-WAIT-1(终止等待1)状态。

  • FIN=1:发送端数据发送完毕,请求释放连接。
  • seq=u:传输的第一个数据字节的序号是u

2、第二次挥手,服务器向客户端发送确认报文段(ACK=1,seq=v,ack_seq=u+1)

  • ACK=1:确认字号段有效。
  • ack_seq=u+1:服务器期望接收客户数据序号为u+1。
  • seq=v:服务器传输的数据序号是v。

此时,服务器状态由ESTABLISHED进入CLOSE_WAIT(关闭等待),第二次挥手标识A已经不需要给B发送数据了,但是B给A发送数据时,A是可以接收的。

3、第三次挥手,当A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。若B已经没有要向A发送的数据了,其应用进程就通知TCP释放连接,服务器向客户端发送释放连接报文段(FIN=1,ACK=1,seq=v+1,ack_seq=u+1)。

  • FIN=1:请求释放连接
  • ACK=1:确认字号段有效。
  • ack_seq=u+1:表示服务器期望接收客户数据序号为u+1。
  • seq=v+1:表示自己传输的第一个数据字节的序号是v+1。

这时B就进入了LAST-ACK(最后确认)状态,等待A的确认。

4、第四次挥手:当A收到B的连接释放报文段后,必须对此发出确认,客户端向服务器发送确认段(ACK=1,seq=u+1,ack_seq=w+1)

  • ACK=1:确认字号段有效。
  • ack_seq=v+1+1:表示客户期望接收服务器数据序号为v+1+1。
  • seq=u+1:表示客户传输的数据的序号是u+1。

客户端状态由FIN_WAIT_2进入到TIME-WAIT(时间等待)状态。请注意,现在TCP连接还没有释放掉。必须经过时间等待计时器(TIME-WAIT timer)设置的时间 2MSL后,A才进入到CLOSED状态。时间MSL叫做最长报文段寿命(Maximum Segment Lifetime)。

5、服务器只要收到客户端发出的确认,就进入CLOSED状态。由于释放TCP连接的过程需要发送四个报文段,因此释放连接的过程也称之为四次握手。细心的我们会发现服务器结束TCP连接的时间要比A早一些。

TIME_WAIT状态的意义

上述释放连接的过程中,A在TIME-WAIT状态必须等待2MSL,才进入CLOSED状态,上面也提到,这个MSL是报文段的最长寿命。为什么客户在TIME-WAIT状态必须2MSL的时间呢?这有两个理由:

1)可靠地实现TCP全双工连接的终止

客户A最后一个ACK报文段可能丢失,这样服务器B处于LAST-ACK状态而收不到确认。接下来B会超时重传FIN + ACK报文段,而A就能在2MSL时间内收到这个重传的FIN + ACK报文段,并再重传一次确认,并重新启动2MSL计时器。最后,A和B都正常进入CLOSED状态。

如果A在发送完最后一个ACK报文段后立即释放连接,那么就无法收到B重发的FIN + ACK报文段,因而也不会再发送一次确认报文段,这样B就无法按照正常步骤进入CLOSED状态。

2)防止“已失效的连接请求报文段”出现在本连接中

客户A在发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都会从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

TCP可靠数据传输

可靠就是保证接收方应用进程从缓冲区读出的字节流与发送方发出的字节流是完全一样的。

计算机网络通信中的可靠数据传输我们在之前的文章《计算机网络|停等协议与滑动窗口协议》中有介绍,这里我们来学习TCP实现可靠数据传输服务的工作机制:

分段:将应用层数据分割成TCP认为最适合发送的数据块。这个数据块的大小就叫最大报文段长度(Maximum Segment Size , MSS),他是指报文段中封装的应用层数据的最大长度。

序号:一个字节占用一个序号。序号字段指的就是一个报文段第一个字节的序号。为了便于理解,这里就把它称为1号包。假定这个包的负载长度是100字节,那么可以推算出下一个包的编号应该是101。这就是说,每个数据包都可以得到两个编号:自身的编号,以及下一个数据包的编号。接收方由此知道,应该按照什么顺序将它们还原成原始文件,万一发生丢包,也可以知道丢失的是哪一个包,然后让发送方重传该包。

ACK:接收方向发送方反馈接收状态,确认是否正确接收数据;TCP采用累计确认的方式。累计确认的概念在《计算机网络|停等协议与滑动窗口协议》中有介绍。

查错检测:利用差错编码实现数据包传输过程中的比特查错检测(甚至纠正)。

重传:发送方重新发送接收方没有正确接收的数据。

快速重传: TCP发送方接收到对相同序号的3次重复ACK,就说明被重复确认的报文段已丢失,这时候即便没有超时,也会重发该报文段。

计时器:在发送方引入计时器,解决数据丢失问题,发送方会为每个数据包添加一个发送时间,如果在指定的时间范围内没有收到ACK,就会重新发送。

TCP流量控制

为了提高信道的利用率TCP协议采用滑动窗口协议,发送窗口和接收窗口都大于等于1。所谓流量控制就是让发送方发送速率不要过快,让接收方来得及接收。TCP就是利用滑动窗口机制来实施流量控制。在通信过程中,接收方设置报文段的接收窗口字段来将窗口大小通知给发送方,发送方由此控制发送数据的速率。

考虑一种特殊的情况,就是接收方若没有缓存窗口可用,就会发送零窗口大小的报文,此时发送方将发送窗口设置为0,停止发送数据。之后接收方有足够的缓存,发送了非零窗口大小的报文,但是这个报文在中途丢失的,那么发送方的发送窗口就一直为零导致死锁。解决这个问题,TCP为每一个连接设置一个持续计时器(persistence timer)。只要TCP的一方收到对方的零窗口通知,就启动该计时器,周期性的发送一个零窗口探测报文段。对方就在确认这个报文的时候给出现在的窗口大小(注意:TCP规定,即使设置为零窗口,也必须接收以下几种报文段:零窗口探测报文段、确认报文段和携带紧急数据的报文段)。

TCP拥塞控制

计算机网络tcpip协议在哪,怎么查看计算机的tcp和ip协议参数

拥塞

网络拥塞:太多的主机以太快的速度向网络中发送太多的数据,超出了网络处理能力,导致大量数据分组拥挤在中间设备队列中等待转发,网络性能显著下降的现象。

拥塞控制:通过合理调度、规范、调整向网络中发送数据的主机数量、发送速率、数据量,以避免拥塞或消除已发生的拥塞。

计算机网络tcpip协议在哪,怎么查看计算机的tcp和ip协议参数

TCP拥塞控制的方法

拥塞窗口(CongWin):拥塞窗口是任何时刻内确定能被发送出去的字节数的控制因素之一,是阻止发送方至接收方之间的链路变得拥塞的手段。他是由发送方维护,通过估计链路的拥塞动态程度计算出来的,与由接收方维护的接收窗口大小并不冲突。congwin=1也就意味着1个RTT时间内只允许发送1个MSS。

RTT(Round-Trip Time):往返时延。是指数据从网络一端传到另一端所需的时间。通常,时延由发送时延、传播时延、排队时延、处理时延四个部分组成。

阈值(Threshold):拥塞窗口在每个阶段的临界值

计算机网络tcpip协议在哪,怎么查看计算机的tcp和ip协议参数

TCP拥塞控制

慢启动

慢启动算法的思路就是,不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加网络拥塞窗口的大小。在TCP连接建立时,使用慢启动算法,每经过1个RTT时间,拥塞窗口增大一倍。

如上图所示,在慢启动阶段阈值(Threshold)=16MSS,当拥塞窗口(CongWin)小于该阈值时就采用慢启动算法。如果第1个RTT,拥塞窗口(CongWin)等于2,则第2个RTT拥塞窗口(CongWin)等于4。

拥塞避免

拥塞避免算法让拥塞窗口缓慢增长,即每经过一个RTT就把发送方的拥塞窗口(CongWin)加1,而不是加倍。这样拥塞窗口按线性规律缓慢增长。简单说就是当拥塞窗口大于等于阈值时,每经过1个RTT,拥塞窗口的值加1。

如上图所示,当拥塞窗口(CongWin)等于16MSS时,再经过一个RTT,拥塞窗口(CongWin)等于17MSS,在这里他是线性增长的。

继续看上图,当拥塞窗口(CongWin)等于24MSS的时候,拥塞窗口(CongWin)发生了很大的变化,产生该变化的原因是检测到网络发生了拥塞。

发生什么样的场景算是出现了网络拥塞,或者叫报文丢失?

  • 收到三次重复确认。
  • 计时器超时。

计时器超时很好理解,就是已发送的报文在指定的时间内没有收到ACK。那什么是三次重复确认?拥有序号大于期望序号的失序报文段到达,TCP接收方立即发送重复ACK,指示下一个期望接收字节的序号。举个例子,接收方已经接收了1,2,3,4号报文,此时他期望接收5号报文,但是此时6号报文来了,这时接收方立即发送三次ACK5。这就是三次重复确认和产生三次重复确认的原因。

快速重传

快速重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认的报文就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。

快速恢复算法

快速恢复算法分两种场景:

1、当发生3次重复确认时,网络拥塞程度不是很严重。 阈值和拥塞窗口的调整方法:是直接从新的阈值开始,直接进入拥塞避免阶段;

  • 发生3次重复确认时,当前拥塞窗口为24MSS,当前阈值为16MSS。
  • 新的阈值:为当前拥塞窗口的一半;新的阈值= 24MSS÷2=12MSS
  • 新的拥塞窗口:调整为新的阈值;新的拥塞窗口=新的阈值=12MSS

2、当发生计时器超时,网络拥塞很严重,新的阈值等于当前窗口的一半,然后从慢启动阶段开始。

  • 新的阈值:为当前拥塞窗口的一半; 新的阈值= 24MSS÷2=12MSS
  • 新的拥塞窗口:调整为1MSS; 新的拥塞窗口=1MSS

总结:TCP拥塞窗口调整的基本策略是AIMD

  • 乘性减小(Multiplicative Decrease):不论在慢开始阶段或拥塞避免阶段,只要出现超时,就把慢开始门限值减半(当前拥塞窗口的一半)
  • 加性增大(Additive Increase):执行拥塞避免算法后,使拥塞窗口缓慢增大,以防止网络过早出现拥塞
  • 将这两种算法结合起来被称为AIMD算法
  • 拥塞避免不能完全避免拥塞,只是在拥塞避免阶段将拥塞窗口控制为线性增长,使网络不容易出现拥塞