1、心跳方法我知道,但这次不知道对方的心不会跳
2、通过发送测试性数据是否成功的方法然后检测错误也不适用于这里,因为对方收到莫名奇妙的东西时会弹出来说有“垃圾信息”
3、有人说用recv()的方法,若返回值小于等于0就认为对方断开了,但是这次对方基本是哑巴,我recv一直收不到任何东西,只会阻塞在那儿
4、有人用WSAASyncSelect,我写的是WSAASyncSelect(m_sock, m_dlg->m_hWnd, WM_MYMSG, FD_CONNECT),然后在WindowProc的时候也没有找到对方断开后会发送什么暗号给我,这个方法我不会用请教高人速速教我怎么不发送测试信息而又能及时判断对方断开了原先建立的socket(比如对方的程序关闭了)分数就这么多了,抱歉。

解决方案 »

  1.   

    udp方式只能通过收发报文判断
    tcp方式在正常情况下对方关闭会发送关闭socket消息,这是socket会被置为无效状态,通过select判断socket是否还可写能判断是否连接正常,如果对方拔网线,那不行,但是可以重建一个socket,看看能不能connect成功判断。
    如MFC中无论哪一方关闭socket,对方都会就会触发OnClose响应,拔网线不行。
      

  2.   

    是这样的,如果对方是正常退出,包括在程序中断开连接、退出程序等等,你这边都是可以获得onclose()事件,和socket   error,直接处理就好但是如果对方是非正常断开,比如突然断电或者拔掉网线什么,你这边是无论如何也不会立即获知状态的,这里只能使用“心跳包”的方式,包括现在最新版本的腾讯QQ2009都同样是使用的心跳包的方式来判断QQ客户端是否在线,这就说明处理这个问题,暂时还没有更好的解决方案。否则你就只能通过频繁的调用connnect来测试对方是否在线了....
      

  3.   

    keepalive的选项或者超时自动默认为断开了.........
      

  4.   

    我觉得 发心跳包不好 , 呵呵, 因为如果对方只发不收的话, 会把对方的接受buffer发满的, 大概就是8k左右。 然后继续发心跳包失败。还是超时判断好, 某一短时间如果没有收到对方数据则认为 断线。应该根据自己的具体应用, 上面2种结合也好的, 如果超时没收到就发一个小的心跳包,如果失败,则短线。呵呵。
      

  5.   

    KeepAlive的使用应该就是心跳包吧?
    不过,为什么要去掉心跳包呢?对系统有什么影响呢
      

  6.   


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

  7.   

    如果正常断开的话,如feiyangdn所说:“如MFC中无论哪一方关闭socket,对方都会就会触发OnClose响应”
    如果不正常断开,如死机、网线突然断开,可以采取定时发送数据包的方式来检测。比如,a每隔5秒向b发送一个数据包并将某标志位置0,b收到后返回给a,并将标志位置1。如果b断开了就不能返回,标志位继续保持为0。这样只要检测标志位是1还是0就知道对方是否断开了。
      

  8.   

    在delphi 中, 有个Indy 的 TClientSocket 控件,很灵敏,对方一停, 马上就有一个事件Disconnect被触发。
    具体原理没有研究,但是我想在VC中一定也是可以做出来得。
      

  9.   

    心跳包的方法只适合对方有相应的心跳包处理的情况,如果对方没有心跳包机制,你自作多情地发心跳包,开始还正常,时间长了就会发现对方死了——但其实它没死,只是接收缓冲区被你填满了connect的办法只适合对方是服务器,对方是客户端的话你没办法connect总之这个问题没有完美方案,需要双方配合解决
      

  10.   

    发送icmp给对方看看  看返回什么类型
      

  11.   

    我记得select之后,尝试读已经断开的socket,会返回-1之类的值。
      

  12.   

    正常情况下不管你掉电还是拔掉网线 recv一般都返回滴,以上同学们说的是一种非常异常的情况
      

  13.   

    要收数据的话 你把该套接字放到FD_SET集合里
    然后交给select函数,在一个线程里循环收数据包即可
    对方一断开,另一端立即能感知到,select会立即受信,你可以试试
      

  14.   

    ok,在recv前加个select,recv这个连接后若不正常就表示对方断开了,很准,谢谢各位