You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中send()低频率调用时性能下降的优化方案咨询

问题描述

基于微软MSDN的C++ TCP服务器与客户端示例开展乒乓测试:服务器向客户端发送10字节TCP小数据包,客户端等待指定时长后回复10字节数据包,服务器立即回传,循环执行该流程。
测试环境为本地Windows Server 2019系统,搭载Intel Xeon 2288G处理器(已关闭C状态,完成高性能硬件优化)。测试观察到:客户端等待时长从0增加至数秒时,服务器端send()调用耗时从5微秒升至13微秒。

需求:如何让服务器端的send()调用在客户端任意等待时长下都保持最低耗时?


相关代码

服务器端代码

do {
    iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);

    QueryPerformanceCounter(&counter);   // 计时
    t0 = counter.QuadPart / (double)freq.QuadPart * 1000000;

    iSendResult = send(ClientSocket, recvbuf, iResult, 0);

    QueryPerformanceCounter(&counter);
    T[i] = counter.QuadPart / (double)freq.QuadPart * 1000000 - t0;
    i++;
} while (i < N);

客户端代码

do{
    iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);

    i++;

    // 延迟实现:通过调整Cycles值(0到3*10^9)改变等待时长
    int j = 0;
    double a = 1.000000001;
    do
    {
        a0 = a0 * a;
        j++;
    } while(j < Cycles);

} while (i < N);

测试趋势参考

send()耗时随客户端等待时长变化的趋势图:send()耗时 vs 客户端等待时长


解决方案建议
  • 禁用Nagle算法(TCP_NODELAY)
    默认TCP的Nagle算法会延迟小数据包发送以合并报文,当连接空闲后,首次send()可能触发该延迟。调用以下代码禁用Nagle算法,强制小数据包立即发送:

    int optval = 1;
    setsockopt(ClientSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&optval, sizeof(optval));
    
  • 启用TCP保活机制
    客户端长时间等待会让连接进入空闲状态,内核可能会调整连接资源状态,导致send()时额外开销。通过设置TCP保活,维持连接活跃:

    tcp_keepalive keepalive = {0};
    keepalive.onoff = 1;
    keepalive.keepalivetime = 1000;  // 连接空闲1秒后开始发送保活包
    keepalive.keepaliveinterval = 1000;  // 保活包发送间隔1秒
    DWORD bytesReturned;
    WSAIoctl(ClientSocket, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), NULL, 0, &bytesReturned, NULL, NULL);
    
  • 调整TCP发送缓冲区大小
    过小的发送缓冲区可能导致send()等待内核处理,可通过以下代码增大缓冲区(建议设置为64KB或更大,根据实际场景调整):

    int bufsize = 65536;  // 64KB
    setsockopt(ClientSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&bufsize, sizeof(bufsize));
    
  • 改用异步I/O模型
    同步send()在连接空闲后可能触发额外的内核态/用户态切换开销。改用重叠I/O或IOCP(完成端口)等异步模型,让send()以非阻塞方式完成,避免状态切换耗时。

  • 优化系统网络参数
    在Windows Server 2019中调整以下注册表项(修改后需重启系统):

    • HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\KeepAliveTime:设为1000(毫秒),加快保活探测启动
    • HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay:适当缩短TIME_WAIT状态时长(需注意避免端口耗尽风险)
    • HKLM\SYSTEM\CurrentControlSet\Services\AFD\Parameters\FastSendDatagramThreshold:设为小于10字节,让系统优先快速处理小数据包

内容的提问来源于stack exchange,提问作者Vitaly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 10:05:21