TCP的那点玩意儿

本文详细介绍了TCP协议的工作原理,包括TCP报文段的首部格式、可靠传输机制(基于连续ARQ和滑动窗口)、流量控制(通过可变大小的滑动窗口实现)以及连接管理的三次握手和四次挥手过程。通过这些机制,TCP确保了数据的有序、可靠传输,同时避免了拥塞问题。
摘要由CSDN通过智能技术生成

运输层

运输层为 应用进程 提供端到端的的逻辑通信。(补充:网络层主机之间 提供逻辑通信。)
运输层有两种不同的运输协议,即面向连接的TCP和无连接的UDP

TCP报文段的首部格式

了解一些TCP首部中常用的字段:
ACK: 确认ACK,仅当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。TCP规定,在建立连接后所有传送的报文段都必须把ACK置为1。
SYN: 同步SYN, 在连接建立时用来同步序号。当SYN = 1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在相应的报文段中使SYN=1和ACK = 1。因此,SYN置为1就表示这是一个连接请求或连接接受报文。
FIN: 用来释放一个连接。当FIN = 1时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。

TCP的可靠传输机制

TCP的可靠传输机制是基于连续ARQ协议和滑动窗口协议的。
TCP协议在发送方维持了一个发送窗口,发送窗口以前的报文段是已经发送并确认了的报文段,发送窗口中包含了已经发送但未确认的报文段允许发送但还未发送的报文段,发送窗口以后的报文段是缓存中还不允许发送的报文段。
发送方接收方发送报文时,会依次发送窗口内的所有报文段,并且设置一个定时器,这个定时器可以理解为是最早发送但未收到确认的报文段。如果在定时器的时间内收到某一个报文段的确认回答,则滑动窗口,将窗口的首部向后滑动到确认报文段的后一个位置,此时如果还有已发送但没有确认的报文段,则重新设置定时器,如果没有了则关闭定时器。
如果定时器超时,则重新发送所有已经发送但是未收到确认的报文段,并将超时的间隔设置为以前的两倍。当发送发收到接收方的三个冗余的确认应答后,这是一种指示,说明该报文段以后的报文段很有可能发生丢失了,那么发送方会启用快速重传的机制,就是当前定时器结束前,发送所有已发送的但确认的报文段。
接收方使用的是累计确认的机制,对于所有按序到达的报文段,接收方返回一个报文段的肯定回答。如果收到了一个乱序的报文 段,那么接方会直接丢弃, 并返回一个最近的按序到达的报文段的肯定回答。使用累计确认保证了返回的确认号之前的报文段都 已经按序到达了,所以发送窗口可以移动到已确认报文段的后面。
发送窗口的大小是变化的,它是由接收窗口剩余大小和网络中拥塞程度来决定的,TCP 就是通过控制发送窗口的长度来控制报文 段的发送速率。
但是 TCP 协议并不完全和滑动窗口协议相同,因为许多的 TCP 实现会将失序的报文段给缓存起来,并且发生重传时,只会重 传一个报文段,因此 TCP 协议的可靠传输机制更像是窗口滑动协议和选择重传协议的一个混合体

TCP的流量控制机制

一般来说,流量控制就是为了让发送方发送数据的速度不要太快,要让接收方来得及接收。TCP采用大小可变的滑动窗口进行流量控制,窗口大小的单位是字节。这里说的窗口大小其实就是每次传输的数据大小。

  • 当连接建立时,连接的每一端分配一个缓冲区来保存输入的数据,并将缓冲区的大小发送给另一端。
  • 当数据到达时,接收方发送确认,其中包含了自己剩余的缓冲区大小。(剩余的缓冲区空间的大小被称为窗口,指出窗口大小的通知称为窗口通告 。接收方在发送的每一确认中都含有一个窗口通告。)
  • 如果接收方应用程序读数据的速度能够与数据到达的速度一样快,接收方将在每一确认中发送一个正的窗口通告。
  • 如果发送方操作的速度快于接收方,接收到的数据最终将充满接收方的缓冲区,导致接收方通告一个零窗口 。发送方收到一个零窗口通告时,必须停止发送,直到接收方重新通告一个正的窗口。

TCP如何保证数据包传输的有序可靠?

对字节流分段并进行编号然后通过ACK回复和超时重发这两个机制来保证。
(1)为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区。
(2)并为每个已发送的数据包启动一个超时定时器
(3)如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;
(4)否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
(5)接收方收到数据包后,先进行CRC校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。

TCP的重传机制

由于TCP的下层网络(网络层)可能出现丢失、重复或失序的情况,TCP协议提供可靠数据传输服务。为保证数据传输的正确性,TCP会重传其认为已丢失(包括报文中的比特错误)的包。TCP使用两套独立的机制来完成重传,一是基于时间,二是基于确认信息
TCP在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。

TCP三次握手

请添加图片描述

三次握手其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接受能力发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。

刚开始客户端处于closed的状态,服务端处于Listen状态,进行三次握手

  • 第一次握手: 客户端给服务端发一个SYN报文,这时首部中的同部位SYN = 1, 同时选择一个初始序号seq = x 。TCP规定,SYN报文段(即SYN = 1的报文段)不能携带数据,但要消耗一个序号。这时TCP客户进程进入SYN-SENT(同步发送)状态

  • 第二次握手: 服务器收到客户端的SYN报文之后,会以自己的SYN报文作为应答,服务端在确认报文段中应把SYN位和ACK位都置1,确认号是ack = x + 1,同时也为自己选择一个初始序号 seq = y 。这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态

  • 第三次握手: TCP客户进程在收到服务端的确认后还要向服务端做出确认。确认报文段的ACK置为1,确认号ack = y + 1,而自己的序号seq = x + 1(初始为seq = x,所以第二个报文段要+1)。ACK报文段可以携带数据,不携带数据则不消耗序号。这时TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。当服务端收到客户端的确认后,也进入ESTABLISHED状态。

三次握手的作用是什么?

  • 第一次握手:客户端发送网络包,服务端收到了。
    这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
  • 第二次握手:服务端发包,客户端收到了。
    这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接受能力是否正常。
  • 第三次握手:客户端发包,服务端收到了。
    这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

三次握手过程中可以携带数据吗?
其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据
为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

TCP四次挥手

请添加图片描述

建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务器均可主动发起挥手动作。
刚开始双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:

  • 第一次挥手: 客户端进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。 客户端 把连接释放的报文段首部的终止控制位FIN置1,其序号seq = u,它等于前面已传送过的数据的最后一个字节的序号加1。这时 客户端 进入FIN-WAIT-1(终止等待1)状态,等待 服务器 的确认。请注意,TCP规定,FIN报文段即使不携带数据,它也消耗掉一个序号。
  • 第二次挥手: 服务器 收到连接释放报文段后即发出确认,确认号是 ack = u + 1,而这个报文段自己的序号是v,等于 客户端前面已经传送过的数据的最后一个字节的序号加1。然后 服务器就进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应该通知高层应用进程,因而从 客户端服务器这个方向的连接就释放了。这时TCP连接处于半关闭状态,即 客户端已经没有数据要发送了,但服务器若发送数据, 客户端仍要接收。也就是说,从服务器客户端这个方向的连接并未关闭,这个状态可能会持续一段时间。
    客户端收到来自服务器的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待服务器发出的连接释放报文段。
  • 第三次挥手:服务器 已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这时 服务器 发出的连接释放报文段必须使 FIN = 1。现假定服务器的序号为w,(在半关闭状态服务器可能有发送了一些数据)。服务器必须重复上次已经发送过的确认号 ack = u + 1。这时 服务器 就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  • 第四次挥手: 客户端在收到b的连接·释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack = w + 1,而自己的序号是seq = u + 1(根据TCP标准,前面发送过的FIN报文段要消耗一个序号)。然后进入到TIME-WAIT(时间等待)状态。请注意,现在TCP连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置时间2MSL后,客户端才进入到CLOSED状态。
    时间MSL叫做最长报文段寿命。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值