前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP & UDP

TCP & UDP

原创
作者头像
Nujil
修改2023-04-06 10:11:10
9130
修改2023-04-06 10:11:10
举报
文章被收录于专栏:CNotesCNotes

TCP

TCP报文头部格式:

TCP报文头部格式
TCP报文头部格式
  • 源端口和目的端口: 字段长度各为16位,它们为封装的数据指定了源和目的应用程序。
  • 序列号: 字段长度为32位,序列号确定了发送方发送的数据流中被封装的数据所在位置
  • 确认号: 字段长度为32位,确认号确定了源点下一次希望从目标接收的序列号。如果主机收到的确认号与它下一次打算发送(或已发送)的序列号不符,那么主机将获悉丢失的数据(差错控制机制)。
  • 报头长度(Header Length)又叫数据偏移量(Data Offset),长度为4位,报头长度指定了以32位字为单位的报头长度。由于可选项字段的长度可变,所以这个字段标识出数据的起点是很有必要的。
  • 保留: 字段长度为4位,通常设置为0。
  • 标记(Flag:包括8个1位的标记,用于流和连接控制。它们从左到右分别是:拥塞窗口减少(Congestion Window Reduced,CWR)、ECN-Echo(ECE)、紧急(URG)、确认(ACK)、弹出(PSH)、复位(RST)、同步(SYN)和结束(FIN)。
  • 窗口大小:字段长度为16位,主要用于流控制。窗口大小指明了自确认号指定的八位组开始,接收方在必须停止传输并等待确认之前发送方可以接收的数据段的八位组长度。用来指明发送方发送数据的大小(用于流控)
  • 校验和: 字段长度为16位,它包括报头和被封装的数据,校验和允许错误检测。
  • 紧急指针:字段仅当URG标记置位时才被使用。这个16位数被添加到序列号上用于指明紧急数据的结束。
  • 可选项: 字段用于指明TCP的发送进程要求的选项。最常用的可选项是最大段长度MSS,最大段长度通知接收者发送者愿意接收的最大段长度。为了保证报头的长度是一个八位组的倍数,所以使用0填充该字段的剩余部分。

TCP 三次握手 四次挥手

TCP 三次握手简约版本:

TCP同步而UDP没有,就导致TCP是有连接,而UDP是无连接的

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

  • 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

客户端与服务器端将保持活动状态,直到任何一方发送FIN(结束)信号

TCP 三次握手详细说明:

TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;

TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文

(1)首先客户端向服务器端发送一段TCP报文,其中:

标记位为SYN,表示“请求建立新连接”;

序号为seq=X(X一般为1);

随后客户端进入SYN-SENT阶段。

(2)服务器端接收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段TCP报文,其中:

标志位为SYN和ACK,表示“确认客户端的报文seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”(即告诉客户端,服务器收到了你的数据);

序号为seq=y;确认号为ack=x+1,表示收到客户端的序号seq并将其值加1作为自己确认号ack的值;随后服务器端进入SYN-RCVD阶段。

(3)客户端接收到来自服务器端的确认收到数据的TCP报文之后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP报文。其中:

标志位为ACK,表示“确认收到服务器端同意连接的信号”(即告诉服务器,我知道你收到我发的数据了);

序号为seq=x+1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值;

确认号为ack=y+1,表示收到服务器端序号seq,并将其值加1作为自己的确认号ack的值;随后客户端进入ESTABLISHED阶段。服务器收到来自客户端的“确认收到服务器数据”的TCP报文之后,明确了从服务器到客户端的数据传输是正常的。结束SYN-SENT阶段,进入ESTABLISHED阶段。

在客户端与服务器端传输的TCP报文中,双方的确认号ack和序号seq的值,都是在彼此ack和seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性。一旦出现某一方发出的TCP报文丢失,便无法继续"握手",以此确保了"三次握手"的顺利完成。

此后客户端和服务器端进行正常的数据传输。这就是“三次握手”的过程。

TCP 四次挥手详细说明:

TCP四次挥手
TCP四次挥手
  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
  3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗ *∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

为什么客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

TCP滑动窗口(Sliding Window)

在上面的模型当中,我们之所以觉得算法不好设计,是因为用错了数据结构。有个说法叫作如果程序写复杂了,那就是写错了。这里其实应该用一种叫作滑动窗口的数据结构去实现。

如上图所示:

深绿色代表已经收到 ACK 的段,浅绿色代表发送了,但是没有收到 ACK 的段,白色代表没有发送的段,紫色代表暂时不能发送的段

下面我们重新设计一下不同类型封包的顺序,将已发送的数据放到最左边,发送中的数据放到中间,未发送的数据放到右边。假设我们最多同时发送 5 个封包,也就是窗口大小 = 5。窗口中的数据被同时发送出去,然后等待 ACK。如果一个封包 ACK 到达,我们就将它标记为已接收(深绿色)。

如下图所示,有两个封包的 ACK 到达,因此标记为绿色。

这个时候滑动窗口可以向右滑动,如下图所示:

TCP 数据重传机制

TCP数据的重传机制,就导致TCP是可靠的传输,而UDP不具备这样的能力,是一个不可靠的传输

起初,假定发送端拥塞窗口尺寸为3,含义为:在收到对方的确认之前可以连续发送3个字节,同时假定接收方通告的窗口大小也是3,取两者的最小值作为发送窗口尺寸,结果是3.

因此图中那个发送者发送完3字节后等待接收方确认。接收方由于缓冲区变化造成第3字节的数据被丢弃,因此接收方在返回给发送者的确认数据中只提示收到2字节。确认码为3表示收到2字节,等待第3个。

同时接收方在它的确认数据中将窗口尺寸改为2,这个数值是由TCP头中的窗口字段表示的。发送方收到这个确认后得知第3字节丢失,重新传送第3字节的内容,并且调整发送窗口尺寸为两者中的最小者,结果是2.这样将解决丢包现象。

如果发送过程中,部分数据没能收到 ACK 会怎样呢?这就可能发生重传。

如果发生下图这样的情况,段 4 迟迟没有收到 ACK。

这个时候滑动窗口只能右移一个位置,如下图所示:

在这个过程中,如果后来段 4 重传成功(接收到 ACK),那么窗口就会继续右移。如果段 4 发送失败,还是没能收到 ACK,那么接收方也会抛弃段 5、段 6、段 7。这样从段 4 开始之后的数据都需要重发。

快速重传

在 TCP 协议中,如果接收方想丢弃某个段,可以选择不发 ACK。发送端超时后,会重发这个 TCP 段。而有时候,接收方希望催促发送方尽快补发某个 TCP 段,这个时候可以使用快速重传能力。

例如段 1、段 2、段 4 到了,但是段 3 没有到。 接收方可以发送多次段 3 的 ACK。如果发送方收到多个段 3 的 ACK,就会重发段 3。这个机制称为快速重传。这和超时重发不同,是一种催促的机制。

为了不让发送方误以为段 3 已经收到了,在快速重传的情况下,接收方即便收到发来的段 4,依然会发段 3 的 ACK(不发段 4 的 ACK),直到发送方把段 3 重传。

UDP:

UDP协议有如下的特点:

  1. UDP传送数据前并不与对方建立连接,即UDP是无连接的,在传输数据前,发送方和接收方相互交换信息使双方同步。
  2. UDP不对收到的数据进行排序,在UDP报文的首部中并没有关于数据顺序的信息(如TCP所采用的序号),而且报文不一定按顺序到达的,所以接收端无从排起。
  3. UDP对接收到的数据报不发送确认信号,发送端不知道数据是否被正确接收,也不会重发数据。
  4. UDP传送数据较TCP快速,系统开销也少。
  5. 缺乏拥塞控制(congestion control),需要基于网络的机制来减小因失控和高速UDP流量负荷而导致的拥塞崩溃效应。换句话说,因为UDP发送者不能够检测拥塞,所以像使用包队列和丢弃技术的路由器这样的网络基本设备往往就成为降低UDP过大通信量的有效工具。数据报拥塞控制协议(DCCP)设计成通过在诸如流媒体类型的高速率UDP流中增加主机拥塞控制来减小这个潜在的问题。(需要QOS来解决)

参考自:

https://blog.csdn.net/m0_56649557/article/details/119492899

https://kaiwu.lagou.com/course/courseInfo.htm?courseId=837#/detail/pc?id=7268

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TCP
    • TCP报文头部格式:
      • TCP 三次握手 四次挥手
        • TCP 三次握手简约版本:
        • TCP 三次握手详细说明:
        • TCP 四次挥手详细说明:
        • 为什么客户端最后还要等待2MSL?
      • TCP滑动窗口(Sliding Window)
        • TCP 数据重传机制
          • 快速重传
          • UDP:
            • UDP协议有如下的特点:
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档