您的位置:首页 > 其它

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

2014-08-25 15:02 183 查看

一、lwip稳定性测试

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

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

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

Client端的测试代码如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <netinet/tcp.h>

#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 <rtthread.h>
#include <lwip/sockets.h>

#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过滤器



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

未完待续。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: