TCP中如何判断,已建立一个socket后,对方断开了此连接

flamkuavos 2009-09-27 05:25:23
1、心跳方法我知道,但这次不知道对方的心不会跳
2、通过发送测试性数据是否成功的方法然后检测错误也不适用于这里,因为对方收到莫名奇妙的东西时会弹出来说有“垃圾信息”
3、有人说用recv()的方法,若返回值小于等于0就认为对方断开了,但是这次对方基本是哑巴,我recv一直收不到任何东西,只会阻塞在那儿
4、有人用WSAASyncSelect,我写的是WSAASyncSelect(m_sock, m_dlg->m_hWnd, WM_MYMSG, FD_CONNECT),然后在WindowProc的时候也没有找到对方断开后会发送什么暗号给我,这个方法我不会用

请教高人速速教我怎么不发送测试信息而又能及时判断对方断开了原先建立的socket(比如对方的程序关闭了)

分数就这么多了,抱歉。
...全文
7050 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
sweil000843 2010-11-01
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 arong1234 的回复:]
1、2的方法其实是同一个,你当然不能发无意义的数据让对方认为这是“垃圾信息”,心跳、检测报文是双方约定的一部分,是有用数据。你担心这个说明你还不懂这个。


引用楼主 flamkuavos 的回复:
1、心跳方法我知道,但这次不知道对方的心不会跳
2、通过发送测试性数据是否成功的方法然后检测错误也不适用于这里,因为对方收到莫名奇妙的东西时会弹出来说有“垃圾信息”
3、有人说用recv(……
[/Quote]

对的,心跳和底层应答是需要双方约定的,这在有保障的网络通信过程中是必须的。
flamkuavos 2009-10-09
  • 打赏
  • 举报
回复
ok,在recv前加个select,recv这个连接后若不正常就表示对方断开了,很准,谢谢各位
arong1234 2009-10-07
  • 打赏
  • 举报
回复
1、2的方法其实是同一个,你当然不能发无意义的数据让对方认为这是“垃圾信息”,心跳、检测报文是双方约定的一部分,是有用数据。你担心这个说明你还不懂这个。

[Quote=引用楼主 flamkuavos 的回复:]
1、心跳方法我知道,但这次不知道对方的心不会跳
2、通过发送测试性数据是否成功的方法然后检测错误也不适用于这里,因为对方收到莫名奇妙的东西时会弹出来说有“垃圾信息”
3、有人说用recv()的方法,若返回值小于等于0就认为对方断开了,但是这次对方基本是哑巴,我recv一直收不到任何东西,只会阻塞在那儿
4、有人用WSAASyncSelect,我写的是WSAASyncSelect(m_sock, m_dlg->m_hWnd, WM_MYMSG, FD_CONNECT),然后在WindowProc的时候也没有找到对方断开后会发送什么暗号给我,这个方法我不会用

请教高人速速教我怎么不发送测试信息而又能及时判断对方断开了原先建立的socket(比如对方的程序关闭了)

分数就这么多了,抱歉。
[/Quote]
hurryboylqs 2009-10-07
  • 打赏
  • 举报
回复
要收数据的话 你把该套接字放到FD_SET集合里
然后交给select函数,在一个线程里循环收数据包即可
对方一断开,另一端立即能感知到,select会立即受信,你可以试试
hurryboylqs 2009-10-07
  • 打赏
  • 举报
回复
正常情况下不管你掉电还是拔掉网线 recv一般都返回滴,以上同学们说的是一种非常异常的情况
delphiwcdj 2009-10-07
  • 打赏
  • 举报
回复
学习
chuanqi2009 2009-10-07
  • 打赏
  • 举报
回复
用户 昵称 2009-10-04
  • 打赏
  • 举报
回复
我记得select之后,尝试读已经断开的socket,会返回-1之类的值。
ljbcharles 2009-10-03
  • 打赏
  • 举报
回复
winSocket学习一下了
  • 打赏
  • 举报
回复
发送icmp给对方看看 看返回什么类型
angeryi 2009-10-03
  • 打赏
  • 举报
回复
采用 心跳包可以实现
fangle6688 2009-09-30
  • 打赏
  • 举报
回复
心跳包的方法只适合对方有相应的心跳包处理的情况,如果对方没有心跳包机制,你自作多情地发心跳包,开始还正常,时间长了就会发现对方死了——但其实它没死,只是接收缓冲区被你填满了

connect的办法只适合对方是服务器,对方是客户端的话你没办法connect

总之这个问题没有完美方案,需要双方配合解决


Hotthing 2009-09-29
  • 打赏
  • 举报
回复
在delphi 中, 有个Indy 的 TClientSocket 控件,很灵敏,对方一停, 马上就有一个事件Disconnect被触发。
具体原理没有研究,但是我想在VC中一定也是可以做出来得。
野男孩 2009-09-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 flamkuavos 的回复:]
1、心跳方法我知道,但这次不知道对方的心不会跳
2、通过发送测试性数据是否成功的方法然后检测错误也不适用于这里,因为对方收到莫名奇妙的东西时会弹出来说有“垃圾信息”
3、有人说用recv()的方法,若返回值小于等于0就认为对方断开了,但是这次对方基本是哑巴,我recv一直收不到任何东西,只会阻塞在那儿
4、有人用WSAASyncSelect,我写的是WSAASyncSelect(m_sock, m_dlg->m_hWnd, WM_MYMSG, FD_CONNECT),然后在WindowProc的时候也没有找到对方断开后会发送什么暗号给我,这个方法我不会用

请教高人速速教我怎么不发送测试信息而又能及时判断对方断开了原先建立的socket(比如对方的程序关闭了)

分数就这么多了,抱歉。
[/Quote]

阻塞方式下,recv()函数收到小于等于0的返回值就是说明断链了。但是对端拔网线基本上检测不出来。此时只能靠心跳包来检测。心跳包可以是应用层自定义的心跳消息,也可以是TCP协议本身的Keep-Alive消息。建议用Keep-Alive消息,系统开销很小,并且很有效。

可通过setsockopt来设置keep-alive消息的间隔时间,建议30秒
PiggyXP 2009-09-28
  • 打赏
  • 举报
回复
是这样的,如果对方是正常退出,包括在程序中断开连接、退出程序等等,你这边都是可以获得onclose()事件,和socket error,直接处理就好

但是如果对方是非正常断开,比如突然断电或者拔掉网线什么,你这边是无论如何也不会立即获知状态的,这里只能使用“心跳包”的方式,包括现在最新版本的腾讯QQ2009都同样是使用的心跳包的方式来判断QQ客户端是否在线,这就说明处理这个问题,暂时还没有更好的解决方案。

否则你就只能通过频繁的调用connnect来测试对方是否在线了....
cpp_crab 2009-09-28
  • 打赏
  • 举报
回复
KeepAlive的使用应该就是心跳包吧?
不过,为什么要去掉心跳包呢?对系统有什么影响呢

[Quote=引用 9 楼 ahniyilin 的回复:]
如果对方是非正常断开,比如突然断电或者拔掉网线,还是对方发送心跳包比较好。。。
我现在做的和楼主差不多的系统
也想去掉心跳包。。。但是就是去不掉心跳包
呵呵!!
高人出来指点指点啊!!
[/Quote]
ahniyilin 2009-09-28
  • 打赏
  • 举报
回复
如果对方是非正常断开,比如突然断电或者拔掉网线,还是对方发送心跳包比较好。。。
我现在做的和楼主差不多的系统
也想去掉心跳包。。。但是就是去不掉心跳包
呵呵!!
高人出来指点指点啊!!
PiggyXP 2009-09-28
  • 打赏
  • 举报
回复
只使用超时来判断是不可行的

因为如果你能和客户端之间保持一个非常频繁的通信的话,是可以的,但是我们设想一个比较极限但是非常有可能的情况,就是你和客户端之间平均每一个小时才收发一次数据的话:

如果上次通信完毕之后,客户端那边就关机了,这样问题就出现了,服务器这边却只能等到一个小时之后再次与客户端通信的时候才可以知道客户端断开了?这样做有点不合理吧

这里最理想的就是使用心跳包的方法了,暂时没有更好的解决方案
muzizongheng 2009-09-28
  • 打赏
  • 举报
回复
我觉得 发心跳包不好 , 呵呵, 因为如果对方只发不收的话, 会把对方的接受buffer发满的, 大概就是8k左右。 然后继续发心跳包失败。

还是超时判断好, 某一短时间如果没有收到对方数据则认为 断线。

应该根据自己的具体应用, 上面2种结合也好的, 如果超时没收到就发一个小的心跳包,如果失败,则短线。

呵呵。
dirdirdir3 2009-09-28
  • 打赏
  • 举报
回复
keepalive的选项或者超时自动默认为断开了.........
加载更多回复(5)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧