tcp中,把accept得到的CSocket::m_hSocket传入线程中,Attach后使用,收发正常。但发现当连接的另一端ShutDown后,OnClose()并不被调用,Receive(...)返回0,且变成非阻塞调用。请问这种情况下怎样得知对方的ShutDown或Close。另外,如果是完线断了或其他硬件连接中断,该如何得知呢?

解决方案 »

  1.   

    一块讨论讨论吧 我想是只有对方调用Close后 这边的OnClose才会响应 仅仅是
    关闭程序或网络本身出线问题OnClose都不会响应
      

  2.   

    相互间发送握手消息,或者进行Ping
      

  3.   

    Receive(...)返回0
    那就靠这个判断吧。
      

  4.   

    只有当对方是正常的关闭SOCKET,OnClose才能响应。
    而其他的如非法操作等ONCLOSE都不会响应。
    我用的办法是每隔一定的时间发一些信息,如果对方已经断了,那么就会收到发送异常。从而知道对方已经断了。
      

  5.   

    等到Receive返回0,可能都猴年马月了。
      

  6.   

    to _liang_(liang):
    对方的程序可能根本就不是你来做的 怎么自定义消息?
      

  7.   

    我想问2个问题:
    1。连接的另一端使用ShutDown()或Close(),我这儿的OnClose怎么没有响应。是不是和在线程中使用CSocket有关。不过m_hSocketWindow已正常创建,WSAAsyncSelect也没有错误,没有理由收不到。
    2。但硬件中断后,如进行读操作,一般会陷入诸塞状态,如果等待操作结束,可能要事先对超时加以设置。不知有没有更好的办法。希望有经验的朋友能够指点一下。
      

  8.   

    huangqd(点点) :
    attach已调用AsyncSelect
      

  9.   

    这样搞,和对方约定一个协议,比如每隔两秒钟发一个包,如果对方异常关闭了那么你发包的时候send()就会返回SOCKET_ERROR
      

  10.   

    recv()返回0不一定代表对方已经关闭连接了啊,假如是数据传送完毕或者网络阻塞造成超时?我想这样是否可行:分析得到的IP数据包的头部,如果有了FIN字段,那就是正常关闭连接,如果长时间比如2分钟不能收到数据那就是连接断开(包括非正常关闭),关注
      

  11.   

    我们认为对服务端而言,非超时的错误,都可以认为对方关闭。当然,对CLIENT与与SERVER端的通讯,相互可以通过在闲时的握手消息(ECHO消息)得知对方的状态。
      

  12.   

    Receive(...)返回0 最好是自己写一个传送函数 如果没有返回就判断对方退出
      

  13.   

    1.用Event I/O可解决。但还是没搞清楚CSocket在线程中怎么会这样。
    2.用了Ping解决。但心有不甘,tcp这样面向连接的协议,还要在用户程序这一级做这些事吗?搞得跟写Udp一样。在sock option有SO_KEEPALIVE一项,MSDN说:
    If a connection is dropped as the result of keep-alives the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN.但我试了一下,好像不是那么回事。不知各位试过没有
      

  14.   

    可以sleep(100)等待对方i/o结束,tcp应该自己应该可以判断的。然后发送消息判断。
      

  15.   

    使用select(),如果socket连接异常它会返回错误!
      

  16.   

    关注~~`正如上面一位老兄的话,TCP应该自己能发现连接的中断,并上报给上面的层阿~~我也猜不透了
      

  17.   

    如果服务端主机shutdown或者程序dump,都会给你的客户端程序发送长度为0的消息,依靠这个可以判断对方是否关闭!
    但是TCP对于网络连线物理断开无任何侦测能力,除非这时你在传送数据,你才会发现网络出了问题,因此对于这类错误,你必须使用定时询问的方式才能了解错误的发生。
      

  18.   

    呵呵,各位楼上的,我所知道的是这样:
    当你在适当的时候调用recv时(我指的适当有如下两种情况:阻塞socket时recv有返回,或者非阻塞情况下当接收到recv事件时),如果recv返回0,则表示远端已经优雅的关闭了socket,
    如果你一定想在某个时候知道对方是否还保持着socket连接,你应该使用MSG_PEEK作为参数调用recv,使用MSG_PEEK时,从tcp队列中取出数据,但并不会将队列中的数据清掉,如果recv(..MSG_PEEK)返回的值为错误,则表示对方肯定已经掉线了
    欢迎拍砖—————————————————————————————————
    ┏━★━━◆━━★━┓ 
    ♂欢|◢CSDN◣|使♂        ▲自由保存帖子,浏览,关注检测
    ┃迎|◥论坛助手◤|用┃        ▲完善的CSDN客户端工具
    ┗━☆━━◇━━━☆┛       ▲自动添加签名......让你更快,更爽,更方便地上CSDN...
    http://www.csdn.net/expert/topic/573/573604.xml
    http://www.chinaok.net/csdn/csdn.zip
      

  19.   

    对于一个全双工的TCP连接,在一端调用shutdown只是关闭某一方向的通信,实际上TCP连接还是存在的,也就是说还没有发送FIN抱文,系统为插口分配的资源都还保留,当然也不会有OnClose被调用了,如果一方调用了close,FIN被发送,OnClose会被调用的
      

  20.   

    我现在就想问:
    对于SO_KEEPALIVE,MSDN说:
    If a connection is dropped as the result of keep-alives the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN.
    我使用SO_KEEPALIVE,但结果不象MSDN写的,各位不知有没有用过,介绍一下。
      

  21.   

    回复人: yyc_csdn(yyc) ( ) 信誉:100  2003-1-28 14:10:35  得分:0 
     
    使用select(),如果socket连接异常它会返回错误!同意一部分。
    先select,FD_ISSET()为真了。(断开了也为真)
    再int nRecv = recv()
    if(nRect == 0)
    {
      //断开了
    }