linux-TCP网络接口传输速率测试程序

时间:2021-01-24 10:14:40

原先想测试板子的网口通信速率,但是由于开发环境没有外网,没法用现成的各种工具,只好自力更生。所以写了一个基于socket的小代码,拿出来跟大家分享一下。在centos和ubuntu环境下编译成功。ps:由于使用了多线程,因此编译是要加上-lpthread的选项哦。

代码链接:https://github.com/yangyinqi/nic_speed

对于测试网口传输速率这种需求,既然要测量比较纯粹的传输速率,因此连接直接建立在tcp传输层上,排除各种应用层协议解析带来的延时。

服务端:

服务端负责向客户连接不断的发送数据包,长度为1400,因为考虑到链路层中mtu大小一般为1500。定义一个带头节点单向链表用来存储各个连接上的数据包总数,方便计算速率。

typedef struct _thread_args {
int client_sockfd;
char *data_pointer;
long packet_count;
int thread_seq;
pthread_t thread_id;
struct _thread_args *next;
}thread_args;
头节点存放监听套接字信息,以及速率计算线程的信息。

在主线程中阻塞在accept处,有返回时创建一个线程来维持这个连接,向客户端发送数据。

int thread_seq = 0;
client_len = sizeof(client_address);
while(1) {
printf("Server waiting.\n");
client_sockfd = accept(listen_sockfd, (struct sockaddr *)&client_address, &client_len);
if((response_args = (thread_args *)malloc(sizeof(thread_args))) == NULL) {
printf("Thread args malloc failed.\n");
close(listen_sockfd);
break;
}

response_args->thread_seq = thread_seq++;
response_args->client_sockfd = client_sockfd;
response_args->packet_count = 0;
response_args->data_pointer = send_buff;
response_args->next = response_head->next;
response_head->next = response_args;

//create thread for send data to client_sockfd
if(pthread_create(&(response_args->thread_id), NULL, thread_response, (void *)response_args) != 0) {
perror("Thread response create failed");
break;
}
}

客户端处理线程如下:

void *thread_response(void *arg)
{
thread_args *internal_args = (thread_args *)arg;
internal_args->packet_count = 0;
int sem_status = 0;

pthread_detach(pthread_self());
printf("Server the client,fd:%d. Thread No.%d.\n", internal_args->client_sockfd, internal_args->thread_seq);
while(1) {
sem_getvalue(&sem_send_data, &sem_status);
if(sem_status == 0) {
continue;
}
else {
int wr_res = send(internal_args->client_sockfd, internal_args->data_pointer, MTU_NUM, 0);
if(wr_res == 0) {
printf("Disconnected!\n");
break;
}
else if(wr_res < 0) {
perror("Error in connection");
break;
}
(internal_args->packet_count)++;
}
}

close(internal_args->client_sockfd);
pthread_exit("");
}

计算速率的线程通过线程信号量控制响应线程的运行逻辑。具体可以参照文章开头连接中的程序,这里不贴出具体代码。

客户端:

客户端的逻辑是,分别创建若干个线程(本例中是8,因为测试环境的cpu是8核),然后在线程中进行套接字的创建,connect,recv等等操作。注意此处不可以创建一个套接字,然后在多个线程里直接connect,我就犯了这个错误,发现这样子服务端会当作一个链接请求去处理。

具体代码参照文章开头github地址。

测试:

回来后进行了本地测试,将client.h中的IP设置为127.0.0.1,然后起两个终端分别运行服务器与客户端:

服务器打印:

Server waiting.
Server the client,fd:5. Thread No.1.
Server waiting.
Server the client,fd:6. Thread No.2.
Server the client,fd:4. Thread No.0.
Server waiting.
Server waiting.
Server waiting.
Server the client,fd:7. Thread No.3.
Server the client,fd:8. Thread No.4.
Server the client,fd:9. Thread No.5.
Server waiting.
Server waiting.
Server the client,fd:10. Thread No.6.
Server the client,fd:11. Thread No.7.
No.7 client count packet:1516597.
No.6 client count packet:1486722.
No.5 client count packet:1494818.
No.4 client count packet:1522742.
No.3 client count packet:1541814.
No.2 client count packet:1405446.
No.1 client count packet:1586907.
No.0 client count packet:1598772.
Total length:12153818bytes. Sample timing:5s, Transmittion speed:3245.42Mb/s
No.7 client count packet:2625885.
No.6 client count packet:2658081.
No.5 client count packet:2788680.
No.4 client count packet:2387941.
No.3 client count packet:2776665.
No.2 client count packet:2514184.
No.1 client count packet:2648765.
No.0 client count packet:2461294.
Total length:20861495bytes. Sample timing:5s, Transmittion speed:5570.62Mb/s
No.7 client count packet:2431768.
No.6 client count packet:2388140.
No.5 client count packet:2415890.
No.4 client count packet:2329173.
No.3 client count packet:2550932.
No.2 client count packet:2524958.
No.1 client count packet:2492313.
No.0 client count packet:2537837.
Total length:19671011bytes. Sample timing:5s, Transmittion speed:5252.73Mb/s
No.7 client count packet:1855025.
No.6 client count packet:1954570.
No.5 client count packet:1929904.
No.4 client count packet:1898067.
No.3 client count packet:2134070.
No.2 client count packet:1930880.
No.1 client count packet:1965562.
No.0 client count packet:1834356.
Total length:15502434bytes. Sample timing:5s, Transmittion speed:4139.60Mb/s
客户端打印:

Creating thread..
Connect successfully,seq_num:3, id:-1562437888
Connect successfully,seq_num:5, id:-1587616000
Connect successfully,seq_num:4, id:-1570830592
Connect successfully,seq_num:5, id:-1596008704
Connect successfully,seq_num:6, id:-1604401408
Thread create finished. Test running...
Connect successfully,seq_num:5, id:-1579223296
Connect successfully,seq_num:8, id:-1621186816
Connect successfully,seq_num:8, id:-1612794112
Main process.

可以看到本地回环网络的速度确实很快。千兆网卡的实际测试速率大概在112Mb/s左右,有兴趣的读者可以自己跑一边测试一下。