IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 在UDP应用层面测试实现丢包的检测 -> 正文阅读

[网络协议]在UDP应用层面测试实现丢包的检测

我们已经已经做好在FPGA上的UDP的用户接口,也在PC上做好了UDP的收发函数,这里可以加上一些逻辑和代码实现UDP是否丢包以及是否错报的实验。

首先来看开UDP接收的用户层面的接口:

这里给出了udp长度,包头包尾分别用 sof和eof指示,还有我方以及对方的IP和端口。所有这些信号都在valid=1是有效。

这很简洁的接口,写起测试模块很容易

-------------

为了实行包内数据数据校验我们就是设置每一包内的所有字节递加,为了判断出包是否丢失我们让每包第一个字节的数字也依次递加。实现的 c代码如下:

全部完整PC运行的测试代码如下:

const static int    BUFFER_LENGTH = 12;
//创建新的套接字之前需要调用一个引入Ws2_32.dll库的函数,否则服务器和客户端连接不上
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
 WSADATA wsaData;                                   //指向WinSocket信息结构的指针
 SOCKET src_socket;
 SOCKADDR_IN sin,saClient;                          //设置两个地址,sin用来绑定
                                                    //saClient用来从广播地址接收消息
 char cRecvBuff[800];                               //定义接收缓冲区
 int nSize,nbSize;
 int iAddrLen=sizeof(saClient);
 if(WSAStartup(MAKEWORD( 1, 1 ), &wsaData )!=0)           //进行WinSocket的初始化
 {
         printf("Can't initiates windows socket!Program stop.\n");//初始化失败返回-1
         return -1;
 }
 src_socket=socket(AF_INET, SOCK_DGRAM,0);
 sin.sin_family = AF_INET;
 sin.sin_port = htons(7001);             //发送端使用的发送端口,可以根据需要更改
 sin.sin_addr.s_addr = htonl(INADDR_ANY);
 if(bind( src_socket, (SOCKADDR FAR *)&sin, sizeof(sin))!=0)
 {
  printf("Can't bind socket to local port!Program stop.\n");//初始化失败返回-1
  return -1;
 }
 while(1)
 { 
  nSize = sizeof ( SOCKADDR_IN );
  if((nbSize=recvfrom (src_socket,cRecvBuff,800,0,
   (SOCKADDR FAR *) &saClient,&nSize))==SOCKET_ERROR) //若接收失败则提示错误
  {
   printf("Recive Error");
   break;
  }
  cRecvBuff[nbSize] = '\0';                              //字符串终止
  printf("%s\n",cRecvBuff);                              //显示所接收到的字符串
 
 
 }
 return 0;
}

----

在FPGA端我们写两个模块,分别是检测是否丢包的chk_udp_lost以及包内数据是否正确的chk_udp_frame,代码实现如下:


module chk_udp_lost(
input clk , rst ,
input valid,sof,
input [7:0]din,
output reg [31:0] lost_count,ok_count  
);

reg [7:0]  r;  wire r_equ_din = r == din ; 
always@ (posedge clk ) if (rst) r<=0; else if(valid & sof) r<=din+1;

always @ (posedge clk) 
casex ({ rst,valid,sof,r_equ_din })
4'b1xxx:{lost_count,ok_count}<=0;
4'b0111:ok_count <=ok_count+1;
4'b0110:lost_count<=lost_count+1;
endcase 

endmodule
module chk_udp_frame(
input clk , rst ,
input valid,sof,eof,
input [7:0]din,
output reg [31:0]err_count,ok_count  
);
reg [7:0] dinr ;always @ (posedge clk) dinr<=din;
 reg [7:0] st ; 
always @ (posedge clk )if (rst) st<=0; else case(st)
0:st <=10;
10:st<=15;
15:if (valid & sof) st<=20;
20:if (valid & eof )st<=30;
30:st<=35;
35:st<=40;
40:st<=10;
default  st<=0;
endcase 

reg [7:0] r ;
always @ (posedge clk)if (rst)r<=0; else case (st)
0,10:  r<=0;
15:if (valid & sof) r<= din ; 
20: r <= r+1;
endcase 

reg err  = 0 ;
always @ (posedge clk)if (rst)err<=0; else case (st)
0,10:  err<=0;
15:  err<=0; 
20:if (r!=dinr)err <=1;
endcase 

always @ (posedge clk) if (rst)err_count<=0;else if (st==40) if (err )err_count<= err_count +1 ;
always @ (posedge clk) if (rst)ok_count<=0;else  if (st==40) if (~err) ok_count<=ok_count + 1 ;

endmodule

这里注意chk_udp_lost模块由于第一数据需要初始化,这时候也会产生导致lost_coun加1,所以说是实际丢包数应该是lost_count-1,我们没有必要改代码,统计结果的时候注意下就好。

----------

在板子上运行,实际看结果:

?我们看到丢包和包内数据出错是存在的,虽然很低。并且我发现在电脑同时运行其他大型编译程序的时候(CPU使用率上升,更多进程分享存储带宽),时候丢包和包内错误会明显上升。

关于错误是在哪里产生,无非两点 FPGA端和PC端。

1,FPGA端导致错误,最大可能是FPGA与PHY接口部分的有一段数据穿越异步时钟,那部分产生的错误。哪里用了一个FIFO,设置流水级数是三级的时候出粗很多,设置为9级(最高)的时候才能得到上述截图的结果,因此我们可以怀疑这部接口虽然量上完善了,但是质上还没完美。

2,电脑端发送产生的丢包或者错误。当电脑开多个程序分别运行的时候,就能明显感觉到出错率的提升。

其实也好判断上述两点:现在是PC链接FPGA,我们用PC链接PC看看错误率情况。或者用FPGA链接FPGA看看错误率情况,前提是FPGA板子的UDP发射部分保证不出错,(这已经测试实现了,之后文字介绍)。

------

想起孙子兵法一句话:

微乎微乎至于无形,神乎神乎至于无声,故能为敌之司命

要细致入微,我们尽力研究透彻了项目设计中遇到的每个细节,哪怕不是我们当前项目的要求,这样融汇贯通,能达到做一个项目经验和功力的提升非常大。

又想起了兵法里面的另外一段:

声不过五,五声之变,不可胜听也;
色不过 五,五色之变,不可胜观也;
味不过五,五味之变,不可胜尝也;
战势不过奇正,奇正之变,不可胜穷也。
奇正相生,如循环之无端,孰能穷之哉

基本的知识点就那么点,我们从具体的设计里面深究下去挖到根源,之后总结出来这些基本规律,也就是上段说的五声五色五味,之后自己设计的时候运用上融汇贯通灵活运用上这色声味的基本原理规律或者套路,就能提出诸多方案并在这些方案中选择最优化的设计。

提到声味色,心经有讲:

无色声香味触法,无眼耳鼻舌身意

这是更高层次的抽象,已经上升到唯识层面了。已经将总结的五声五色五味升华成了诸法空性了。对我们的指导意义是及时消化这写规律,得其义忘其形。

非法非非法,一切都是无,之后就是《金刚经》的那句

一切有为法,如梦幻泡影,如露亦如电,应作如是观。

要看穿,要悟空,具体而言

无我相,无人相,无众生相,无寿者相.

觉悟到诸法空性,也就能看穿世间远离颠倒梦想了,也就修佛入门了,接下来就是无主宰非自然三世因果六道轮回...

你我程序猿工程狮凡夫俗子三尺微命一介书生,到不了那么高的境界无法乘风归去。要在这婆娑世界风雨红尘中携妻雏承上启下忙生活,暂且写写代码调调板子以混口狗粮。时有发骚,写写博文以自娱...

那咱们下篇就继续DEBUG哈,调试的内容是ICMP_REQUEST的信息提取以及ICMP_REPLY的生成。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-15 18:40:09  更:2021-12-15 18:42:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 11:25:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码