c++ - Boost::ASIO:优化以最小的流量,长连接,小消息,立即传递

标签 c++ sockets boost tcp boost-asio

我正在Boost::ASIO中编写一个协议(protocol),该协议(protocol)具有以下要求:

  • 连接是持久的,应该使用最少的开销来“保持 Activity ”。
  • 消息很小,需要立即传递。

  • 我应该使用其他TCP套接字标志或Boost::ASIO设置吗?
    socket_.set_option(boost::asio::ip::tcp::no_delay(true));   // enable PSH
    socket_.set_option(boost::asio::socket_base::keep_alive(true)); // enable SO_KEEPALIVE
    socket_.set_option(boost::asio::detail::socket_option::integer<SOL_TCP, TCP_KEEPIDLE>(120)); // secs before keepalive probes
    socket_.set_option(boost::asio::detail::socket_option::integer<SOL_TCP, TCP_KEEPINTVL>(10)); // interval between keepalive
    socket_.set_option(boost::asio::detail::socket_option::integer<SOL_TCP, TCP_KEEPCNT(5)); // failed keepalive before declaring dead
    

    最佳答案

    TL; DR -该协议(protocol)将处理所谓的“细流” ,如果我的回答还不够的话,它们将被很好地记录下来。最大的优势应该来自no_delay(true)async读/写(用于正常操作)以及dupACK和线性超时(用于故障恢复)。有关更多详细信息(包括静态/服务器TCP选项)和其他说明,请参见下文。

    通常,我会考虑以下因素来选择这些选项:

  • 我的用例是什么?在您的情况下,持续时间长(多长时间?),将通过该连接发送不带缓冲的小消息。需要一个很小的保持 Activity 空间。这在经典的“稀薄流” 例子中看来。
  • 最佳使用传输层协议(protocol)是什么? https://en.wikipedia.org/wiki/Transport_layer#Protocols-每个都有自己的用例。在这一点上,我认为您确实需要TCP来实现可靠性和面向连接,否则,基于udp的协议(protocol)可能会更好(例如UDP-lite,它可以在应用程序层实现部分校验和和基础的可靠性决策(或您作为开发人员将要实现的层)。
  • 选择了要构建的基础协议(protocol)-研究该协议(protocol)的调优选项 4。对于TCP,这些是:
  • Nagle的算法-数据缓冲,您已正确将其关闭。
  • 延迟的ACK-组合ACK,对于类似telnet的应用程序很有用,在这种应用程序中不必为每个传输的字符发送ACK。如果需要,则使用TCP_QUICKACK-立即发送ACK。万一您很少发送数据,它可能会很有用。
  • Keepalive探针-我看到您使用的值很短。不确定如何确定这些特定值,但可以考虑扩展它们,以保持“最小开销以保持”。Linux的默认值:7200、75、9。
  • PSH标志-有助于理解,在很大程度上未使用/忽略/不相关。
  • URG标志-将紧急数据通过单独的 channel 转发到应用程序,如果您打算接收带外数据(某些控制数据,例如取消),则很有用。在您的情况下可能没有用,因为在“精简流”的情况下,OOB数据的空间很小。
  • TCP Windows(RWND/CWND)-不适用于很少发送的小型消息。窗口应足以容纳数据。
  • 空闲后的窗口大小(SSR)-Not surprisingly, SSR can have a significant impact on performance of long-lived TCP connections that may idle for bursts of time — e.g., due to user inactivity. As a result, it is generally recommended to disable SSR on the server to help improve performance of long-lived HTTP connections.,取自here。选项:sysctl -w tcp_slow_start_after_idle=0
  • TCP快速重传-tcp_thin_dupack应该为ON。它减少了发送者在重新传输丢失的段之前等待的时间。请仔细阅读并试验预防措施(可以在每个插槽中指定,请立即参阅下面的要点)。
  • tcp_thin_linear_timeouts-这样可以在丢失数据包时更快地进行恢复,可以针对每个套接字指定它:https://nnc3.com/mags/LJ_1994-2014/LJ/219/11180.html
  • TFO_FASTOPEN(TFO):-缩短了初始连接的建立。对于生命周期长的连接不是很适用,但是可以考虑。
  • 压缩-根据我所看到的信息,不应在您的情况下使用它(不是TCP选项,可以在TCP之上添加),因为它会增加延迟,我相信您可以避免。如果此选项不正确,请添加此选项。
  • 应用程序应处理或协议(protocol)文档可以指定的一些基础结构详细信息。
  • 对于持久连接,如果它们被服务器端终止,则TIME_WAIT状态将很重要。启动连接终止的一方会受到TIME_WAIT的罚款,因此,可能要考虑根据您的应用程序/协议(protocol)的使用情况。这取决于您如何处理连接终止。
  • 临时端口-也许增加临时端口数量以容纳那些持久的连接将很有用,但不确定。这是您的协议(protocol)可能的文档要点。

  • 如果您的协议(protocol)针对telnet之类的通信进行了调整,则可以看到此telnet的实现。基本上,它充满了异步读写:
    https://lists.boost.org/boost-users/att-40895/telnet.cpp

    一些不错的读物:

    https://www.extrahop.com/company/blog/2016/tcp-nodelay-nagle-quickack-best-practices/
    https://sourceforge.net/p/asio/mailman/asio-users/?page=257-获得其他帮助。

    关于c++ - Boost::ASIO:优化以最小的流量,长连接,小消息,立即传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48047579/

    相关文章:

    delphi - 在delphi中建立tcp ip连接时无法读取消息

    android - 使用背景图像刷新 android 中的 ImageView

    c++ - 如何重现 Boost 流程文档提示的死锁?

    c++ - boost 源代码

    c++ - cvCreateCameraCapture 无法访问 OpenCV 3.0 相机

    c++ - 在 C++ 中的 3D map 中插入值

    c++ - Visual C++ 2008 作为 Access 的前端

    c++ - 通过代码在 Windows 操作系统上启用和禁用 DST

    objective-c - 结束/停止 NSFileHandle 套接字服务器

    c++ - 使用 boost void 分配器是不好的做法吗?