开2个客户端用telnet方式连上echo_server,长时间后关掉telnet后,echo_server竟然不会断开客户端?
而且在echo_server的机器上用netstat -ano -p tcp查看,服务端于客户端的连接还处于ESTABLISHED状态,这就是所谓的终极网络库?搞笑的吧!
用asio到商业项目的大牛来解释下?
77 个解决方案
#1
本来想学习学习asio的,就这么个样子,我看是不是网上吹的人太多了?
尼玛我客户端机器telnet都关掉了,服务端上竟然还是ESTABLISHED状态,无敌的asio。。。
尼玛我客户端机器telnet都关掉了,服务端上竟然还是ESTABLISHED状态,无敌的asio。。。
#2
呵呵,别管什么库,掌握“机制”是最重要的。
如果因为存在某个库,而使你丧失了学习此技术之内部机制的可能,那么,我劝你还是不要先使用这个库为好。
就像这个asio,如果因为它的存在,而令你不再学习异步重叠I/O,那么,还是先不要使用这个库为好。
如果因为存在某个库,而使你丧失了学习此技术之内部机制的可能,那么,我劝你还是不要先使用这个库为好。
就像这个asio,如果因为它的存在,而令你不再学习异步重叠I/O,那么,还是先不要使用这个库为好。
#3
难道asio只有在handle_read/handle_write的时候出现error_code才知道客户端已经断开吗?
就像我telnet测试一样,客户端不write,难道asio就没办法返回客户端断开了?
连底层onclose()都不提供,你说学习啥呢?为了学哪些晦涩难懂的所谓func/bind吗?
自己运行下async_tcp_echo_server.cpp测试下再来喷可行?
就像我telnet测试一样,客户端不write,难道asio就没办法返回客户端断开了?
连底层onclose()都不提供,你说学习啥呢?为了学哪些晦涩难懂的所谓func/bind吗?
自己运行下async_tcp_echo_server.cpp测试下再来喷可行?
#4
asio当然在机制仅会支持TCP或UDP支持的feature,而TCP保活超时是半个小时以上,半个小时(或45分钟)后会产生一个“网络错误”,那个时候就asio就会给客户事件了。
如果要建立商业级的服务器软件,仅仅依赖“传输层”的feature是远远不够的,你要自己做心跳来保活。
#5
长连接服务器需要做心跳,在“问答式服务器”里做定时器就可以了。
当你收到一个包,就对这个socket开始计时,如果再收到包就重新计时,如果超时,就自己产生一个事件以关掉socket。
当你收到一个包,就对这个socket开始计时,如果再收到包就重新计时,如果超时,就自己产生一个事件以关掉socket。
#6
ok,如果说asio建立在tcp协议栈上,那么保活超时之后,也要给调用者返回所谓的“网络错误”,事实上是并无任何返回(handle_read未触发),还是麻烦LS的兄台自己跑一下example那个例子,再来解答,哦可?
不要跟我讲应用层面要保证的机制,写server都会这样处理,现在问题关键是底层的所谓"终极神器"的asio,在socket keeplive超时后,并无任何异常触发并返回,你可明白?
不要跟我讲应用层面要保证的机制,写server都会这样处理,现在问题关键是底层的所谓"终极神器"的asio,在socket keeplive超时后,并无任何异常触发并返回,你可明白?
#7
你等了多长时间?
#8
昨天晚上在公网机器上跑的server,然后在另外2个公网机器上开的telnet客户端,今天早上发现连接都没断很正常,然后把2个telnet关掉后,server没有任何hand_read()调用,无error_code,在netstat -ano -p tcp里面,还显示与2个telnet的连接处于ESTABLISHED已连接状态,其他的话我也不想多说了,谁不相信谁自己试下就知道了,无奈的asio,连最基本的保活机制都没检测。
#9
server用的官方example代码,无任何改动。
我相信select/iocp都不可能出现这么低级的问题(同样的方法测试过)
我相信select/iocp都不可能出现这么低级的问题(同样的方法测试过)
#10
“在netstat -ano -p tcp里面,还显示与2个telnet的连接处于ESTABLISHED已连接状态”,
呵呵,你想想看。 tcp协议栈认为这两个连接依然是ESTABLISHED,这跟asio有什么关系呢?
#11
select / iocp不用你本机的tcp协议栈吗?
ESTABLISHED状态是协议栈决定的,还是asio抑或iocp决定的?
#12
不知道你看清楚我的回答没?
"然后把2个telnet关掉后,server没有任何hand_read()调用,无error_code,在netstat -ano -p tcp里面,还显示与2个telnet的连接处于ESTABLISHED已连接状态"
随便做个c/s,c关掉后,我不信s与这个c的staus还是ESTABLISHED,说明什么问题?
说明c断开后,s并没有将和c连接的socket断开,asio也一样,也就是说asio的GCQS无返回 或 没出现错误。你想想这样正常吗?
还要怎样说?真是无语,你完全连问题都没看懂!
"然后把2个telnet关掉后,server没有任何hand_read()调用,无error_code,在netstat -ano -p tcp里面,还显示与2个telnet的连接处于ESTABLISHED已连接状态"
随便做个c/s,c关掉后,我不信s与这个c的staus还是ESTABLISHED,说明什么问题?
说明c断开后,s并没有将和c连接的socket断开,asio也一样,也就是说asio的GCQS无返回 或 没出现错误。你想想这样正常吗?
还要怎样说?真是无语,你完全连问题都没看懂!
#13
请翻开斯蒂文斯的卷1,182页,请仔细看看TCP状态变迁图。
当ESTABLISHED收到FIN,应转为CLOSE_WAIT状态,就是说,你的服务器的TCP协议栈并未受到远端(主动关闭端)发出的FIN。
这跟asio一点关系都没有,协议栈未收到FIN,套接口层当然不会得到事件。
#14
算了,不跟你解释了,你自己试下官方那个例子就知道了!
在telnet连上server后:
1、很短时间内关闭telnet,此时server会调用handle_read,因为有error_code,所以自动delete this,一切正常;
2、很长时间后关闭telnet(我是过了1晚上,大概10-12小时),同样关闭telnet,此时server不会调用handle_read,更无error_code,可笑的是:server所在的机器上,server与这个已经关闭的telnet连接状态还是ESTABLISHED。
ps:其他的话不多说了,如果你们以为这样是正常的,asio也正常的,可以无视了。
LS的你也不用回帖了,你适合去看书。
在telnet连上server后:
1、很短时间内关闭telnet,此时server会调用handle_read,因为有error_code,所以自动delete this,一切正常;
2、很长时间后关闭telnet(我是过了1晚上,大概10-12小时),同样关闭telnet,此时server不会调用handle_read,更无error_code,可笑的是:server所在的机器上,server与这个已经关闭的telnet连接状态还是ESTABLISHED。
ps:其他的话不多说了,如果你们以为这样是正常的,asio也正常的,可以无视了。
LS的你也不用回帖了,你适合去看书。
#15
看来你还是分不清运输层和套接口层甚至是asio所在的上层机制之间的区别,你应该看看书,补充这些知识,再来讨论综合性的问题吧。
#16
真厉害,你应该让写boost的人都滚蛋,然后你去实现asio。
麻烦你喷asio之前,先用wireshark看看你关闭telnet的时候fin到底发没发。
另外你对KEEP_ALIVE的触发条件理解有误,麻烦你还是再去看看书吧。
啥都不懂,就上来喷,服了你了。
#17
#18
就是 好大的口气啊
#19
让他多喷会
#20
我封装的boost asio.很好嘛. 单线程iocp. 也能支持1000连接并发1KB/S速度.
关键还是看写代码的人.
关键还是看写代码的人.
#21
1.46里面带的asio有bug,但不是你说的这种。
我有用作商用,大量项目均基于它,没出现你所说的这种"不可思议"的bug。
另外如果服务端网络状态还是 ESTABLISHED, 那么这本身和asio无关
说明你虽然关闭了client端,但是client并没有正常发送fin,这种情况就是我们常说的异常断开。
那么通常你有两种方式处理:
1. Keep_alive 正常windows下2小时左右(另外windows下有WSAIoctl这个API来实现类似TCP层的保活,而linux下setsockopt有超时选项也可以用来实现tcp层保活)
2. 通过自己的上层协议发送心跳包等来保活
我有用作商用,大量项目均基于它,没出现你所说的这种"不可思议"的bug。
另外如果服务端网络状态还是 ESTABLISHED, 那么这本身和asio无关
说明你虽然关闭了client端,但是client并没有正常发送fin,这种情况就是我们常说的异常断开。
那么通常你有两种方式处理:
1. Keep_alive 正常windows下2小时左右(另外windows下有WSAIoctl这个API来实现类似TCP层的保活,而linux下setsockopt有超时选项也可以用来实现tcp层保活)
2. 通过自己的上层协议发送心跳包等来保活
#22
我最近用boost1.47的asio做东西,感觉确实不错,楼主你不要乱喷了,自己2就检点些,不要说什么不行,你自己行不行? 好东西是要花时间和精力去弄懂的,就算你花了时间精力你也可能看不懂。
#23
自己设定时啊.不过我到记得asio里面有个整数计数器.每收次数据加一次,溢出了就出错.这也就意味着别想做长期保存连接的服务器啦.不知道现在还有不
#24
先把基础的东西打好,boost asio我一直在用,用了asio你就不会再想去自己封装一个什么XXX网络库了
#25
asio不是用来搞笑的, 而是给理解网络编程的人用的...
#26
楼主提供的所有证据,不能证明telnet正常关闭了套节字。
楼主的意思是:
一:用telnet连上服务端,短时间内退出telnet,服务端正常;
二:用telnet连上服务端,长时间内退出telnet,服务端异常;
这两条不能证明异常是服务端设计有问题,还是telnet设计有问题。
对于上面第二点,你可以像4楼所说的,等长一点时间,比如1小时,看看asio会不会有网络断开的提示。
楼主没有理解4楼的“你等了多长时间”的意思,4楼的意思是,你断开telnet之后,等了多长时间,而不是你用telnet连接上服务端之后,等了多长时间。
如果在telnet退出之后,等了足够长的时间,比如1小时,asio检测到了网络断开,那说明你的telnet没有正常关闭套节字。
楼主的意思是:
一:用telnet连上服务端,短时间内退出telnet,服务端正常;
二:用telnet连上服务端,长时间内退出telnet,服务端异常;
这两条不能证明异常是服务端设计有问题,还是telnet设计有问题。
对于上面第二点,你可以像4楼所说的,等长一点时间,比如1小时,看看asio会不会有网络断开的提示。
楼主没有理解4楼的“你等了多长时间”的意思,4楼的意思是,你断开telnet之后,等了多长时间,而不是你用telnet连接上服务端之后,等了多长时间。
如果在telnet退出之后,等了足够长的时间,比如1小时,asio检测到了网络断开,那说明你的telnet没有正常关闭套节字。
#27
看来ASIO还是不错的。。大家都在用。。
#28
#29
又是一个喷子
#30
再好的利器在楼主手里也只不过是石器罢了。
一个示例有N多的情况没有考虑,这是正常的,何必纠着一个hello,world不放。
一个示例有N多的情况没有考虑,这是正常的,何必纠着一个hello,world不放。
#31
借题发挥以下,请大家特别是hurryboylqs, jwybobo2007, sinservice看下这个问题,有关asio的(内存泄露?)问题:
http://topic.csdn.net/u/20120804/01/fb5259bf-f15c-4062-a7fe-3ef52d0d6305.html?8348
http://topic.csdn.net/u/20120804/01/fb5259bf-f15c-4062-a7fe-3ef52d0d6305.html?8348
#32
自问自答吗?
#33
我也遇到这个问题。本来打算每次在向fastcgi服务器端前判断一下连接是否还存在,不存在的话先连接再写数据,结果用is_open判断不起作用,每次都是async_write之后报错,还需要重新写一个回调,把数据保存下来,等待异步连接之后再发,结构复杂多了
#34
#35
我貌似也遇到这个类似的问题。
boost 版本 1.47
demo chat_server chat_client
现象 客户端连接上服务器后收发数据都很正常 但是如果长时间(几分钟) 不发送数据,就会自动断开,我以为以为服务器有 类似 timeout 检测客户端无输入自动断开的功能呢,结果没找到,google 半天也没有相关的文档(自动断开的说明,BUG描述....)
然后,我自己改了下代码, 2个客户端
client 1 原有的
client 2 我自己改的 没 1秒发送一个数据包
两个客户端同时连接上服务器,截至到我发帖 7381 秒都过去了,两个客户端都没掉线
这说明 BUG 可能存在服务器端,根本原因可能是ASIO 不正确的使用IOCP导致的.
另外,我想问下,大家以前使用 TCP 协议都需要应用层做心跳机制么??? 我咋从来没做过呢,我刚和同事吵过架,他说TCP 应用层心跳机制是必须的.....
我以前用的IOCP 断开都有通知过来。从来不需要所谓的 “TCP 应用层心跳” 只有UDP 的时候,我才做过心跳
QQ 21700579 欢迎交流
boost 版本 1.47
demo chat_server chat_client
现象 客户端连接上服务器后收发数据都很正常 但是如果长时间(几分钟) 不发送数据,就会自动断开,我以为以为服务器有 类似 timeout 检测客户端无输入自动断开的功能呢,结果没找到,google 半天也没有相关的文档(自动断开的说明,BUG描述....)
然后,我自己改了下代码, 2个客户端
client 1 原有的
client 2 我自己改的 没 1秒发送一个数据包
两个客户端同时连接上服务器,截至到我发帖 7381 秒都过去了,两个客户端都没掉线
这说明 BUG 可能存在服务器端,根本原因可能是ASIO 不正确的使用IOCP导致的.
另外,我想问下,大家以前使用 TCP 协议都需要应用层做心跳机制么??? 我咋从来没做过呢,我刚和同事吵过架,他说TCP 应用层心跳机制是必须的.....
我以前用的IOCP 断开都有通知过来。从来不需要所谓的 “TCP 应用层心跳” 只有UDP 的时候,我才做过心跳
QQ 21700579 欢迎交流
#36
我用ASIO 是想写一个 websocket 服务器,我之前写了个 xmlsocket 服务器,跟FLASH 交互的很好,从来没有自动断开这种现象. 我做上面的测试程序的时候,服务器同时开着 xmlsocket 服务呢,聊天室聊天都很正常
#37
刚才又仔细测试了,为防止误导新手..补充说明下:
boost asio chat_server 本机(127.0.0.1)测试 客户端和服务器直连 没任何问题,没有断开的现象
那么还有个可能是 服务器所在机房的防火墙对长时间没有数据收发的连接 采取了 自动断开
网络太复杂了,看来心跳还是必须的
boost asio chat_server 本机(127.0.0.1)测试 客户端和服务器直连 没任何问题,没有断开的现象
那么还有个可能是 服务器所在机房的防火墙对长时间没有数据收发的连接 采取了 自动断开
网络太复杂了,看来心跳还是必须的
#38
lz故意找抽的。多看看书多补补基础再来弄asio神器
#39
你为什么觉得,is_open是判断连接用的呢?
套接字先要open,再连接,连不连接与有没有open有什么关系?
如果不懂网络编程基础知识,不管封装多么好的一个库,也会被错用。
#40
其实我知道“echo_server竟然不会断开客户端?”的原因
真的不是boost的错
#41
那你说说open具体做了什么?
tcp的连接只需要三次握手就可以了,对方断开连接时会发松fin包过来,这个时候自己方是可以判断出连接已经断开了。那为什么就不能封装一个函数直接判断到这个状态呢?非得在写数据或者读数据的时候报错。
还有不要动不动就说别人不懂这个那个的,越牛的人态度越谦虚,半灌水响叮当
#42
作为一个网络库, 我还是同意楼主说的话的. asio作为一个完善的网络基础库来说, 假如是UDP, 那么在检测断线的时间上应该是可以设置的, 假如是TCP, 假如对方非法关闭, TCP的connect应该会得自动检测到断开的, 虽然有点延迟, 但TCP的默认设置不改的话, 不会有30分钟这么长时间的, TCP的socket有问题, 应该会释放客户端相关资源才对的.
网络库就应该提供完善的接口让外部只处理业务内容即可, 还要外部心跳什么的, 就算网络件性能不错, 但设计可以说是烂到掉渣了.
网络库就应该提供完善的接口让外部只处理业务内容即可, 还要外部心跳什么的, 就算网络件性能不错, 但设计可以说是烂到掉渣了.
#43
我是新手,想要学习asio,为了更顺的学,我至少需要先看哪写书呀?求指导,谢谢
#44
#45
有nat的公网对于长时间没有数据来往的连接会忽略fin的发送,这样导致两台机之间通信实际断了但又没收到断线的消息,因此要在应用层加上心跳包来检测,协议层不是完全靠谱的
#46
作为一个库 不做断开检测这很正常 他不知道你需要多频繁的检测
#47
#48
我觉得boost asio这个封装也确实不是很人性化。珍惜生命,远离boost。
#49
#50
继续讨论呀,讨论太有火花
#1
本来想学习学习asio的,就这么个样子,我看是不是网上吹的人太多了?
尼玛我客户端机器telnet都关掉了,服务端上竟然还是ESTABLISHED状态,无敌的asio。。。
尼玛我客户端机器telnet都关掉了,服务端上竟然还是ESTABLISHED状态,无敌的asio。。。
#2
呵呵,别管什么库,掌握“机制”是最重要的。
如果因为存在某个库,而使你丧失了学习此技术之内部机制的可能,那么,我劝你还是不要先使用这个库为好。
就像这个asio,如果因为它的存在,而令你不再学习异步重叠I/O,那么,还是先不要使用这个库为好。
如果因为存在某个库,而使你丧失了学习此技术之内部机制的可能,那么,我劝你还是不要先使用这个库为好。
就像这个asio,如果因为它的存在,而令你不再学习异步重叠I/O,那么,还是先不要使用这个库为好。
#3
难道asio只有在handle_read/handle_write的时候出现error_code才知道客户端已经断开吗?
就像我telnet测试一样,客户端不write,难道asio就没办法返回客户端断开了?
连底层onclose()都不提供,你说学习啥呢?为了学哪些晦涩难懂的所谓func/bind吗?
自己运行下async_tcp_echo_server.cpp测试下再来喷可行?
就像我telnet测试一样,客户端不write,难道asio就没办法返回客户端断开了?
连底层onclose()都不提供,你说学习啥呢?为了学哪些晦涩难懂的所谓func/bind吗?
自己运行下async_tcp_echo_server.cpp测试下再来喷可行?
#4
asio当然在机制仅会支持TCP或UDP支持的feature,而TCP保活超时是半个小时以上,半个小时(或45分钟)后会产生一个“网络错误”,那个时候就asio就会给客户事件了。
如果要建立商业级的服务器软件,仅仅依赖“传输层”的feature是远远不够的,你要自己做心跳来保活。
#5
长连接服务器需要做心跳,在“问答式服务器”里做定时器就可以了。
当你收到一个包,就对这个socket开始计时,如果再收到包就重新计时,如果超时,就自己产生一个事件以关掉socket。
当你收到一个包,就对这个socket开始计时,如果再收到包就重新计时,如果超时,就自己产生一个事件以关掉socket。
#6
ok,如果说asio建立在tcp协议栈上,那么保活超时之后,也要给调用者返回所谓的“网络错误”,事实上是并无任何返回(handle_read未触发),还是麻烦LS的兄台自己跑一下example那个例子,再来解答,哦可?
不要跟我讲应用层面要保证的机制,写server都会这样处理,现在问题关键是底层的所谓"终极神器"的asio,在socket keeplive超时后,并无任何异常触发并返回,你可明白?
不要跟我讲应用层面要保证的机制,写server都会这样处理,现在问题关键是底层的所谓"终极神器"的asio,在socket keeplive超时后,并无任何异常触发并返回,你可明白?
#7
你等了多长时间?
#8
昨天晚上在公网机器上跑的server,然后在另外2个公网机器上开的telnet客户端,今天早上发现连接都没断很正常,然后把2个telnet关掉后,server没有任何hand_read()调用,无error_code,在netstat -ano -p tcp里面,还显示与2个telnet的连接处于ESTABLISHED已连接状态,其他的话我也不想多说了,谁不相信谁自己试下就知道了,无奈的asio,连最基本的保活机制都没检测。
#9
server用的官方example代码,无任何改动。
我相信select/iocp都不可能出现这么低级的问题(同样的方法测试过)
我相信select/iocp都不可能出现这么低级的问题(同样的方法测试过)
#10
“在netstat -ano -p tcp里面,还显示与2个telnet的连接处于ESTABLISHED已连接状态”,
呵呵,你想想看。 tcp协议栈认为这两个连接依然是ESTABLISHED,这跟asio有什么关系呢?
#11
select / iocp不用你本机的tcp协议栈吗?
ESTABLISHED状态是协议栈决定的,还是asio抑或iocp决定的?
#12
不知道你看清楚我的回答没?
"然后把2个telnet关掉后,server没有任何hand_read()调用,无error_code,在netstat -ano -p tcp里面,还显示与2个telnet的连接处于ESTABLISHED已连接状态"
随便做个c/s,c关掉后,我不信s与这个c的staus还是ESTABLISHED,说明什么问题?
说明c断开后,s并没有将和c连接的socket断开,asio也一样,也就是说asio的GCQS无返回 或 没出现错误。你想想这样正常吗?
还要怎样说?真是无语,你完全连问题都没看懂!
"然后把2个telnet关掉后,server没有任何hand_read()调用,无error_code,在netstat -ano -p tcp里面,还显示与2个telnet的连接处于ESTABLISHED已连接状态"
随便做个c/s,c关掉后,我不信s与这个c的staus还是ESTABLISHED,说明什么问题?
说明c断开后,s并没有将和c连接的socket断开,asio也一样,也就是说asio的GCQS无返回 或 没出现错误。你想想这样正常吗?
还要怎样说?真是无语,你完全连问题都没看懂!
#13
请翻开斯蒂文斯的卷1,182页,请仔细看看TCP状态变迁图。
当ESTABLISHED收到FIN,应转为CLOSE_WAIT状态,就是说,你的服务器的TCP协议栈并未受到远端(主动关闭端)发出的FIN。
这跟asio一点关系都没有,协议栈未收到FIN,套接口层当然不会得到事件。
#14
算了,不跟你解释了,你自己试下官方那个例子就知道了!
在telnet连上server后:
1、很短时间内关闭telnet,此时server会调用handle_read,因为有error_code,所以自动delete this,一切正常;
2、很长时间后关闭telnet(我是过了1晚上,大概10-12小时),同样关闭telnet,此时server不会调用handle_read,更无error_code,可笑的是:server所在的机器上,server与这个已经关闭的telnet连接状态还是ESTABLISHED。
ps:其他的话不多说了,如果你们以为这样是正常的,asio也正常的,可以无视了。
LS的你也不用回帖了,你适合去看书。
在telnet连上server后:
1、很短时间内关闭telnet,此时server会调用handle_read,因为有error_code,所以自动delete this,一切正常;
2、很长时间后关闭telnet(我是过了1晚上,大概10-12小时),同样关闭telnet,此时server不会调用handle_read,更无error_code,可笑的是:server所在的机器上,server与这个已经关闭的telnet连接状态还是ESTABLISHED。
ps:其他的话不多说了,如果你们以为这样是正常的,asio也正常的,可以无视了。
LS的你也不用回帖了,你适合去看书。
#15
看来你还是分不清运输层和套接口层甚至是asio所在的上层机制之间的区别,你应该看看书,补充这些知识,再来讨论综合性的问题吧。
#16
真厉害,你应该让写boost的人都滚蛋,然后你去实现asio。
麻烦你喷asio之前,先用wireshark看看你关闭telnet的时候fin到底发没发。
另外你对KEEP_ALIVE的触发条件理解有误,麻烦你还是再去看看书吧。
啥都不懂,就上来喷,服了你了。
#17
#18
就是 好大的口气啊
#19
让他多喷会
#20
我封装的boost asio.很好嘛. 单线程iocp. 也能支持1000连接并发1KB/S速度.
关键还是看写代码的人.
关键还是看写代码的人.
#21
1.46里面带的asio有bug,但不是你说的这种。
我有用作商用,大量项目均基于它,没出现你所说的这种"不可思议"的bug。
另外如果服务端网络状态还是 ESTABLISHED, 那么这本身和asio无关
说明你虽然关闭了client端,但是client并没有正常发送fin,这种情况就是我们常说的异常断开。
那么通常你有两种方式处理:
1. Keep_alive 正常windows下2小时左右(另外windows下有WSAIoctl这个API来实现类似TCP层的保活,而linux下setsockopt有超时选项也可以用来实现tcp层保活)
2. 通过自己的上层协议发送心跳包等来保活
我有用作商用,大量项目均基于它,没出现你所说的这种"不可思议"的bug。
另外如果服务端网络状态还是 ESTABLISHED, 那么这本身和asio无关
说明你虽然关闭了client端,但是client并没有正常发送fin,这种情况就是我们常说的异常断开。
那么通常你有两种方式处理:
1. Keep_alive 正常windows下2小时左右(另外windows下有WSAIoctl这个API来实现类似TCP层的保活,而linux下setsockopt有超时选项也可以用来实现tcp层保活)
2. 通过自己的上层协议发送心跳包等来保活
#22
我最近用boost1.47的asio做东西,感觉确实不错,楼主你不要乱喷了,自己2就检点些,不要说什么不行,你自己行不行? 好东西是要花时间和精力去弄懂的,就算你花了时间精力你也可能看不懂。
#23
自己设定时啊.不过我到记得asio里面有个整数计数器.每收次数据加一次,溢出了就出错.这也就意味着别想做长期保存连接的服务器啦.不知道现在还有不
#24
先把基础的东西打好,boost asio我一直在用,用了asio你就不会再想去自己封装一个什么XXX网络库了
#25
asio不是用来搞笑的, 而是给理解网络编程的人用的...
#26
楼主提供的所有证据,不能证明telnet正常关闭了套节字。
楼主的意思是:
一:用telnet连上服务端,短时间内退出telnet,服务端正常;
二:用telnet连上服务端,长时间内退出telnet,服务端异常;
这两条不能证明异常是服务端设计有问题,还是telnet设计有问题。
对于上面第二点,你可以像4楼所说的,等长一点时间,比如1小时,看看asio会不会有网络断开的提示。
楼主没有理解4楼的“你等了多长时间”的意思,4楼的意思是,你断开telnet之后,等了多长时间,而不是你用telnet连接上服务端之后,等了多长时间。
如果在telnet退出之后,等了足够长的时间,比如1小时,asio检测到了网络断开,那说明你的telnet没有正常关闭套节字。
楼主的意思是:
一:用telnet连上服务端,短时间内退出telnet,服务端正常;
二:用telnet连上服务端,长时间内退出telnet,服务端异常;
这两条不能证明异常是服务端设计有问题,还是telnet设计有问题。
对于上面第二点,你可以像4楼所说的,等长一点时间,比如1小时,看看asio会不会有网络断开的提示。
楼主没有理解4楼的“你等了多长时间”的意思,4楼的意思是,你断开telnet之后,等了多长时间,而不是你用telnet连接上服务端之后,等了多长时间。
如果在telnet退出之后,等了足够长的时间,比如1小时,asio检测到了网络断开,那说明你的telnet没有正常关闭套节字。
#27
看来ASIO还是不错的。。大家都在用。。
#28
#29
又是一个喷子
#30
再好的利器在楼主手里也只不过是石器罢了。
一个示例有N多的情况没有考虑,这是正常的,何必纠着一个hello,world不放。
一个示例有N多的情况没有考虑,这是正常的,何必纠着一个hello,world不放。
#31
借题发挥以下,请大家特别是hurryboylqs, jwybobo2007, sinservice看下这个问题,有关asio的(内存泄露?)问题:
http://topic.csdn.net/u/20120804/01/fb5259bf-f15c-4062-a7fe-3ef52d0d6305.html?8348
http://topic.csdn.net/u/20120804/01/fb5259bf-f15c-4062-a7fe-3ef52d0d6305.html?8348
#32
自问自答吗?
#33
我也遇到这个问题。本来打算每次在向fastcgi服务器端前判断一下连接是否还存在,不存在的话先连接再写数据,结果用is_open判断不起作用,每次都是async_write之后报错,还需要重新写一个回调,把数据保存下来,等待异步连接之后再发,结构复杂多了
#34
#35
我貌似也遇到这个类似的问题。
boost 版本 1.47
demo chat_server chat_client
现象 客户端连接上服务器后收发数据都很正常 但是如果长时间(几分钟) 不发送数据,就会自动断开,我以为以为服务器有 类似 timeout 检测客户端无输入自动断开的功能呢,结果没找到,google 半天也没有相关的文档(自动断开的说明,BUG描述....)
然后,我自己改了下代码, 2个客户端
client 1 原有的
client 2 我自己改的 没 1秒发送一个数据包
两个客户端同时连接上服务器,截至到我发帖 7381 秒都过去了,两个客户端都没掉线
这说明 BUG 可能存在服务器端,根本原因可能是ASIO 不正确的使用IOCP导致的.
另外,我想问下,大家以前使用 TCP 协议都需要应用层做心跳机制么??? 我咋从来没做过呢,我刚和同事吵过架,他说TCP 应用层心跳机制是必须的.....
我以前用的IOCP 断开都有通知过来。从来不需要所谓的 “TCP 应用层心跳” 只有UDP 的时候,我才做过心跳
QQ 21700579 欢迎交流
boost 版本 1.47
demo chat_server chat_client
现象 客户端连接上服务器后收发数据都很正常 但是如果长时间(几分钟) 不发送数据,就会自动断开,我以为以为服务器有 类似 timeout 检测客户端无输入自动断开的功能呢,结果没找到,google 半天也没有相关的文档(自动断开的说明,BUG描述....)
然后,我自己改了下代码, 2个客户端
client 1 原有的
client 2 我自己改的 没 1秒发送一个数据包
两个客户端同时连接上服务器,截至到我发帖 7381 秒都过去了,两个客户端都没掉线
这说明 BUG 可能存在服务器端,根本原因可能是ASIO 不正确的使用IOCP导致的.
另外,我想问下,大家以前使用 TCP 协议都需要应用层做心跳机制么??? 我咋从来没做过呢,我刚和同事吵过架,他说TCP 应用层心跳机制是必须的.....
我以前用的IOCP 断开都有通知过来。从来不需要所谓的 “TCP 应用层心跳” 只有UDP 的时候,我才做过心跳
QQ 21700579 欢迎交流
#36
我用ASIO 是想写一个 websocket 服务器,我之前写了个 xmlsocket 服务器,跟FLASH 交互的很好,从来没有自动断开这种现象. 我做上面的测试程序的时候,服务器同时开着 xmlsocket 服务呢,聊天室聊天都很正常
#37
刚才又仔细测试了,为防止误导新手..补充说明下:
boost asio chat_server 本机(127.0.0.1)测试 客户端和服务器直连 没任何问题,没有断开的现象
那么还有个可能是 服务器所在机房的防火墙对长时间没有数据收发的连接 采取了 自动断开
网络太复杂了,看来心跳还是必须的
boost asio chat_server 本机(127.0.0.1)测试 客户端和服务器直连 没任何问题,没有断开的现象
那么还有个可能是 服务器所在机房的防火墙对长时间没有数据收发的连接 采取了 自动断开
网络太复杂了,看来心跳还是必须的
#38
lz故意找抽的。多看看书多补补基础再来弄asio神器
#39
你为什么觉得,is_open是判断连接用的呢?
套接字先要open,再连接,连不连接与有没有open有什么关系?
如果不懂网络编程基础知识,不管封装多么好的一个库,也会被错用。
#40
其实我知道“echo_server竟然不会断开客户端?”的原因
真的不是boost的错
#41
那你说说open具体做了什么?
tcp的连接只需要三次握手就可以了,对方断开连接时会发松fin包过来,这个时候自己方是可以判断出连接已经断开了。那为什么就不能封装一个函数直接判断到这个状态呢?非得在写数据或者读数据的时候报错。
还有不要动不动就说别人不懂这个那个的,越牛的人态度越谦虚,半灌水响叮当
#42
作为一个网络库, 我还是同意楼主说的话的. asio作为一个完善的网络基础库来说, 假如是UDP, 那么在检测断线的时间上应该是可以设置的, 假如是TCP, 假如对方非法关闭, TCP的connect应该会得自动检测到断开的, 虽然有点延迟, 但TCP的默认设置不改的话, 不会有30分钟这么长时间的, TCP的socket有问题, 应该会释放客户端相关资源才对的.
网络库就应该提供完善的接口让外部只处理业务内容即可, 还要外部心跳什么的, 就算网络件性能不错, 但设计可以说是烂到掉渣了.
网络库就应该提供完善的接口让外部只处理业务内容即可, 还要外部心跳什么的, 就算网络件性能不错, 但设计可以说是烂到掉渣了.
#43
我是新手,想要学习asio,为了更顺的学,我至少需要先看哪写书呀?求指导,谢谢
#44
#45
有nat的公网对于长时间没有数据来往的连接会忽略fin的发送,这样导致两台机之间通信实际断了但又没收到断线的消息,因此要在应用层加上心跳包来检测,协议层不是完全靠谱的
#46
作为一个库 不做断开检测这很正常 他不知道你需要多频繁的检测
#47
#48
我觉得boost asio这个封装也确实不是很人性化。珍惜生命,远离boost。
#49
#50
继续讨论呀,讨论太有火花