【问题标题】:Winsock connect is slowWinsock 连接很慢
【发布时间】:2021-10-27 15:06:44
【问题描述】:

我有一个程序使用 Boost.Asio 连接到本地主机上的服务器。这是代码的相关部分:

TcpClient::TcpClient(uint16_t port_number) : socket_(service_)
{
    boost::asio::ip::tcp::resolver resolver(service_);
    boost::asio::ip::tcp::resolver::query resolver_query("localhost", std::to_string(port_number));
    auto endpoint_iterator = resolver.resolve(resolver_query);
    boost::asio::connect(socket_, endpoint_iterator);
}

代码功能很好。在 Ubuntu 上,connect 函数几乎立即返回。但是,在 Windows 上,完成需要超过 2 秒。

单步执行 boost 代码,我发现这 2 秒都花在了 Winsock connect 函数调用上。

我是否遗漏了一些可以加快调用速度的东西(无论是在代码中还是在环境中)?

谢谢!

【问题讨论】:

  • 我通常的嫌疑人是Nagle's algorithm。嗯,在这种情况下可能不是嫌疑人。
  • @Eljay AFAIK Nagle 不适用于connect(),仅适用于send()
  • 可能与 IPv6 有关。检查resolver.resolve 返回的地址。还有,端口和服务器是什么?
  • 延迟 Acks (TCP_QUICKACK) 可能有问题?
  • 我的猜测是localhost 可能返回一个 ipv4 和 ipv6 地址,首先尝试 ipv6 地址,然后在错误/超时后尝试 ipv4。

标签: c++ boost-asio winsock winsock2


【解决方案1】:

如果您启用了 IPv6,则resolver_query("localhost", std::to_string(port_number)); 将返回 IPv4 和 IPv6 地址(根据首先列出的 IPv6 的经验)。如果您的服务器没有监听 IPv6,那么boost::asio::connect 将首先尝试 IPv6,等待它失败,然后再尝试 IPv4。

要么让你的服务器监听 IPv6,使用“127.0.0.1”而不是 localhost,要么限制解析器只返回 IPv4:

resolver_query(boost::asio::ip::tcp::v4(), "localhost", std::to_string(port_number));

【讨论】:

  • 专业提示:将127.0.0.1 localhost 添加到hosts 文件中,以后再也不用担心这个问题了。
猜你喜欢
  • 2012-07-18
  • 2015-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-10
相关资源
最近更新 更多