ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UDP如何实现可靠传输

2022-06-26 19:31:11  阅读:577  来源: 互联网

标签:UDP 重传 报文 TCP 可靠 发送 传输 机制


1.什么时候会考虑UDP

答:

  • 实时性:UDP重传实际是用户层可控制的,TCP的重传时机是由协议栈去做,用户层控制不了。时钟翻倍
  • 资源消耗考虑:DNS服务器,请求DNS查询数据量小,使用三次握手浪费资源,效率低,域名服务器维护大小的tcp连接消耗大量资源
  • 手机定位信息上报 app:位置信息 信息量比较少,偶尔丢包没有影响
  • 物联网:用电池的设备 周期性上报信息到服务器
  • 音视频通话  

2.UDP sendto、recvfrom的坑

udp不能发太大的数据包,带宽不足的影响

udp发外网一般不超过1400字节

recvfrom接收时必须接收整个报文,udp是面向报文的,但也不能一次接收多个报文

3.udp是无连接的,面向报文的数据传输协议,与TCP相比,有两个缺点:

(1)数据包容易丢失;-》数据确认,超时重传机制

(2)数据包无序;-》重排机制

(3)拥塞控制

body:1388   header:12字节

 

 

前言

一般而言对于大部分的应用使用TCP既可以满足工程的需求,因为TCP即保证的可靠性,又是一个相对绅士的协议,对于网络拥塞提供了流量和拥塞控制保证了网络友好性。那为啥还需要使用UDP呢?主要是因为在一些实时性要求比较高的情景中TCP没办法满足要求同时对于数据量不大的低功耗情景也是考虑使用的UDP,但是需要在用户态自行保证可靠性,也就是接下来需要阐述的内容。

1 可靠性传输

UDP的可靠性,其实是借鉴TCP可靠性传输的策略,并且化繁为简取其精华。首先我们需要了解TCP是如何保证可靠性的。

1.1 常见保证可靠性的策略有哪些?

(1)ACK机制
(2)重传机制
(3)序号机制
(4)重排机制
(5)窗口机制

ACK机制比较好理解,即当接收到包即发送ACK进行确认。序号机制和重排机制用的也比较多,网络接收到数据包有可能是乱序的这时候需要在发送之初把每一个包的序号先加上,接收到之后进行重排即可。重传和窗口机制比较复杂,下面分开阐述。

1.2 重传机制

1.2.1 重传的三种策略

1. 停等协议
这是一种比较古老的方式,效率比较低,主要是每发送一帧数据后需要接收到对方的回复之后才发送下一帧数据,主要是用于对话的模式,一问一答。

 

 

 


2. 回退N帧重传
这种方式目前TCP仍然有在使用,就是发送一串连续的包,当中间存在丢包的情况后,会回复确认连续收到包的最大值,对应丢包以后的数据包都需要重传。

 

 

 

3. 选择性重传
从上面回退N帧的方式发现比较浪费带宽,因此想到一一个方式,就是我们只重传对方丢失的包。可以正向告诉发送端,哪一个报文丢失,重传丢失报文即可。

1.2.2 重传的时机

(1)发送方没有收到ack,则重传对应的报文;
(2)接收方收到的序号有缺失,这时候发送信息告诉发送方重传相应的包。

1.2 流量控制

1. 流量控制的目的
主要是是为了保证网络带宽的通畅,防止带宽浪费,而引入的机制,主要是在发送方进行流量的控制,即控制发送方的发送速率。
2. 流量控制原理
利用发送端和接收端的窗口进行调节当前的流量。边界条件,当接收端窗口为0时,发送方需要终止发送。即没有可以接收的空间,需要终止发送。
3. 终止发送后,什么时候恢复发送速率?
(1)接收端读数据时,需要更新窗口给发送方。
(2)隔一段时间发一个探测包去询问。接收方需要回应窗口大小。

1.3 拥塞控制

这里介绍两种策略,这幅图估计大部分人都不陌生。

 

1.3.1 慢启动

慢启动:其实并不慢主要是起点低,从一个包开始发送,然后指数递增。

 

1.3.2 快速恢复

快速恢:快速恢复并不快采用的是线性递增的方式,主要是起点高从阈值的一半开始。

 

 

 

1.4 基本概念

RTO:
定时器超时时间,即超时后需要进行数据包重传。
注意:
tcp超时计算:第一次重传时间:RTO2,连续丢包三次之后变成:RTO8,延迟非常大。
RTT:
网络往返时延,需要记录发送方和接收方的时间戳。

2 UDP可靠性设计

基于应用层的可靠传输,udp可靠设计没有万精油,需要根据具体的使用场景。

2.1 协议设计

协议设计:
|同步字|总字节大小|分片数|分片编号|载荷大小|预留|荷载|

typedef struct packet
{
    int recv_pieces;                                //当前已经接收的数量;
    int total_size;                                 //总数据大小
    int left;                                         //最后一片大小
    int paiece_size;                                 //分片大小
    int recv_len;                                      //接收数据长度
    uint8_t *recv_buf;                                //保存接收数据
    uint8_t * send_pt;                                 //指向发送数据buffer
       uint8_t piece_buf[PIECE_FIX_SIZE+HEAD_SIZE+1] ;    //单帧的buf
       circular_buffer_t *circular_buffer;             //环形缓存
}packet;

 

2.2 具体实现

这里不展开写具体实现,但是需要注意的几个点,UDP可靠性传输需要考虑的几个点,一个是重传机制,丢包需要进行重传,可以用ACK也可以用NACK的方式;第二是重排机制,我们在收到乱序数据一定需要增加一个缓冲区进行数据重排;第三是超时机制,长时间没收收到对方的回复需要进行重试;第四,流量控制,在局域网内一般是不考虑这部分,实现起来比较复杂,收益不是那么大。

3 UDP使用场景

实时性考虑
资源消耗考虑
具体场景主要包括下面几方面:

1 音视频通话(网络延时,tcp不可以控制重传,延时太大,udp可以控制重传时间);
2 游戏开发(实时性操作:王者荣耀;传输位置,延迟会造成卡顿)
3 DNS查询(一问一答;一个包就可以,丢包直接重发就行)
4 物联网设备监控,用电池(活跃状态耗电,睡眠,发送数据量不大)
5 心跳机制 监测设备在不在线心跳包

4 UDP编程需要注意的一些坑

4.1UDP乱序问题

一般采用接收缓冲区进行排序

4.2 发送包大小

sendto一次发送1400字节
需要小于最小的MTU,以太网数据帧一般是1500字节
经验值:1400 (实时通讯)500(游戏)主要是包比较小有一定的优先权

4.3 接收数据

recvfrom一次需要完整读取报文
udp一次只能收一个包,没有边界问题(报文传输)
tcp一次可以收一部分数据,有黏包问题(流式传输)
————————————————
版权声明:本文为CSDN博主「响箭零零一」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38731735/article/details/121444828

标签:UDP,重传,报文,TCP,可靠,发送,传输,机制
来源: https://www.cnblogs.com/cuijy1/p/16413999.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有