searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

netperf TCP_CRR模式代码解读及使用方法

2024-09-18 09:21:35
96
0

1.简介

netperf 是一个用于网络性能测试的工具,专门设计来衡量各种类型的网络吞吐量和延迟。它能够在客户端和服务器端进行通信,通过运行不同的测试来评估网络的性能。netperf 常被用于测量 TCP、UDP 等协议的性能,在紫金DPU中用于测试网络性能。TCP_CRR(连接请求响应)测试,是其中的一种测试模式,用于测量在创建和关闭连接时的性能,通常用于模拟短时连接的应用场景。

2.代码解读

2.1 初始化阶段

为消息缓冲区分配内存,分配的大小基于发起端发送的请求(tcp_conn_rr_request)。根据请求中的对齐方式和偏移量设置接收(recv_message_ptr)和发送(send_message_ptr)缓冲区。

netperf_response.content.response_type = TCP_CRR_RESPONSE;
message = (char *)malloc(DATABUFFERLEN);
/* ... */
recv_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->recv_alignment, tcp_conn_rr_request->recv_offset);
send_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->send_alignment, tcp_conn_rr_request->send_offset);


2.2 监听端口等待连接

使用 accept() 接受来自客户端的连接请求,将其分配给 s_data 套接字。如果连接成功,会进入数据传输阶段;如果失败,则返回相应的错误信息并关闭套接字。

s_listen = create_data_socket(local_res);
if (s_listen == INVALID_SOCKET) {
    netperf_response.content.serv_errno = errno;
    send_response();
    exit(1);
}
if (listen(s_listen, 128) == SOCKET_ERROR) {
    netperf_response.content.serv_errno = errno;
    close(s_listen);
    send_response();
    exit(1);
}

s_data = accept(s_listen, (struct sockaddr *)&peeraddr_in, &addrlen);
if (s_data == INVALID_SOCKET) {
    fprintf(where,"recv_tcp_conn_rr: accept: errno = %d\n",errno);
    close(s_listen);
    exit(1);
}

2.3 接收请求数据

从客户端接收请求消息,数据存放在 recv_message_ptr 指向的缓冲区中。函数通过 recv() 循环接收数据,直到接收到完整的请求或发生错误。如果接收到的字节数为 0,表示客户端关闭了连接,函数会处理连接关闭并跳出循环。

request_bytes_remaining = tcp_conn_rr_request->request_size;
while (!times_up && (request_bytes_remaining > 0)) {
    request_bytes_recvd = recv(s_data, temp_message_ptr, request_bytes_remaining, 0);
    if (request_bytes_recvd == SOCKET_ERROR) {
        // 处理错误
    } else if (request_bytes_recvd > 0) {
        request_bytes_remaining -= request_bytes_recvd;
        temp_message_ptr += request_bytes_recvd;
    } else {
        goto bail;
    }
}

2.4 发送响应数据

接收到完整的请求后,服务器根据请求中的响应大小,通过 send() 函数将数据发送回客户端。此过程会继续直到传输计数用尽或测试时间结束。

bytes_sent = send(s_data, send_message_ptr, tcp_conn_rr_request->response_size, 0);
if (bytes_sent == SOCKET_ERROR) {
    netperf_response.content.serv_errno = 99;
    send_response();
    exit(1);
}

2.5 关闭连接

每次完成一次请求-响应后,服务器会关闭数据连接 s_data,并准备接收下一个连接。会通过调用 shutdown() 来优雅地关闭连接,确保数据发送完毕。

shutdown(s_data, SHUT_WR);
recv(s_data, recv_message_ptr, 1, 0);
close(s_data);

2.6 计算性能并返回结果

使用 cpu_start() 和 cpu_stop() 记录 CPU 使用情况和测试的运行时间。当测试完成后,服务器会计算传输的总字节数、事务的总数以及消耗的时间,并将这些结果通过 send_response() 返回给客户端。

cpu_start(tcp_conn_rr_request->measure_cpu);

/* ... */

cpu_stop(tcp_conn_rr_request->measure_cpu, &elapsed_time);
tcp_conn_rr_results->bytes_received	= (trans_received *
					   (tcp_conn_rr_request->request_size +
					    tcp_conn_rr_request->response_size));
tcp_conn_rr_results->trans_received = trans_received;
tcp_conn_rr_results->elapsed_time = elapsed_time;
if (tcp_conn_rr_request->measure_cpu) {
    tcp_conn_rr_results->cpu_util = calc_cpu_util(elapsed_time);
}
send_response();

3.测试方法

服务端

netserver

客户端

netperf -t TCP_CRR -H $DST_IP -L $SRC_IP -v 8 -D 10 -l $DURATION -- -r 32,1024 > /tmp/netperf_crr.log 2>&1 &
0条评论
作者已关闭评论
t****n
3文章数
0粉丝数
t****n
3 文章 | 0 粉丝
t****n
3文章数
0粉丝数
t****n
3 文章 | 0 粉丝
原创

netperf TCP_CRR模式代码解读及使用方法

2024-09-18 09:21:35
96
0

1.简介

netperf 是一个用于网络性能测试的工具,专门设计来衡量各种类型的网络吞吐量和延迟。它能够在客户端和服务器端进行通信,通过运行不同的测试来评估网络的性能。netperf 常被用于测量 TCP、UDP 等协议的性能,在紫金DPU中用于测试网络性能。TCP_CRR(连接请求响应)测试,是其中的一种测试模式,用于测量在创建和关闭连接时的性能,通常用于模拟短时连接的应用场景。

2.代码解读

2.1 初始化阶段

为消息缓冲区分配内存,分配的大小基于发起端发送的请求(tcp_conn_rr_request)。根据请求中的对齐方式和偏移量设置接收(recv_message_ptr)和发送(send_message_ptr)缓冲区。

netperf_response.content.response_type = TCP_CRR_RESPONSE;
message = (char *)malloc(DATABUFFERLEN);
/* ... */
recv_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->recv_alignment, tcp_conn_rr_request->recv_offset);
send_message_ptr = ALIGN_BUFFER(message, tcp_conn_rr_request->send_alignment, tcp_conn_rr_request->send_offset);


2.2 监听端口等待连接

使用 accept() 接受来自客户端的连接请求,将其分配给 s_data 套接字。如果连接成功,会进入数据传输阶段;如果失败,则返回相应的错误信息并关闭套接字。

s_listen = create_data_socket(local_res);
if (s_listen == INVALID_SOCKET) {
    netperf_response.content.serv_errno = errno;
    send_response();
    exit(1);
}
if (listen(s_listen, 128) == SOCKET_ERROR) {
    netperf_response.content.serv_errno = errno;
    close(s_listen);
    send_response();
    exit(1);
}

s_data = accept(s_listen, (struct sockaddr *)&peeraddr_in, &addrlen);
if (s_data == INVALID_SOCKET) {
    fprintf(where,"recv_tcp_conn_rr: accept: errno = %d\n",errno);
    close(s_listen);
    exit(1);
}

2.3 接收请求数据

从客户端接收请求消息,数据存放在 recv_message_ptr 指向的缓冲区中。函数通过 recv() 循环接收数据,直到接收到完整的请求或发生错误。如果接收到的字节数为 0,表示客户端关闭了连接,函数会处理连接关闭并跳出循环。

request_bytes_remaining = tcp_conn_rr_request->request_size;
while (!times_up && (request_bytes_remaining > 0)) {
    request_bytes_recvd = recv(s_data, temp_message_ptr, request_bytes_remaining, 0);
    if (request_bytes_recvd == SOCKET_ERROR) {
        // 处理错误
    } else if (request_bytes_recvd > 0) {
        request_bytes_remaining -= request_bytes_recvd;
        temp_message_ptr += request_bytes_recvd;
    } else {
        goto bail;
    }
}

2.4 发送响应数据

接收到完整的请求后,服务器根据请求中的响应大小,通过 send() 函数将数据发送回客户端。此过程会继续直到传输计数用尽或测试时间结束。

bytes_sent = send(s_data, send_message_ptr, tcp_conn_rr_request->response_size, 0);
if (bytes_sent == SOCKET_ERROR) {
    netperf_response.content.serv_errno = 99;
    send_response();
    exit(1);
}

2.5 关闭连接

每次完成一次请求-响应后,服务器会关闭数据连接 s_data,并准备接收下一个连接。会通过调用 shutdown() 来优雅地关闭连接,确保数据发送完毕。

shutdown(s_data, SHUT_WR);
recv(s_data, recv_message_ptr, 1, 0);
close(s_data);

2.6 计算性能并返回结果

使用 cpu_start() 和 cpu_stop() 记录 CPU 使用情况和测试的运行时间。当测试完成后,服务器会计算传输的总字节数、事务的总数以及消耗的时间,并将这些结果通过 send_response() 返回给客户端。

cpu_start(tcp_conn_rr_request->measure_cpu);

/* ... */

cpu_stop(tcp_conn_rr_request->measure_cpu, &elapsed_time);
tcp_conn_rr_results->bytes_received	= (trans_received *
					   (tcp_conn_rr_request->request_size +
					    tcp_conn_rr_request->response_size));
tcp_conn_rr_results->trans_received = trans_received;
tcp_conn_rr_results->elapsed_time = elapsed_time;
if (tcp_conn_rr_request->measure_cpu) {
    tcp_conn_rr_results->cpu_util = calc_cpu_util(elapsed_time);
}
send_response();

3.测试方法

服务端

netserver

客户端

netperf -t TCP_CRR -H $DST_IP -L $SRC_IP -v 8 -D 10 -l $DURATION -- -r 32,1024 > /tmp/netperf_crr.log 2>&1 &
文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0