client.cpp在windows下修改addr无法正常运行
平台:windows10 编译器:vs2019 代码:\lib_fiber\samples-c++1x\client\client.cpp
错误现象: client.cpp中的 acl::string addr = "127.0.0.1:9000", event_type("kernel"); 如果将addr换成 "www.baidu.com:80" 则这个demo无法正常获取结果。
acl::socket_stream conn; //
if (!conn.open(addr, timeout, timeout)) {
printf("connect %s error %s\r\n", addr, acl::last_serror());
return 0;
}
经调试,程序调用dnslookup查找www.baidu.com对应的ip,由于已经hook,调用的是acl自己实现的函数,但是不知是什么原因,未能正常返回。
大神能否帮忙看一下?
在linux也试了一下,写成"www.baidu.com:80"是可以连接成功的,但如果端口号不正确,open() 并不会超时。 能不能看一下?
该例子不是一个 http client,是一个简单的 echo 客户端测试程序,你可以参考一下 samples/http_request, samples-gui/HttpGet 两个例子来写一个 http client.
我并不是要实现http client. 只是tcp client , open() 要么成功,要么因超时而返回失败, 总要有个结果。 但是client.cpp在open() 这里并没有返回, 这属于bug,要么是这个例子写的不太对,要么就是acl本身存在不足。
目前看在windows下,使用 iocp 做为事件引擎时对于 UDP 的支持可能存在问题,所以导致域名解析不出来,不过你可以试一下 select或poll做为windows平台下的事件引擎,测试方法为:./client -e select -s www.baidu.com:80 ,这样协程引擎就会使用select了,该示例的默认引擎kernel在windows下表示使用 iocp.
改成select 或 poll 后在windows下确实可以正确连接上 "www.baidu.com:80". 但是对于 "www.baidu.com:9000" ,给一个错误的端口号,理论上应该超时连不上,但是 open(addr,3,3)给的是3秒超时 ,但实际的超时时间非常长大概要30秒。 这个在linux下也是这样的。
改成select 或 poll 后在windows下确实可以正确连接上 "www.baidu.com:80". 但是对于 "www.baidu.com:9000" ,给一个错误的端口号,理论上应该超时连不上,但是 open(addr,3,3)给的是3秒超时 ,但实际的超时时间非常长大概要30秒。 这个在linux下也是这样的。
协程模式下确实存在连接超时不准的问题,目前已经修复了Unix/Linux下的连接超时问题;在 acl_fiber_connect() 中,原来的做法是以非阻塞方式连接然后置入可写队列中等待连接完成,但对于上层调用者已经设置了非阻塞模式且希望自己控制连接超时的场景是有问题的,所以修改了 acl_fiber_connect()中的逻辑,当判断上层调用者已经设置了非阻塞模式时则直接返回,而不会放入“等待可写“队列中,从而把连接超时控制权交给上层调用者;但在Windows平台下微软没有提供可以判断一个套接字是否为非阻塞模式的方式,所以Windows下的连接超时仍然是不可控的。
针对windows平台,现在增加了一个辅助函数:acl::fiber::set_non_blocking(bool),当连接时带超时时可以调用此静态方法,从而使连接超时机制可控。参见:lib_fiber\samples-c++1x\client\client.cpp
目前看在windows下,使用 iocp 做为事件引擎时对于 UDP 的支持可能存在问题,所以导致域名解析不出来,不过你可以试一下 select或poll做为windows平台下的事件引擎,测试方法为:./client -e select -s www.baidu.com:80 ,这样协程引擎就会使用select了,该示例的默认引擎kernel在windows下表示使用 iocp.
目前存在于 iocp 模式下的几处问题也已经修复。
非常感谢!