【网络】传输层协议TCP(重点)

立山  金牌会员 | 2025-2-13 06:17:09 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 903|帖子 903|积分 2709


TCP协议全称为 “传输控制协议(Transmission Control Protocol”)。
人如其名,要对数据的传输进行一个 具体的控制
可靠性:
   

  • 校验和
  • 序列号(按序到达) (去重)
  • 确认应答
  • 超时重传
  • 毗连管理
  • 流量控制
  • 拥塞控制
  进步性能:
   

  • 滑动窗口
  • 快重传
  • 延迟应答
  • 捎带应答
  其他:
   

  • 定时器(超时重传定时器, 保活定时器, TIME_WAIT 定时器等)
  1. TCP协议段格式


   

  • 16位源/目的端口号:表示数据是从哪个历程来, 到哪个历程去;
  • 32位序号/32 位确认序号
  • 4 位首部长度: 表示该 TCP 头部有多少个 32 位 bit(有多少个4 字节); 以是 TCP 头部最大长度是 15 * 4 = 60
  • 6 位标志位

    • ACK:确认号是否有效
    • SYN:请求建立毗连;我们把携带 SYN 标识的称为同步报文段
    • FIN:关照对方, 本端要关闭了, 我们称携带 FIN 标识的为结束报文段
    • PSH: 提示接收端应用程序立即从 TCP 缓冲区把数据读走
    • RST:对方要求重新建立毗连; 我们把携带 RST标识的称为复位报文段
    • URG:紧急指针是否有效

  • 16 位窗口巨细
  • 16 位校验和:发送端添补,CRC 校验。接收端校验不通过,则以为数据有题目,此处的检验和不但包含 TCP 首部,也包含TCP 数据部分.
  • 16 位紧急指针:标识哪部分数据是紧急数据;
  • 40 字节头部选项:临时忽略
  下面的是Linux源代码中,tcp报头的定义:
  1. struct tcphdr {
  2.     __be16 source;          // 源端口号
  3.     __be16 dest;            // 目的端口号
  4.     __be32 seq;             // 序列号
  5.     __be32 ack_seq;         // 确认号
  6. #if defined(__LITTLE_ENDIAN_BITFIELD)
  7.         //使用了位段
  8.     __u16 res1:4,           // 保留位
  9.           doff:4,           // 数据偏移(头部长度,以32位字为单位)
  10.           fin:1,            // FIN标志:结束连接
  11.           syn:1,            // SYN标志:同步序列号
  12.           rst:1,            // RST标志:重置连接
  13.           psh:1,            // PSH标志:Push函数
  14.           ack:1,            // ACK标志:确认字段有效
  15.           urg:1,            // URG标志:紧急指针字段有效
  16.           ece:1,            // ECN回显标志
  17.           cwr:1;            // 拥塞窗口减少标志
  18. #elif defined(__BIG_ENDIAN_BITFIELD)
  19.     __u16 doff:4,           // 数据偏移(头部长度,以32位字为单位)
  20.           res1:4,           // 保留位
  21.           cwr:1,            // 拥塞窗口减少标志
  22.           ece:1,            // ECN回显标志
  23.           urg:1,            // URG标志:紧急指针字段有效
  24.           ack:1,            // ACK标志:确认字段有效
  25.           psh:1,            // PSH标志:Push函数
  26.           rst:1,            // RST标志:重置连接
  27.           syn:1,            // SYN标志:同步序列号
  28.           fin:1;            // FIN标志:结束连接
  29. #else
  30. #error "Adjust your <asm/byteorder.h> defines"
  31. #endif
  32.     __be16 window;          // 窗口大小
  33.     __sum16 check;          // 校验和
  34.     __be16 urg_ptr;         // 紧急指针
  35. };
复制代码
2. 详解TCP

2.1 4位首部长度

4位首部长度 = 尺度报头长度 + 选项长度,单位是4字节。
4个比特位可表示的范围是 [0,15],可表示的巨细就是 [0,60]字节,由于尺度报头占 20 字节,以是4位首部长度的范围是 [20,60]。

以是,TCP解包时,先读取报文的前20字节,然后再根据4位首部长度,将报头+选项提取出来,剩下的就是有效载荷的长度。
2.2 32位序号与32位确认序号(确认应答机制)

起首我们要知道,32位序号是用来保证收到的报文的可靠性的(对汗青报文的可靠性)。
TCP中的可靠性主要是依赖确认应答实现的,否则发送方不知道自己发送的报文是否被收到了。
只要发送端收到了应答,阐明发送的数据一定被收到了,可靠性也就保证了。(接收端无需关心自己的应答是否可靠,如果不可靠,发送端会重发数据;如果可靠,发送端就发新的数据了)
那什么是确认呢?
   确认,至少是一个“裸”的tcp报头
  32位序号又是什么呢?
根据我们上面所说的,一条请求对应一条应答,没有收到应答就会重新发送请求;如果是串行的话,服从就太低了,以是TCP选择的是并行发送。

并行发送会存在一个题目,不知道应答对应哪一条请求,以是必须对请求编号,这个编号就是32位序号
32位确认序号就是对报文的序号+1,表示序号之前的内容已经收到了
序号与确认序号不一定是一对一的,多个序号可能只会有一条确认序号,表示该序号之前的内容已全部收到)
   序号存在的另一个缘故原由:保证报文的按序到达
报文如果到达后是乱序的,这也是不可靠的的表现,以是可以根据序号排序,然后按顺序入缓冲区。
  可是报头中为什么要有两个32位序号呢?一个也够用呀?
   两个32位序号,是为了实现捎带应答机制。接收端应答的同时,也想捎带着给发送端发送数据。
以是,TCP报文在很大概率上,既是应答,也是数据。
  那序号又是如何产生的呢?

2.3 超时重传机制


主机 A 发送数据给 B 之后,可能由于网络拥堵等缘故原由,数据无法到达主机 B;如果主机 A 在一个特定时间隔断内没有收到 B 发来的确认应答,就会进行重发;
但是,主机 A 未收到 B 发来的确认应答, 也可能是由于应答丢失

因此主机 B 会收到很多重复数据。那么 TCP 协议需要能够辨认出那些包是重复的包, 而且把重复的丢弃掉。
这时候我们可以使用前面提到的序列号, 就可以很容易做到去重的效果。
以是,为了低落重复率,不能让发送方不绝发,需要设定一个时间,超过这个时间后,发送端再发,这种机制叫做超时重传机制。
那超时的时间如何确定呢?
   

  • 最理想的环境下, 找到一个最小的时间, 保证 “确认应答一定能在这个时间内返回”。
  • 但是这个时间的是非,随着网络环境的差别,是有差异的。 如果超时时间设的太长,会影响整体的重传效;如果超时时间设的太短,有可能会频繁发送重复的包。
  TCP 为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间
Linux 中(BSD Unix 和 Windows 也是如此),超时以 500ms 为一个单位进行控制,每次判定超时重发的超时时间都是 500ms 的整数倍。
   

  • 如果重发一次之后, 仍旧得不到应答, 等候 2*500ms 后再进行重传。
  • 如果仍旧得不到应答,等候 4*500ms 进行重传, 依次类推, 以指数情势递增。
  • 累计到一定的重传次数, TCP 以为网络大概对端主机出现异常,强制关闭毗连。
  2.4 毗连管理机制(3次握手、4次挥手 + 3个标志位)

在正常环境下,TCP 要颠末三次握手建立毗连,四次挥手断开毗连。

在正式学习握手、挥手之前,先相识报头中的几个标志位。
在TCP报头中,有6个标志位,用来区分接收端收到的TCP报文的类型 (可能有多个发送端)。


  • ACK:acknowledgement
表明自己是一个确认报文,让对方关心确认序号。 (由于有捎带应答机制,以是大部分的TCP报文的ACK标志位都为1)

  • SYN:synchronize
同步标志位,即表明是一个建立毗连的请求

  • FIN:finish
表明自己是一个断开毗连的请求,一般用于通信结束时。

两边建立毗连,起主要进行3次握手
   举个栗子:
男:你愿意做我女朋侪吗?
女:好呀,什么时候开始?
男:就现在!
  在上面的例子中,两边用了最小的握手次数,建立了关系,这就叫做三次握手

两边断开毗连,起主要进行4次挥手
   举个栗子:
女:我们分手吧!
男:好!
男:我也要跟你分手!
女:好!
  为什么叫做四次挥手? - 由于断开毗连需要征得两边的同意 ! (由于TCP是全双工的,要关闭两个朝向上的毗连)


3次握手,是由操作体系自动完成的。
服务器端:accept返回后,毗连已经建立完成了。即accept等3次握手完成,它不参与3次握手。
客户端:connect调用后,触发操作体系,让操作体系发送SYN,两边握手完成,connect返回。
   

  • 只要客户端发出去SYN,它的状态就酿成了SYN_SENT;客户端发出去ACK,就以为自己把毗连建立好了,状态变为established。(客户端不保证发送的ACK一定能被收到,以是3次握手本质就是在赌,由于3次握手本来就不一定成功)

    • 服务端未收到ACK,但发送端以为毗连建立成功了,发送端此时就会发送数据,但是服务端不熟悉它,会通过标志位RST要求重新建立毗连。

  • 一般服务端只要收到了SYN,它的状态就酿成SYN_RECV;它收到客户端的ACK后,才以为毗连建立完成。
  • 以是,一般是客户端以为毗连先建立好。
  有了四次挥手的理解,3次握手的本质,其实也是四次握手!

以是,为什么要3次握手呢?

  • 建立毗连,要征得两边的同意;由于TCP是全双工的,要建立两个朝向上的毗连
  • 在3次握手期间,正式通信之前,两边验证了全双工信道的通畅性(客户端与服务端的IO是正常的,即网络是通畅的)
谈了这么多,到底什么是毗连呢?
   

  • 一条毗连,一定会和一个文件对应;由于一个毗连,对应一个文件形貌符。
  • 那么,毗连在操作体系内就会存在很多个,操作系同一定要管理毗连。先形貌在组织,创建毗连的struct,在struct内部,一定会有一个字段来表示毗连的状态。
  
下面我们再来看一下4次挥手

介绍一个体系调用,shutdown可控制关闭毗连的读写端

我们具体是使用close照旧shutdown,取决于应用层。
在服务器这边,如果不调用close关闭sockfd,那就只会进行两次挥手,server会不绝处于close_wait状态,会造成文件形貌符走漏、内存走漏题目。
当服务器关闭后,server会进入last_ack状态,可是此时客户端早就关闭了,没人给它应答了,那么服务端在一段时间后,自动进入closed状态。
那客户端的time_wait状态是什么意思呢??
   

  • 在四次挥手时,自动断开毗连的一方会进入time_wait状态,要等候一个 2MSL(Max Segment Life,报文最大生存时间),才会进入 CLOSED 状态
  为什么会这样呢?举个例子:
  

  • 在有些环境下,两边都关闭后,接收端重启并与发送端建立毗连后,发送方被判定为超时的报文可能又到达了。为了防止报文被接收端误处理,发送方需要等候2MSL后才可再次启动。
  等候2MSL的目的是:
  

  • 等候汗青的游离报文,在网络中消散!
  • 若time_wait状态下的ACK丢了,那么就可以以最快的速度重新发送,尽可能正常的完成4次挥手断开毗连
  为什么是2MSL呢?MSL不可吗?
   

  • 理想环境下,1个MSL时间足以确保一个报文在网络中消散

    • 报文在网络中传输时,会经历各种延迟,包括路由器处理延迟、链路传输延迟等。这些延迟是不确定的,可能会导致报文在较长时间内仍旧存在于网络中。

  • 等候2MSL时间可以确保旧毗连的全部报文(包括丢失的报文和重传的报文)在网络中完全消失。

    • 假设MSL为30秒:
    • 丢失的报文:一个报文在接近30秒时丢失。
    • 重传的报文:发送方在超时后(假设超时时间为1秒)重传该报文,重传的报文也会在网络中传输,其生存时间也是30秒。
      总时间:因此,最坏环境下,报文的总生存时间是30秒(丢失的报文)+ 30秒(重传的报文)= 60秒。

  • 如果ACK报文丢失,被动关闭方重传的FIN报文也需要在网络中传输,这同样需要一个MSL时间。因此,总共需要2MSL时间来确保ACK报文的可靠传输和FIN报文的重传处理。
  在我们前面写代码时,端口号绑定失败的缘故原由:
   

  • 当服务端自动关闭后,其进入time_wait状态,即历程没有退出,端口号被占用了。
  • 若想使用旧端口号,可以通过体系调用 setsockopt()设置套接字的类型
  可以通过 cat /proc/sys/net/ipv4/tcp_fin_timeout 检察 msl 的值

2.5 16位窗口巨细(流量控制)

接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应,不做任何处理则会浪费了各种资源(网络带宽、CPU等等)。
因此 TCP 支持根据接收端的处理本领,来决定发送端的发送速度,这个机制就叫做流量控制
   接收端将自己可以接收的缓冲区巨细放入 TCP 首部中的 “窗口巨细” 字段
  

  • 窗口巨细字段越大, 阐明网络的吞吐量越高,发送端接受到这个窗口之后, 就会进步自己的发送速度
  • 接收端一旦发现自己的缓冲区快满了,就会将窗口巨细设置成一个更小的值关照给发送端;发送端接受到这个窗口之后, 就会减慢自己的发送速度
  • 如果接收端缓冲区满了,就会将窗口置为 0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口巨细告诉发送端。
  • 两边都要进行流量控制
  • 初次发送如何知道对方的接收本领呢? 三次握手时,是做过报文交换与窗口协商的!
  

接收端如何把窗口巨细告诉发送端呢? TCP 首部中,有一个 16 位窗口巨细字段,就是存放了窗口巨细信息(即自己接收缓冲区中剩余空间的巨细);
   那么题目来了,16 位数字最大表示 65535, 那么 TCP 窗口最大就是 65535 字节么?
实际上,TCP 首部 40 字节选项中还包含了一个窗口扩大因子 M,实际窗口巨细是窗口字段的值左移 M 位;
  2.6 滑动窗口

在我们讨论了确认应答策略时, 对每一个发送的数据段,都要给一个 ACK 确认应答,收到 ACK 后再发送下一个数据段(串行发送)。
这样做有一个比较大的缺点:就是性能较差,尤其是数据往返的时间较长的时候。
我们说TCP是采用并行发送的,它是怎么实现的呢?流量控制又是怎么实现的呢? - - 滑动窗口
窗口巨细指的是:无需等候确认应答就可以继续发送数据的最大值。 下图的窗口巨细就是 4000 个字节(四个段)
   

  • 发送前四个段的时候, 不需要等候任何 ACK, 直接发送;
  • 收到第一个 ACK 后, 滑动窗口向后移动(start = ACK),继续发送第五个段的数据(end = start + 16位窗口巨细),依次类推;
  • 操作体系内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答;只有确认应答过的数据,才气从缓冲区删掉
  • 窗口越大,则网络的吞吐率就越高;窗口越小,网络的吞吐率越低。(流量控制)
  

此时就是并行发送的了

那么如果出现了丢包,如何进行重传?这里分两种环境讨论:

  • 环境一: 数据包已经抵达, ACK 被丢了

这种环境下, 部分 ACK 丢了并不要紧,由于可以通过后续的 ACK 进行确认;

  • 环境二:数据包就直接丢了

当某一段报文段丢失之后,发送端会不绝收到 1001 这样的 ACK,就像是在提示发送端 “我想要的是 1001” 一样,滑动窗口会先向右移动到已经发送成功处,然后补发丢失的报文。
   

  • 如果发送端主机一连三次收到了同样一个 “1001” 这样的应答, 就会将对应的数 据 1001 - 2000 重新发送;
  • 这个时候接收端收到了 1001 之后, 再次返回的 ACK 就是 7001 了(由于 2001 - 7000)接收端其实之前就已经收到了, 被放到了接收端操作体系内核的接收缓冲区中 ,这种机制被称为 “高速重发控制”(也叫 "快重传).
  既然有了快重传,它既快,又能重传,那为什么还要超时重传呢?
   快重传是有条件的:要一连三次收到同一个应答!
万一发送方只发送了2个报文呢?最多就只能收到2个应答呗,那就无法触发快重传,只能超时重传。以是,超时重传是兜底的;快重传是进步服从的。
  2.7 3个标志位 + 16位紧急指针

有了上面的理解,我们来相识一下TCP报头中剩余的3个标志位

  • PSH:push
在进行流量控制时,如果接收方的缓冲区已满,那发送方也就只能发送探测报文,没有别的办法了。
为了告诉对方,请尽快将缓冲区中的数据交给上层,就引入了PSH标志位;也可使用PSH标志位,告诉对端,我的数据比较重要,请尽快交付。

  • RST:reset
重置毗连(重新三次握手)
在三次握手时,服务端未收到ACK,但发送端以为毗连建立成功了,发送端此时就会发送数据,但是服务端不熟悉它,会通过标志位RST要求重新建立毗连。

  • URG:urgent
表示紧急报文,优先让上层从缓冲区中读取。
那紧急数据在那里呢?
在TCP报头中,有16位紧急指针,表示紧急数据在有效载荷中的偏移量,通过它就可以获取紧急数据。
但是只有紧急数据的起始地点,紧急数据有多长呢?
TCP答应插队,但不答应过度插队, 紧急数据只占一个字节! 以后可以在紧急数据中设置状态码(如终止毗连、暂停上传等等)
   在体系调用recv中,可以设置标志位MSG_OOB,来读取紧急数据。
  2.8 拥塞控制

固然 TCP 有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据,但是如果在刚开始阶段就发送大量的数据,仍旧可能引发题目。
由于网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清晰当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。 以是TCP使用拥塞控制来考虑网络的康健状况, 一旦发送的报文大量丢失,则会被判定为网络拥塞。
   大量报文丢失后,能不能直接重传呢?- - - 不能,由于可能会造成网络更加的拥堵!应该等一等
  TCP 引入慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。

此处引入一个拥塞窗口的概念,拥塞窗口是衡量网络拥堵的指标。


  • 发送开始的时候,定义拥塞窗口巨细为 1
  • 每次收到一个 ACK 应答,拥塞窗口加 1 倍
滑动窗口 = min (拥塞窗口,对端接收缓冲区剩余空间的巨细)
像上面这样的拥塞窗口增长速度,是指数级别的。“慢启动” 只是指初使时慢,但是增长速度非常快 (指数级增长)。
   可是为什么使用指数级增长呢?
指数增长的特点是:前期慢,后期快;既然前面慢速度发送的都没有题目,那就应该尽快进行网络的规复。
  但是,为了不增长的那么快,不能使拥塞窗口单纯的加倍;此处引入一个叫做慢启动的阈值,当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长

拥塞控制算法 = 慢启动 + 加法增大 + 乘法减小
可是这个拥塞窗口为什么不绝在试探性的增大呢?
   拥塞窗口是网络康健状况的评估值,网络的状况是不绝在变化的,以是要反复的试探,只管让下一次的阈值高一点。
  拥塞控制,归根结底是 TCP 协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。
2.9 延迟应答

接收端收到数据后,如果接收数据的主机立即返回 ACK 应答,这时候返回的窗口可能比较小(上层未取走刚接收到的报文)


  • 假设接收端缓冲区为 1M,一次收到了 500K 的数据,如果立即应答,返回的窗口就是 500K;
  • 但实际上可能处理端处理的速度很快, 10ms 之内就把 500K 数据从缓冲区消费掉了;在这种环境下,接收端处理还远没有到达自己的极限, 即使窗口再放大一些, 也能处理过来;
  • 如果接收端稍微等一会再应答,比如等候 200ms 再应答, 那么这个时候返回的窗口巨细就是 1M;
  • 一定要记得, 窗口越大, 网络吞吐量就越大, 传输服从就越高。我们的目标是在保证网络不拥塞的环境下只管进步传输服从;
那么全部的包都可以延迟应答么? 肯定也不是
   

  • 数目限定: 每隔 N 个包就应答一次;
  • 时间限定: 超过最大延迟时间就应答一次;
  • 具体的数目和超时时间,依操作体系差别也有差异;一般 N 取 2,超时时间取 200ms;
  

2.10 其它

2.10.1 面向字节流

创建一个 TCP 的 socket,同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区
   

  • 调用 write 时, 数据会先写入发送缓冲区中; 如果发送的字节数太长,会被拆分成多个 TCP 的数据包发出;
  • 如果发送的字节数太短,就会先在缓冲区里等候,比及缓冲区长度差不多了,大概其他符合的时机发送出去;
  • 接收数据的时候,数据也是从网卡驱动程序到达内核的接收缓冲区;然后应用程序可以调用 read 从接收缓冲区拿数据;
  • 另一方面,TCP 的一个毗连,既有发送缓冲区,也有接收缓冲区,那么对于这一个毗连,既可以读数据,也可以写数据,这个概念叫做全双工
  由于缓冲区的存在, TCP 程序的读和写不需要一一匹配,比方:
   

  • 写 100 个字节数据时,可以调用一次 write 写 100 个字节, 也可以调用 100 次write,每次写一个字节;
  • 读 100 个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read 100 个字节, 也可以一次 read 一个字节,重复 100 次
  • 具体传输的数据是什么,由上层解释。
  2.10.2 粘包题目

起主要明确,粘包题目中的 “包” ,是指的应用层的数据包。
   

  • 在 TCP 的协议头中,没有如同 UDP 一样的 “报文长度” 这样的字段, 但是有一个序号这样的字段
  • 站在传输层的角度,TCP 是一个一个报文过来的,按照序号排好序放在缓冲区中
  • 站在应用层的角度,看到的只是一勾通续的字节数据
  • 那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始,到哪个部分是一个完备的应用层数据包
  那么如何避免粘包题目呢? 归根结底就是一句话,明确两个包之间的界限
   

  • 对于定长的包,保证每次都按固定巨细读取即可;那么就从缓冲区从头开始按固定巨细依次读取即可;
  • 对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置;
  • 对于变长的包,还可以在包和包之间使用明确的分隔符(应用层协议,是程序猿自己来定的,只要保证分隔符不和正文辩论即可)
  思索: 对于 UDP 协议来说,是否也存在 “粘包题目” 呢?
   

  • 对于 UDP,如果还没有给上层交付数据,UDP 的报文长度仍旧在;同时,UDP 是一个一个把数据交付给应用层,就有很明确的数据界限.
  • 站在应用层的站在应用层的角度,使用 UDP 的时候, 要么收到完备的 UDP 报文,要么不收,不会出现"半个"的环境
  2.10.3 异常环境



  • 历程终止:历程终止会开释文件形貌符,仍旧可以发送 FIN,和正常关闭没有什么区别
  • 呆板重启:和历程终止的环境相同.
  • 呆板掉电/网线断开:接收端以为毗连还在,一旦接收端有写入操作,接收端发现毗连已经不在了,就会进行 reset。即使没有写入操作, TCP 自己也内置了一个保活定时器,会定期询问对方是否还在,如果对方不在,也会把毗连开释 - - - 毗连保活机制。
  • 应用层的某些协议,也有一些这样的检测机制。比方 HTTP 长毗连中,也会定期检测对方的状态。比方 QQ在 QQ 断线之后,也会定期尝试重新毗连
3. TCP/UDP 对比


  • TCP/UDP 对比
我们说了 TCP 是可靠毗连,那么是不是 TCP 一定就优于 UDP 呢? TCP 和 UDP 之间的优点和缺点。不能简单、绝对的进行比较


  • TCP 用于可靠传输的环境,应用于文件传输,重要状态更新等场景
  • UDP 用于对高速传输和实时性要求较高的通信范畴,比方,早期的 QQ、视频传输等;另外 UDP 可以用于广播;
归根结底,TCP 和 UDP 都是程序员的工具,什么时机用,具体怎么用,照旧要根据具体的需求场景去判定

  • 基于 TCP 应用层协议
   

  • HTTP
  • HTTPS
  • SSH
  • Telnet
  • FTP
  • SMTP
  

  • 用 UDP 实现可靠传输(经典面试题)
先根据应用场景,确定具体的应用需求,可靠性要保障到什么程度;再参考 TCP 的可靠性机制, 在应用层实现雷同的逻辑;
   

  • 比方:
  • 引入序列号, 保证数据顺序;
  • 引入确认应答, 确保对端收到了数据;
  • 引入超时重传, 如果隔一段时间没有应答, 就重发数据;

  


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表