资讯详情

做io测试

📅 2026/10/3 17:04:33 | 华诺云谱 👁 阅读
做io测试
使用 send / recv 做 IO 性能测试TCPsend/recv 是 Linux socket 原生接口适合做用户态TCP IO吞吐、延迟测试区别于epoll/io_uring这里给最简单的阻塞版本再给性能测试思路。 原理服务端 recv客户端 send传输固定大小数据统计耗时、带宽。一、完整C代码阻塞TCPsend/recv 测试server.c接收端recv#include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/socket.h #include netinet/in.h #include time.h #define PORT 8888 #define BUF_SIZE (120) // 1MB buffer int main() { int server_fd, new_socket; struct sockaddr_in addr; socklen_t addrlen sizeof(addr); char *buf malloc(BUF_SIZE); server_fd socket(AF_INET, SOCK_STREAM, 0); addr.sin_family AF_INET; addr.sin_addr.s_addr INADDR_ANY; addr.sin_port htons(PORT); bind(server_fd, (struct sockaddr*)addr, sizeof(addr)); listen(server_fd, 1); printf(server listen on %d\n, PORT); new_socket accept(server_fd, (struct sockaddr*)addr, addrlen); printf(client connected\n); long long total_recv 0; clock_t start clock(); while (1) { int n recv(new_socket, buf, BUF_SIZE, 0); if (n 0) break; total_recv n; } clock_t end clock(); double sec (double)(end - start)/CLOCKS_PER_SEC; printf(recv total: %lld bytes, time: %.2fs, bw: %.2f MB/s\n, total_recv, sec, total_recv / sec / (120)); close(new_socket); close(server_fd); free(buf); return 0; }client.c发送端send#include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h #include time.h #define PORT 8888 #define BUF_SIZE (120) #define SEND_TOTAL (10LL 30) // 10GB 测试流量 int main() { int sock socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in serv_addr; char *buf malloc(BUF_SIZE); memset(buf, A, BUF_SIZE); serv_addr.sin_family AF_INET; serv_addr.sin_port htons(PORT); inet_pton(AF_INET, 127.0.0.1, serv_addr.sin_addr); connect(sock, (struct sockaddr*)serv_addr, sizeof(serv_addr)); printf(connected to server\n); long long remain SEND_TOTAL; clock_t start clock(); while (remain 0) { int send_len (remain BUF_SIZE) ? BUF_SIZE : remain; int n send(sock, buf, send_len, 0); if (n 0) { perror(send); break; } remain - n; } clock_t end clock(); double sec (double)(end - start)/CLOCKS_PER_SEC; printf(send total: %lld bytes, time: %.2fs, bw: %.2f MB/s\n, SEND_TOTAL, sec, SEND_TOTAL / sec / (120)); close(sock); free(buf); return 0; }二、编译 运行gcc server.c -o server -O2 gcc client.c -o client -O2窗口1服务端./server窗口2客户端./client默认本地回环测试 10GB 流量测 TCP 吞吐。 改127.0.0.1换成远端IP测跨机器网络IO。三、send/recv 关键坑做IO测试必须注意send 不代表数据已经送到对端send 只是拷贝到内核 socket send buffer成功返回仅代表拷贝完成真正收完是对端recv。所以吞吐统计一定要以 server recv 累计字节为准client send 的计数会偏乐观。send/recv 返回值永远要检查TCP是字节流不保证一次send多少就一次recv多少。send()返回可能小于传入长度部分发送上面代码已经处理了剩余数据。buffer 大小影响测试结果 调整BUF_SIZE4k/64k/1M/4M用来测试不同应用层缓冲区对IO的影响。阻塞 vs 非阻塞 上面是阻塞socket。 非阻塞fcntl(sock, F_SETFL, O_NONBLOCK)此时 send/recv 可能返回-1errnoEAGAIN需要循环重试。适合高并发IO测试。socket buffer 调优提升上限# 临时修改内核tcp缓冲区 sysctl -w net.core.rmem_max16777216 sysctl -w net.core.wmem_max16777216代码里也可以用setsockopt设置SO_RCVBUF/SO_SNDBUF。参考链接 0voice · GitHub
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑