【开源夏令营第七周】lwip稳定性测试

一、lwip稳定性测试

将龙芯2F笔记本作为TCP Client,开发板作为 TCP Server

笔记本构造随机长度(长度在1-1000之间)的随机字符串,TCP Server作为回显服务器

利用单线程的阻塞模型,测试了3*24小时 一切收发正常,发送420658个字符串,接收420658个字符串,平均来看一个字符串有0.5KB.

Client端的测试代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PORT "10001"
#define SERVADDR "fe80::200:eff:fe12:3456%eth1"
//static const char send_data[] = "This is TCP Client from Debian.";
void setrandstr(char str[], int number);

int main(void)
{
	struct addrinfo hints = {0};
	struct addrinfo *res;
	int get_err;
	int sockfd;
	int sendnum, recvnum;
	int number;
	char send_data[1024];
	char buffer[1024];
	int enable = 1;

	hints.ai_family = AF_INET6;
	hints.ai_socktype = SOCK_STREAM;	
	get_err = getaddrinfo(SERVADDR, PORT, &hints, &res);
	if(get_err)
	{
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(get_err));
		return 1;
	}
	
	sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if(sockfd < 0)
	{
		perror("socket");
		return 1;
	}
	
	setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void *)&enable, sizeof(enable));
	if(connect(sockfd, res->ai_addr, res->ai_addrlen) < 0)
	{
		perror("connect");
		return 1;
	}
	sendnum = 0; recvnum = 0;
	while(1)
	{
                //随机产生字符串的长度
		srand((unsigned int)time((time_t *)NULL));
		number = (rand() % 999) + 1;
//		printf("%d\n", number);
		setrandstr(send_data, number);
		printf("%s\n", send_data);
		send(sockfd, send_data, strlen(send_data), 0);
		sendnum ++;
		printf("reading message\n");
		memset(send_data, 0, sizeof(send_data));
		read(sockfd, buffer, 1024);
		recvnum++;
		printf("got '%s', sendnum:%d, recvnum:%d\n", buffer, sendnum, recvnum);
		memset(buffer, 0, sizeof(buffer));
	}
	close(sockfd);
	return 0;
}

// 产生随机字符串
void setrandstr(char str[], int number)
{
	char standard[64] = "00123456789ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	char genstr[2];
	int i;
	srand((unsigned int)time((time_t *)NULL));
	for(i = 0; i< number; i++)
	{
		sprintf(genstr, "%c", standard[(rand()%62+1)]);
		strcat(str, genstr);
	}
	str[number] = '\0';
//	printf("%s\n", str);
}
Server的测试代码如下:

#include 
#include 

#define SERV_PORT 10001
#define BUF_SIZE  1024
#define BACKLOG	  5
//static const char send_data[] = "This is TCP Server from RT-Thread.";

void tcp_robust_test(void *parameter)
{
	int sockfd, clientfd;
	struct sockaddr_in6 server_addr6, client_addr6;
	int bytes_received;
	char *recv_data;
	rt_uint32_t sin_size;
	rt_bool_t stop = RT_FALSE;

//	recv_data = rt_malloc(BUF_SIZE);
//	if(recv_data == RT_NULL)
//	{
//		rt_kprintf("No memory\n");
//		return ;
//	}
	
	if((sockfd = socket(PF_INET6, SOCK_STREAM, 0)) == -1)
	{
		rt_kprintf("Socket error\n");
//		rt_free(recv_data);
		return ;
	}
	
	server_addr6.sin6_family = AF_INET6;
	memcpy(server_addr6.sin6_addr.s6_addr, IP6_ADDR_ANY, 16);
	server_addr6.sin6_port = htons(SERV_PORT);

	if(bind(sockfd, (struct sockaddr *)&server_addr6, sizeof(struct sockaddr)) == -1)
	{
		rt_kprintf("Bind error\n");
//		rt_free(recv_data);
		return ;
	}
	if(listen(sockfd, BACKLOG) == -1)
	{
		rt_kprintf("Listen error\n");
//		rt_free(recv_data);
		return ;
	}

//	rt_sprintf(recv_data, "%4d", SERV_PORT);
//	rt_kprintf("\nTCPServer Waiting for client on port %s...\n", recv_data);
	
	while(stop != RT_TRUE)
	{ 
		sin_size = sizeof(struct sockaddr_in6);
		clientfd = accept(sockfd, (struct sockaddr *)&client_addr6, &sin_size);
		rt_kprintf("I got a connection from (IP:%s, PORT:%d\n)", inet6_ntoa(client_addr6.sin6_addr), ntohs(client_addr6.sin6_port));
		while(1)
		{
			recv_data = rt_malloc(BUF_SIZE);
			if(recv_data == RT_NULL)
			{
				rt_kprintf("No memory\n");
				return ;
			}
//			send(clientfd, send_data, strlen(send_data), 0);

			bytes_received = recv(clientfd, recv_data, BUF_SIZE, 0);
			if(bytes_received <= 0)
			{
				closesocket(clientfd);
				break;
			}
			recv_data[bytes_received] = '\0';
//			if(strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0)
//			{
//				closesocket(clientfd);
//				break;
//			}
//			else if(strcmp(recv_data, "exit") == 0)
//			{
//				closesocket(clientfd);
//				stop = RT_TRUE;
//				break;
//			}
//			else
//			{
////				rt_kprintf("RECEIVED DATA = %s\n", recv_data);
//			}
			send(clientfd, recv_data, strlen(recv_data), 0);
			rt_free(recv_data);
//			memset(recv_data, 0, sizeof(recv_data));
		}
	}
	
	closesocket(sockfd);
	rt_free(recv_data);
	
	return ;
}

int tcp_robust_init()
{
	rt_thread_t tid = RT_NULL;
	tid = rt_thread_create("tcpserver", tcp_robust_test, RT_NULL, 4096, 19, 1);
	if(tid != RT_NULL)
	{
		rt_kprintf("tcp robust test server init ok\n");
		rt_thread_startup(tid);
		return 0;
	}
	else
	{
		rt_kprintf("tcp robust test server init failed\n");
		return -1;
	}
}

二、lwip ping6

要写ping 的程序必须使用BSD 原始套接字,原理为:某一主机向网络上主机发送ICMP请求报文,如果系统得到了报文会将报文一模一样的传给发送者。在ipv6中须使用icmpv6过滤器,因为相邻的主机会发来邻居请求报文,这是ICMPV6类型的,如下所示:


但是lwip-head并未实现如下icmpv6过滤器

【开源夏令营第七周】lwip稳定性测试_第1张图片


但是可以根据接收到的pid号来判断是否是本主机发出的icmp request包的反馈。

未完待续。。


你可能感兴趣的:(开源夏令营)