Winsock 连接很慢
Posted
技术标签:
【中文标题】Winsock 连接很慢【英文标题】:Winsock connect is slow 【发布时间】: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。
【参考方案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
文件中,以后再也不用担心这个问题了。以上是关于Winsock 连接很慢的主要内容,如果未能解决你的问题,请参考以下文章
Python Winsock - 如何通过已经处于活动状态的 Winsock 连接发送数据