第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 无连接应用程序丢包率测试/UDP丢包率测试【基于数据报套接字的网络程序设计】

无连接应用程序丢包率测试/UDP丢包率测试【基于数据报套接字的网络程序设计】

时间:2022-10-15 13:56:14

相关推荐

无连接应用程序丢包率测试/UDP丢包率测试【基于数据报套接字的网络程序设计】

目录

一、无连接应用程序丢包率测试二、UDP 丢包率测试服务端三、UDP丢包率测试客户端四、用户使用说明(输入 / 输出规定)五、部分运行结果六、UDP 丢包率的测试结果分析(1)讨论服务器接收缓冲区的大小对丢包率的影响:(2)讨论包长,超时时间,以及发包的个数对丢包率的影响:

一、无连接应用程序丢包率测试

UDP的不可靠性使得基于该协议的应用程序在数据通信过程中不可避免地会遇到丢包现象。

一方面,网络拥塞导致路由器转发数据报文时丢失;另一方面,慢速设备来不及处理快速到达的数据报文,使得接收缓存溢出而丢包,等等。在应用程序开发前,设计者需要对当前的网络状况和主机性能进行测试,以确定选择哪种协议承载运输、使用循环方式还是并发方式处理网络通信等等,其中丢包率测试是常用的项目,它可以辅助设计者对程序的可靠性进行直观的探测和诊断。

使用数据报套接字编程,在网络功能框架的基础上对回射服务器和客户端进行修改,实现丢包率测试工具。其中,服务器能够接收客户端发来的数据,统计数据报个数;客户端能够根据用户的指示向服务器批量发送数据。丢包率的计算公式如下:

丢包率=1-(服务器收到的报文个数/客户端发送的报文个数)×100%

要求实现接收缓存大小的修改功能,控制接收数据包的速度,能够给服务器在接收缓存

取不同值时丢包率的变化。画出数据表格,并给出分析。

二、UDP 丢包率测试服务端

//丢包率测试,服务器端#define NETWORK2_2_COMM_H#define NETWORK2_2_COMM_H#include <stdio.h>#include <stdlib.h>#include <winsock2.h>#include <inaddr.h>#include <string.h>#pragma comment(lib, "ws2_32.lib")#define MAXLINE 4096 // 接收缓冲区长度#define SEVER_PORT 13131 // int SETBUFF = 128; // 设置缓冲区大小int RECVTIMEOUT = 1; // 设置服务器收包超时时间(ms)/*套接字初始化*/ int StartUp(){WORD w_version = MAKEWORD(2, 2);WSADATA wsa_data;int res = WSAStartup(w_version, &wsa_data);if (res != 0){printf("WSAStartup Error:%d\n",WSAGetLastError());return -1;}//版本号错误 if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2){printf("WSAStartup Error:%d\n",WSAGetLastError());WSACleanup();return -1;}return 0; //成功返回0 }/*释放资源*/ int cleanUp(){int res = WSACleanup();if (res == SOCKET_ERROR){printf("WSACleanup Error:%d",WSAGetLastError()); return -1;}return 0;}/*断开连接,释放资源*/ int closeConn(SOCKET sock_conn){int res = closesocket(sock_conn); //关闭连接if (res == SOCKET_ERROR){printf("关闭连接失败%d\n",WSAGetLastError());return -1;}res = cleanUp();return res;}/*服务器初始化*/ SOCKET udpServerInit(int port){int res = -1;SOCKET sock_listen;const int on = 1;// 绑定地址、端口struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htonl(INADDR_ANY);server_addr.sin_port = htons(port);//创建监听套接字sock_listen = socket(AF_INET, SOCK_DGRAM, 0);if (sock_listen == INVALID_SOCKET){printf("WSAStartup Error:%d\n",WSAGetLastError());cleanUp();return -1;}//绑定服务器地址res = bind(sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr));if (res == SOCKET_ERROR){printf("绑定失败:%d\n",WSAGetLastError());closeConn(sock_listen);return -1;}return sock_listen;}/*服务器丢包率测试函数*/int udpServerPacket(SOCKET sock_conn) {int sock_res = 0;int count = 0;sockaddr_in client_addr;int addr_len = sizeof(sockaddr_in);char recv_data[MAXLINE];do {memset(recv_data, 0, MAXLINE);sock_res = recvfrom(sock_conn, recv_data, MAXLINE, 0, (SOCKADDR *) &client_addr, &addr_len);if (sock_res >= 0) {count += 1;} else {int error = WSAGetLastError();// 10060 超时if (error != 10060) {printf("recvfrom timeout error\n");} else {sock_res = 0;break;}}} while (sock_res >= 0);if (count > 0) {printf("共接收到的包的数量为:%d\n",count);}return sock_res;}int main(int argc, char *argv[]) {int sock_res;SOCKET sock_listen;if (StartUp() == -1) return -1; // 启动sock_listen = udpServerInit(SEVER_PORT); //监听if (sock_listen == -1) return -1;puts("服务器启动成功");//设置SO_RCVBUF选项,改变缓冲区大小int recv_buff_len;int len = sizeof(recv_buff_len);printf("默认缓冲区大小:%d\n",recv_buff_len);if (getsockopt(sock_listen, SOL_SOCKET, SO_RCVBUF, (char *) &recv_buff_len, &len)<0) {puts("getsockopt error");return -1;}//更改缓冲区大小printf("输入设置的缓冲区大小:");scanf("%d",&SETBUFF);recv_buff_len = SETBUFF;if (setsockopt(sock_listen, SOL_SOCKET, SO_RCVBUF, (char *) &recv_buff_len, len)<0) {puts("setsockopt error");return -1;}printf("更改后的缓冲区大小:%d\n",recv_buff_len);//设置接收包的超时时间printf("输入接受包的超时时间(ms):");scanf("%d",&RECVTIMEOUT);int time_out = RECVTIMEOUT; //设置SO_RCVTIMEO选项if (setsockopt(sock_listen, SOL_SOCKET, SO_RCVTIMEO, (char *) &time_out, sizeof(time_out))<0) {puts("setsockopt error");return -1;}printf("超时时间为:%d ms\n",time_out);puts("===================================");while (1) {// 回射sock_res = udpServerPacket(sock_listen);// 出错,继续其他客户端请求if (sock_res == -1) puts("此用户连接失败,继续其他客户端请求..");}// 关闭监听服务closeConn(sock_listen);return 0;}

三、UDP丢包率测试客户端

//丢包率测试,客户端#define NETWORK2_2_COMM_H#define NETWORK2_2_COMM_H#include <stdio.h>#include <stdlib.h>#include <winsock2.h>#include <inaddr.h>#include <string.h>#pragma comment(lib, "ws2_32.lib")#define MAXLINE 4096 // 接收缓冲区长度#define SEVER_PORT 13131 int TIMES = 1024; // 设置客户端总的发包次数/*套接字初始化*/ int StartUp(){WORD w_version = MAKEWORD(2, 2);WSADATA wsa_data;int res = WSAStartup(w_version, &wsa_data);if (res != 0){printf("WSAStartup Error:%d\n",WSAGetLastError());return -1;}//版本号错误 if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2){printf("WSAStartup Error:%d\n",WSAGetLastError());WSACleanup();return -1;}return 0; //成功返回0 }/*释放资源*/ int cleanUp(){int res = WSACleanup();if (res == SOCKET_ERROR){printf("WSACleanup Error:%d",WSAGetLastError()); return -1;}return 0;}/*断开连接,释放资源*/ int closeConn(SOCKET sock_conn){int res = closesocket(sock_conn); //关闭连接if (res == SOCKET_ERROR){printf("关闭连接失败%d\n",WSAGetLastError());return -1;}res = cleanUp();return res;}/*客户端连接初始化*/SOCKET udpClientInit(char *server_ip, u_short port, sockaddr_in &server_addr, bool flag) {int sock_res = -1;SOCKET sock_conn;// 设置地址、端口memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(port);server_addr.sin_addr.S_un.S_addr = inet_addr(server_ip);//创建套接字sock_conn = socket(AF_INET, SOCK_DGRAM, 0);// 创建失败if (sock_conn == INVALID_SOCKET) {printf("socket error:%d\n",WSAGetLastError());cleanUp();return -1;}if (flag) {// 请求连接服务器sock_res = connect(sock_conn, (struct sockaddr *) &server_addr, sizeof(server_addr));// 连接 服务器失败if (sock_res == SOCKET_ERROR) {printf("connect error:%d\n",WSAGetLastError());closeConn(sock_conn);return -1;}}return sock_conn; //连接成功}/*数据包发送函数*/int udpClientPacket(int times, int data_len, SOCKET sock_conn, SOCKADDR *server_addr, int addr_len) {int sock_res, item = 0;char send_data[MAXLINE];memset(send_data, 1, data_len);printf("发送包的个数:%d\n",times);for (item = 0; item < times; ++item) {sock_res = sendto(sock_conn, send_data, (int) strlen(send_data), 0, (SOCKADDR *) server_addr, addr_len);if (sock_res == SOCKET_ERROR) {puts("send error");return -1;}}return sock_res;}int main() {int sock_res;SOCKET sock_conn;char server_ip[] = "10.236.10.200";struct sockaddr_in server_addr;int data_len = 8;if (StartUp() == -1) return -1; // 启动sock_conn = udpClientInit(server_ip, SEVER_PORT, server_addr, true); //连接if (sock_conn == -1) return -1;// 连接服务器成功puts("服务器连接成功");printf("输入发送数据包的个数:");scanf("%d",&TIMES);printf("输入包长:");scanf("%d",&data_len);sock_res = udpClientPacket(TIMES, data_len, sock_conn, (SOCKADDR *) &server_addr, sizeof(sockaddr_in));if (sock_res == -1) puts("客户端连接失败");closeConn(sock_conn);return sock_res;}

四、用户使用说明(输入 / 输出规定)

1. 对客户端,在与服务器连接成功后,需要输入“发送数据包的个数”以及“包长”,回车后就会发送,发送成功屏幕会显示发送数据包的个数,出错会显示错误信息以及错误号。

2. 对服务器端,在服务器启动成功后,需要输,“缓冲区的大小”以及“接收包的超时时间 ms”,然后服务器就可以开始接收客户端发来的包并在屏幕上显示“接收包的个数”。

五、部分运行结果

六、UDP 丢包率的测试结果分析

(1)讨论服务器接收缓冲区的大小对丢包率的影响:

包长,超时时间不变,改变服务器接收缓冲区的大小,以及发送包的个数,得到以下数据:

结论:

从表格可以看出,随着缓冲区大小的减小,丢包率上升。

(2)讨论包长,超时时间,以及发包的个数对丢包率的影响:

做法:服务器缓冲区大小不变,改变包长,超时时间,发送包的个数数据:见下一页表格结论:

随着超时时间的增加,丢包率减小随着包长的增加,丢包率增加随着发包次数的增加,丢包率增加

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。