由于做的项目对于网络和USB的读写速度有很高的要求,因此新拿回来的板子要测试网络和usb的最佳传输速度。要考虑不少因素,先把我能想到的记录下来。

    测试的环境是开发板和ubuntu虚拟机。虚拟机通过桥接和开发板处于同一局域网内,开发板是linux操作系统。

    网络传输的测试肯定要传输文件过去,这里要传输的文件不能从存储器上读取,因为要排除存储器读写的影响,这就需要建立一个大文件但是不需要读写存储器,我使用了 如下命令:

dd if=/dev/zero of=test bs=1M count=0 seek=1000

    此时创建的文件在文件系统中的显示大小为1000MB,但是并不实际占用block,因此创建速度与内存速度相当,seek的作用是跳过输出文件中指定大小的部分,这就达到了创建大文件,但是并不实际写入的目的。当然,因为不实际写入硬盘,所以你在容量只有10G的硬盘上创建100G的此类文件都是可以的。

    文件传输自然要用到socket通信的知识了,这方面的知识请大家查阅关于socket的相关资料。这里要说的是send和rev函数。有关这两个函数的介绍请移步:http://www.cnblogs.com/keepsimple/archive/2013/04/28/3049138.html

这里这段话对我来说很重要

linux下可用sysctl -a | grep net.ipv4.tcp_wmem查看系统默认的发送缓存大小:

net.ipv4.tcp_wmem = 4096 16384 81920

这有三个值,

第一个值是socket的发送缓存区分配的最少字节数,

第二个值是默认值(该值会被net.core.wmem_default覆盖),缓存区在系统负载不重的情况下可以增长到这个值,

第三个值是发送缓存区空间的最大字节数(该值会被net.core.wmem_max覆盖).

根据实际测试,如果手工更改了net.ipv4.tcp_wmem的值,则会按更改的值来运行,否则在默认情况下,协议栈通常是按net.core.wmem_default和net.core.wmem_max的值来分配内存的.

举例来说,这是我开发板上的 执行

也就是说 这里发送默认缓存不是16384(16KB)而是160KB 。

    理解了socket缓存后,这样我每次发送的文件片段只要不超过160kb就都可以发送。这就是用户每次发送文件片段的最大大小,我们要测试的就是每次从开发板或者从pc发送给开发板时,用户选取多大的片段传送速度是最快的。这里用户的缓存通过设置一个较大的数组每次从大文件中读取相应大小的片段发送或者接收即可。下面是linux下服务器和客户端的源码

sever.c

////////////////////////////////////////////////////////////////////////
// file_server.c -- socket文件传输服务器端示例代码
// /////////////////////////////////////////////////////////////////////
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<time.h>
#define HELLO_WORLD_SERVER_PORT 6666
#define LENGTH_OF_LISTEN_QUEUE 20
//#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512 int main(int argc, char **argv)
{
// set socket's address information
// 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); // create a stream socket
// 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
int server_socket = socket(PF_INET, SOCK_STREAM, 0);
if (server_socket < 0)
{
printf("Create Socket Failed!\n");
exit(1);
} // 把socket和socket地址结构绑定
if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
{
printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
exit(1);
} // server_socket用于监听
if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
{
printf("Server Listen Failed!\n");
exit(1);
} // 服务器端一直运行用以持续为客户端提供服务
while(1)
{
// 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept
// 接受此请求,同时将client端的地址和端口等信息写入client_addr中
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr); // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
// 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
// 用select()来实现超时检测
// accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
// 这里的new_server_socket代表了这个通信通道
int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
if (new_server_socket < 0)
{
printf("Server Accept Failed!\n");
break;
} char buffer[100000];
bzero(buffer, sizeof(buffer));
//length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
//if (length < 0)
// {
// printf("Server Recieve Data Failed!\n");
// break;
// } //char file_name[FILE_NAME_MAX_SIZE + 1];
// bzero(file_name, sizeof(file_name));
// strncpy(file_name, buffer,
// strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
int BUFFER_SIZE,i=0 ;
printf("please input the send size ...") ;
scanf("%d",&BUFFER_SIZE) ;
char count[10];
printf("input the file size :/M") ;
scanf("%s",count) ; char file_name[100]="dd if=/dev/zero of=./test bs=1M count=0 seek=";
strcat(file_name,count);
//printf("%s\n",file_name) ;
system(file_name);//execute the shell command
//printf("hello\n") ;
FILE *fp = fopen("./test", "r");
if (fp == NULL)
{
printf("File:\t%s Not Found!\n", file_name);
}
else
{
bzero(buffer, BUFFER_SIZE);
int file_block_length = 0;
clock_t start, finish;
double duration;
start = clock();
while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
{
//printf("file_block_length = %d time %d\n", file_block_length,i++); // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
if (send(new_server_socket, buffer, file_block_length, 0) < 0)
{
printf("Send File:\t%s Failed!\n", file_name);
break;
} bzero(buffer, sizeof(buffer));
}
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("send time %lf\n",duration) ;
fclose(fp);
printf("File:\t%s Transfer Finished!\n", file_name);
} //close(new_server_socket);
close(new_server_socket) ;
//shutdown(new_server_socket) ;
} close(server_socket); return 0;
}

client.c

////////////////////////////////////////////////////////////////////////
// file_server.c -- socket文件传输服务器端示例代码
// /////////////////////////////////////////////////////////////////////
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<time.h>
#define HELLO_WORLD_SERVER_PORT 6666
#define LENGTH_OF_LISTEN_QUEUE 20
//#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512 int main(int argc, char **argv)
{
// set socket's address information
// 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); // create a stream socket
// 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
int server_socket = socket(PF_INET, SOCK_STREAM, 0);
if (server_socket < 0)
{
printf("Create Socket Failed!\n");
exit(1);
} // 把socket和socket地址结构绑定
if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
{
printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
exit(1);
} // server_socket用于监听
if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
{
printf("Server Listen Failed!\n");
exit(1);
} // 服务器端一直运行用以持续为客户端提供服务
while(1)
{
// 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept
// 接受此请求,同时将client端的地址和端口等信息写入client_addr中
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr); // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
// 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
// 用select()来实现超时检测
// accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
// 这里的new_server_socket代表了这个通信通道
int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
if (new_server_socket < 0)
{
printf("Server Accept Failed!\n");
break;
} char buffer[100000];
bzero(buffer, sizeof(buffer));
//length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
//if (length < 0)
// {
// printf("Server Recieve Data Failed!\n");
// break;
// } //char file_name[FILE_NAME_MAX_SIZE + 1];
// bzero(file_name, sizeof(file_name));
// strncpy(file_name, buffer,
// strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
int BUFFER_SIZE,i=0 ;
printf("please input the send size ...") ;
scanf("%d",&BUFFER_SIZE) ;
char count[10];
printf("input the file size :/M") ;
scanf("%s",count) ; char file_name[100]="dd if=/dev/zero of=./test bs=1M count=0 seek=";
strcat(file_name,count);
//printf("%s\n",file_name) ;
system(file_name);//execute the shell command
//printf("hello\n") ;
FILE *fp = fopen("./test", "r");
if (fp == NULL)
{
printf("File:\t%s Not Found!\n", file_name);
}
else
{
bzero(buffer, BUFFER_SIZE);
int file_block_length = 0;
clock_t start, finish;
double duration;
start = clock();
while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
{
//printf("file_block_length = %d time %d\n", file_block_length,i++); // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
if (send(new_server_socket, buffer, file_block_length, 0) < 0)
{
printf("Send File:\t%s Failed!\n", file_name);
break;
} bzero(buffer, sizeof(buffer));
}
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("send time %lf\n",duration) ;
fclose(fp);
printf("File:\t%s Transfer Finished!\n", file_name);
} //close(new_server_socket);
close(new_server_socket) ;
//shutdown(new_server_socket) ;
} close(server_socket); return 0;
}

    将文件编译完成,服务端执行服务端程序,客户端执行 后边加上 服务器的ip地址。然后就会提示输入用户要求的发送缓存和接受缓存。填入接可,一般是1K的整数倍,不要超过160K。然后即可计算出每次传输接收和发送用时,用作比较。

    这两个文件基本实现了linux平台下,网络测试的要求。还有很多不足之处,以后再做修改。

    参考资料:

http://blog.csdn.net/herecles/article/details/8146017

http://blog.sina.com.cn/s/blog_858820890100sfpx.html

http://www.cnblogs.com/pang1567/p/3562029.html

linux下开发板网络速度测试记录的更多相关文章

  1. Hi3516开发笔记(一):海思HI3516DV300芯片介绍,入手开发板以及Demo测试

    前言   目前主流国产芯片为RV11XX.RK33XX.Hi35XX系列,本系列开启Hi3516系列的开发教程.   Hi3516DV300芯片介绍   Hi3516DV300为专业行Smart IP ...

  2. AC6102开发板USB3.0测试和使用说明

    AC6102开发板USB3.0测试和使用说明 概述 AC6102上集成了一颗Cypress 推出的高性能USB3.0传输芯片CYUSB3014,Cypress称之为EZ-USBFX3.该芯片性能强劲, ...

  3. Linux下开发STM32单片机

    一开始学习51单片机就是用的MDK这个IDE软件,IDE软件虽然看起来直观好像更加容易入门(因为有界面看起来很形象),但是实际上IDE却是向我们这些入门人员隐藏了背后真实存在的过程,让我们以为编译就是 ...

  4. linux下重要的网络配置文件

    linux下重要的网络配置文件:一; /etc/sysconfig/network  文件内容: NETWORKING=yes                                <= ...

  5. linux下history命令显示历史指令记录的使用方法

    Linux系统当你在shell(控制台)中输入并执行命令时,shell会自动把你的命令记录到历史列表中,一般保存在用户目录下的.bash_history文件中.默认保存1000条,你也可以更改这个值 ...

  6. Linux下高并发网络编程

      Linux下高并发网络编程 1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时, 最高的并发数量都要受到系统对用户单一进程同时可打 ...

  7. 在Linux下,在网络没有配置好前,怎样查看网卡的MAC地址?

    在Linux下,在网络没有配置好前,怎样查看网卡的MAC地址? 使用 dmesg 与 grep 命令来实际,例如以下: [root@localhost ~]# dmesg | grep eth e10 ...

  8. 使用eclipse在linux下开发C/C++

    一直在Linux下开发,苦于没有IDE,一般都是自己编写Makefile,然后在windows下用文本编辑器ftp打开文件编辑,然后在linux下完成编译.调试代码也只能是命令行用gdb进行调试,相当 ...

  9. linux下开发C语言需要安装的manpages手册

    linux下开发C代码需要安装的manpages: $ sudo apt-get install manpages$ sudo apt-get install manpages-dev$ sudo a ...

随机推荐

  1. [Angular2 Router] CanActivate Route Guard - An Example of An Asynchronous Route Guard

    In this tutorial we are going to learn how we can to configure an can activate route guard in the An ...

  2. js正則表達式语法

    1. 正則表達式规则 1.1 普通字符 字母.数字.汉字.下划线.以及后边章节中没有特殊定义的标点符号,都是"普通字符".表达式中的普通字符,在匹配一个字符串的时候,匹配与之同样的 ...

  3. Android实现Filterable通过输入文本框实现联系人自动筛选

    相信大家一定在见过手机通讯录的一个情景就是使用在选人的时候输入文本框里的数据就能自动筛选.实现的效果如下图. 其实实现这样的效果相信大家一定对另外一个控件不陌生那就AutoCompleteTextvi ...

  4. iOS开发——实战总结OC篇&网易彩票开发知识点总结

    网易彩票开发知识点总结 关于网易彩票开发中遇到了不少的坑,弄了好久才弄懂,或者有些犹豫很久没用就不记得了,所以这里就总结了一下,希望以后不会忘记,就算忘记也能快速查看! /************** ...

  5. linux内存——/proc/sys/vm/drop_caches

      原贴:http://www.linuxfly.org/post/320/ http://blog.csdn.net/chinalinuxzend/article/category/265273/2 ...

  6. IPC——信号

    Linux进程间通信——使用信号 一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过 ...

  7. qwt 介绍

    QWT,全称是Qt Widgets for Technical Applications,是一个基于LGPL版权协议的开源项目, 可生成各种统计图. [QWT简介] 它为具有技术专业背景的程序提供GU ...

  8. Tomcat7启动报Error listenerStart错误--转载

    原文地址:http://www.cnblogs.com/nayitian/p/3439336.html 问题 Tomcat7在启动时报错,详细信息如下: 十一月 23, 2013 7:21:58 下午 ...

  9. LeetCode32 Longest Valid Parentheses

    题目: Given a string containing just the characters '(' and ')', find the length of the longest valid ...

  10. 重构7-Rename(method,class,parameter)

    这是我最常用也是最有用的重构之一.我们对方法/类/参数的命名往往不那么合适,以至于误导阅读者对于方法/类/参数功能的理解.这会造成阅读者的主观臆断,甚至引入bug.这个重构看起来简单,但却十分重要. ...