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 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 40G光纤模块UDP数据传输测试 -> 正文阅读

[网络协议]40G光纤模块UDP数据传输测试

之前做过一次使用两台电脑传输数据,记录一下。

两台linux系统的电脑主机,各插上一块40G光纤模块,通过光纤连接。一台电脑发送数据,另一台接收数据。测试两台主机收发30Gbs没有问题。
1.为了支持40G光纤模块,首先需要安装驱动。
2.为了数据正常发送,建议关闭防火墙。
3.如果数据包很长,建议设置mtu。当然更长的数据包,会有更高校的传输效率。

问题记录及解决。

1.出现问题	
接收端接收数据包丢包?
2.原因
通过更换不同的电脑主机发现,和电脑cpu的性能有关,cpu性能高的主机向cpu性能低的主机发送数据,接收端接收数据丢包。通过放缓发送端的速率可保证接收端不丢包。

发送端代码:

//
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <unistd.h>

#define CMD_LEN 20

const int LOCAL_PORT = 12368;
const int REMOTE_PORT = 12384;
// const char LOCAL_IP[]="192.168.11.101";
// const char REMOTE_IP[]="192.168.11.101";
const char LOCAL_IP[]="192.168.11.100";
const char REMOTE_IP[]="192.168.11.101";
const int MAXLINE = 2048;

const int WIDTH = 7680;
const int HEIGHT = 4320;


const unsigned char CMD_REQUEST_DATA_8K[CMD_LEN]={0x81,0x00,0xA5,0x5A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

int send_frame(int sockfd,struct sockaddr *pcliaddr, socklen_t clilen, unsigned char* dataptr)
{
	static int count=0;
	for(int i=0;i<HEIGHT;i++)
	{
		if(WIDTH != sendto(sockfd , dataptr, WIDTH , 0 , pcliaddr , clilen))
		{
			perror("sendto error");
			exit(1);
		}//if
		dataptr += WIDTH;
	}
	count++;
	printf("send a frame__%d\n",count);
	if (count%10==0)  //放缓发送速率。
	{
		usleep(1000000);
	}
	
}

void clearRecvBuffer(int sockfd)
{
	struct timeval time_out;
	time_out.tv_sec=0;
	time_out.tv_usec=0;

	fd_set read_fds;
	FD_ZERO(&read_fds);
	FD_SET(sockfd,&read_fds);

	int res=-1;
	char recv_data[2];
	memset(recv_data,0,sizeof(recv_data));
	while (1)
	{
		res = select(FD_SETSIZE,&read_fds,NULL,NULL,&time_out);
		if(res==0)
		{
			break;
		}
		recv(sockfd,recv_data,1,0);
	}	
}

void dg_echo(int sockfd , struct sockaddr *pcliaddr , socklen_t clilen)
{
	int n;
	unsigned char msg[CMD_LEN];
	unsigned char* data = (unsigned char*)malloc(WIDTH*HEIGHT); //create the data of frame.
	while(1)
	{
		if( CMD_LEN != recvfrom(sockfd , msg , CMD_LEN , 0 , NULL , NULL))
		{
			printf("recvfrom error\n");		
			//clearRecvBuffer(sockfd);
			//exit(1);
		}else{
			printf("recv a request cmd\n");
		}
		if(msg[0]==0x81)
		{
			msg[0]=0;
			send_frame(sockfd, pcliaddr,clilen,data);
		}


	}//while

}

int main(int argc , char **argv)
{
	int sockfd,t;
	struct sockaddr_in servaddr , cliaddr;

	bzero(&cliaddr , sizeof(cliaddr));
	cliaddr.sin_family = AF_INET;
	//cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	cliaddr.sin_port = htons(REMOTE_PORT);
	if((t = inet_pton(AF_INET , REMOTE_IP, &cliaddr.sin_addr)) <= 0)
	{
		perror("inet_pton error");
		exit(1);
	}//if

	bzero(&servaddr , sizeof(servaddr));
	servaddr.sin_family = AF_INET;

	servaddr.sin_port = htons(LOCAL_PORT);
	if((t = inet_pton(AF_INET , LOCAL_IP, &servaddr.sin_addr)) <= 0)
	{
		perror("inet_pton error");
		exit(1);
	}//if
	if((sockfd = socket(AF_INET , SOCK_DGRAM , 0)) < 0)
	{
		perror("socket error");
		exit(1);
	}//if
 	int opt = 1;
	setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR, (const void *) &opt, sizeof(opt));

	//缓冲区设置
	int err;
	int snd_size = 35*1024*1024;
	err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &snd_size, sizeof(snd_size));
	if(err<0)
	{
		printf("set send buff failed!\n");
	}
	int rcv_size = 35*1024*1024;
	err = setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF, (char *)&rcv_size, sizeof(rcv_size));
	if(err<0){
		printf("set rev buff failed!\n");
	}

	if(bind(sockfd , (struct sockaddr *)&servaddr , sizeof(servaddr)))
	{
		perror("bind error");
		exit(1);
	}//if

	int n=0;
	char mesg[1000];
	if( (n= recvfrom(sockfd , mesg , 1000 , 0 , NULL , NULL))<0)
	{				
		exit(1);
	}else{
		printf("recv a connection\n");
		printf("recv: %s\n",mesg);
	}

	//设置超时20ms
	// struct timeval tv;
	// socklen_t optlen = sizeof(struct timeval);
	// tv.tv_sec = 1; tv.tv_usec = 20000;
	// setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, optlen);

	printf("be ready to send frames-----------------.\n");
	dg_echo(sockfd , (struct sockaddr *)&cliaddr, sizeof(cliaddr));	
}

接收端代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <unistd.h>

#define CMD_LEN 20

const int LOCAL_PORT = 12384;
const int REMOTE_PORT = 12368;
 const char LOCAL_IP[]="192.168.11.101";
 const char REMOTE_IP[]="192.168.11.100";
//const char LOCAL_IP[]="127.0.0.1";
//const char REMOTE_IP[]="127.0.0.1";
const int MAXLINE = 2048;

const int WIDTH = 7680;
const int HEIGHT = 4320;


const unsigned char CMD_REQUEST_DATA_8K[CMD_LEN]={0x81,0x00,0xA5,0x5A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

void clearRecvBuffer(int sockfd)
{
	struct timeval time_out;
	time_out.tv_sec=0;
	time_out.tv_usec=0;

	fd_set read_fds;
	FD_ZERO(&read_fds);
	FD_SET(sockfd,&read_fds);

	int res=-1;
	char recv_data[2];
	memset(recv_data,0,sizeof(recv_data));
	while (1)
	{
		res = select(FD_SETSIZE,&read_fds,NULL,NULL,&time_out);
		if(res==0)
		{
			break;
		}
		recv(sockfd,recv_data,1,0);
	}	
}

int recv_frame(int sockfd,struct sockaddr *pcliaddr, socklen_t clilen, unsigned char* dataptr)
{
	static int count=0;
	static int count_error=0;
	int n=-1;
	socklen_t len;
	len = clilen;
	count++;
	for(int i=0;i<HEIGHT;i++)
	{
		if((n = recvfrom(sockfd , dataptr, WIDTH , 0 , pcliaddr , &len))<0)
		{
			count_error++;
			printf("packet=%d ----------------recvfrom error=%d\n",i,count_error);
			clearRecvBuffer(sockfd);
			break;
		}//if
		dataptr += WIDTH;
	}
	printf("recv a frame__%d-------lost=%d\n",count,count_error);
}


void dg_echo(int sockfd , struct sockaddr *pcliaddr , socklen_t clilen)
{
	int n;
	// socklen_t len;
	// len = clilen;
	unsigned char *pdata = (unsigned char*)malloc(WIDTH*HEIGHT);
	for( ; ;)
	{
		if((CMD_LEN != sendto(sockfd , CMD_REQUEST_DATA_8K , CMD_LEN , 0 , pcliaddr , clilen)))
		{
			perror("sendto error");
			exit(1);
		}else{
			printf("send a request cmd.\n");
		}
		recv_frame(sockfd, pcliaddr, clilen,pdata);
	}//for

}

int main(int argc , char **argv)
{
	int sockfd,t;
	struct sockaddr_in servaddr , cliaddr;

	bzero(&cliaddr , sizeof(cliaddr));
	cliaddr.sin_family = AF_INET;
	//cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	cliaddr.sin_port = htons(REMOTE_PORT);
	if((t = inet_pton(AF_INET , REMOTE_IP, &cliaddr.sin_addr)) <= 0)
	{
		perror("inet_pton error");
		exit(1);
	}//if

	bzero(&servaddr , sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	//servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(LOCAL_PORT);
	if((t = inet_pton(AF_INET , LOCAL_IP, &servaddr.sin_addr)) <= 0)
	{
		perror("inet_pton error");
		exit(1);
	}//if
	if((sockfd = socket(AF_INET , SOCK_DGRAM , 0)) < 0)
	{
		perror("socket error");
		exit(1);
	}//if

	//ip地址重用
 	int opt = 1;
	setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR, (const void *) &opt, sizeof(opt));

	//超时设置
	struct timeval tv;
	int optlen = sizeof(struct timeval);
	tv.tv_sec =0; tv.tv_usec = 30000;
	setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, optlen);

	//缓冲区设置
	int err;
	int snd_size = 35*1024*1024;
	err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &snd_size, sizeof(snd_size));
	if(err<0)
	{
		printf("set send buff failed!\n");
	}
	int rcv_size = 35*1024*1024;
	err = setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF, (char *)&rcv_size, sizeof(rcv_size));
	if(err<0){
		printf("set rev buff failed!\n");
	}

	if(bind(sockfd , (struct sockaddr *)&servaddr , sizeof(servaddr)))
	{
		perror("bind error");
		exit(1);
	}//if

	int n=0;
	char mesg[]="hello";
	if((n= sendto(sockfd , mesg , sizeof(mesg) , 0 , (struct sockaddr *)&cliaddr , sizeof(cliaddr)))<0)
	{
		perror("request connect,sendto error");
		exit(1);
	}

	printf("be ready to get frames--------------------.\n");
	dg_echo(sockfd , (struct sockaddr *)&cliaddr, sizeof(cliaddr));	
}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-07-15 16:36:12  更:2021-07-15 16:37:07 
 
开发: 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年5日历 -2024/5/6 12:27:16-

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