两种丢包处理策略:丢包重传 和 FEC(前向纠错)

两种丢包处理策略

为了保证实时性,通常适应UDP协议来针对RTP数据进行传输,而UDP无法保证数据传输的质量,所以在网络环境不好的时候,丢包是经常出现的问题,有什么策略来改善这个问题吗?
常用的方法有: 丢包重传和前向纠错

两种丢包处理策略:丢包重传 和 FEC(前向纠错)_第1张图片
两种丢包处理策略

通常抗丢包有两种方式: FEC和ARQ。
FEC是前向冗余,举个例子,发送数据A和B,增加发送一个数据C等于A和B的异或。接收方接到这3个包的任意2个包,异或一下就可以得到第3个包。
当然,实际的FEC没这么简单,通常会有比较复杂的矩阵运算。
ARQ就是接收方发现丢包后,去发送方请求重传。
FEC传递简单,只需要单向传输就可以支持,延时小,缺点就是丢包率波动大时,抗丢包能力差。ARQ的优点是网络携带率高,但延迟大,当延时大或拥塞丢包的情况,不能使用ARQ。拥塞丢包时,使用ARQ会加大传输量,导致拥塞更严重。
http://www.jianshu.com/p/93d2935ab7ed

丢包重传

主要是根据RTP的序号(Sequence Number)来进行判断是否丢包,正常情况下序号是连续的。

两种丢包处理策略:丢包重传 和 FEC(前向纠错)_第2张图片
RTP Header

客户端(视音频数据接收方)如果发现数据丢失,则向服务器放出请求,请求服务器重发指定数据包。

FEC
FEC思想
两种丢包处理策略:丢包重传 和 FEC(前向纠错)_第3张图片
FEC思想
两种丢包处理策略:丢包重传 和 FEC(前向纠错)_第4张图片
FEC
FEC实质

FEC的实质就是异或。

两种丢包处理策略:丢包重传 和 FEC(前向纠错)_第5张图片
Paste_Image.png

假如有4个数据,那么它们可以取4个异或值,其中每一个数据都可以由另外4个异或计算出来。还可以把ABCD和E想象成一个数据包,如果我们传输ABCD这四个数据包,第五个数据包传输的是E,这五个数据包可以丢失任何1个数据包。接收方收到数据之后,能够把它丢的数据恢复出来。前向纠错算法能处理的是连续数据里只丢1个包。同时丢失A和B,这个算法不能解决。

异或的运算规则

两种丢包处理策略:丢包重传 和 FEC(前向纠错)_第6张图片
异或

由图1可知,异或运算的规则是
0⊕0=0,0⊕1=1
1⊕0=1,1⊕1=0
口诀: 相同取0,相异取1
事实上,XOR 在英文里面的定义为either one (is one), but not both, 也即只有一个为真(1)时,取真(1)。

异或举例
#include "stdafx.h"
#include 
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    int i = 1;
    int j = 2;
    int k = 3;

    printf("*************************************\n");
    char szTempBuffer[16] = {0};
    itoa(i, szTempBuffer, 2);   
    printf("i : %08s\n", szTempBuffer);

    memset(szTempBuffer, 0, 16);
    itoa(j, szTempBuffer, 2);   
    printf("j : %08s\n", szTempBuffer);

    memset(szTempBuffer, 0, 16);
    itoa(k, szTempBuffer, 2);   
    printf("k : %08s\n", szTempBuffer);

    int m = i ^ j ^ k;

    memset(szTempBuffer, 0, 16);
    itoa(m, szTempBuffer, 2);   
    printf("m : %08s\n", szTempBuffer);

    printf("*************************************\n");

    int kk = i ^ j ^ m;

    memset(szTempBuffer, 0, 16);
    itoa(i, szTempBuffer, 2);   
    printf("i  : %08s\n", szTempBuffer);

    memset(szTempBuffer, 0, 16);
    itoa(j, szTempBuffer, 2);   
    printf("j  : %08s\n", szTempBuffer);

    memset(szTempBuffer, 0, 16);
    itoa(m, szTempBuffer, 2);   
    printf("m  : %08s\n", szTempBuffer);

    memset(szTempBuffer, 0, 16);
    itoa(k, szTempBuffer, 2);   
    printf("kk : %08s\n", szTempBuffer);

    return 0;
}

输出结果:


两种丢包处理策略:丢包重传 和 FEC(前向纠错)_第7张图片
异或 演示结果

References:

http://www.jianshu.com/p/93d2935ab7ed
http://www.jianshu.com/p/b6af9a978504
https://baike.so.com/doc/1916696-2027869.html

两种丢包处理策略:丢包重传 和 FEC(前向纠错)_第8张图片
FEC

http://www.eecs.umich.edu/courses/eecs489/w10/winter10/lectures/lecture17.pdf

你可能感兴趣的:(两种丢包处理策略:丢包重传 和 FEC(前向纠错))