各位大虾,我编了一个基于tcp/ip协议的多机网络通信程序,如果关机、死机的情况都能判断出通信异常,唯独在建立连接成功后,对方机器拔掉网线后,我再发送数据,程序不出错(信息显示数据仍然发出了,但是对方收不到),我无法立即检验处通信异常。请问有甚莫好办法吗?(getpeername已经试过,不起作用)

解决方案 »

  1.   

    应该会发一个CLOSE消息吧
    重载OnClose()函数试试!
      

  2.   

    关机、豕机都会发出关闭(断开)连接的通知,但是如果在连接的情况下断开网线,则什么消息都不会发出,所以另一方无法得知!可以在发送数据之前先ping得结果之后再处理!
      

  3.   

    前段时间有两个帖子刚讨论过这个问题,不过最后用的是ping,当然最完美的方法是得到Windows的通知,不过想必只能在驱动层实现
      

  4.   

    OnReceive()中的ErrorCode可以判断
      

  5.   

    UNIX当中有一个办法
    用的是心搏函数:即没隔一秒发送紧急数据给对方,如果不回应则认为已经断开。
      

  6.   

    直接拔网线,socket两端都是无法知道的。
    如果阻塞调用,recv将会一直阻塞,send将会成功,一直到阻塞!
    如果非阻塞调用,recv将会返回WSAEWOULDBLOCK错误,send成功,直到返回WSAEWOULDBLOCK错误。建议使用超时控制,不推荐使用OOB数据,因为这样在正常情况下徒增通讯数据量
      

  7.   

    很不幸,因为TCP不提供心跳机制,所以在这种情况下如果不向对方发送数据,是永远不可能知道链路已断的。可定时向对方发送数据以监控链路状态。
      

  8.   

    我也碰到同样的问题,后来我们在自己的协议中加入了Hello信息,在一定的时间,比如10秒,没有收到对方的Hello信息,则认为网络断开了,这样双方都会断开连接。如果网络好了,可以重新连接上。Windows系统倒是能知道网线拔了,但不知如何获取这种消息。欢迎切磋。
      

  9.   

    在自己的协议实现了定义一个 “保持连接活动” 的消息。每隔一段时间发送一次, 调用 send WSASend,如果发生错误, 就知道网络被断开了
      

  10.   

    同意alanwang_(alan)的说的,直接拔网线,socket两端都是无法知道的。
    只能通过recv,send的返回值判断.Windows系统能知道网线拔了,恐怕也是应用了一些小技巧. 
    局域网的速度很快,一段时间内不能联络上其他PC,就可以认为是网线断了.
      

  11.   

    to han012(阿毛)recv 是无法判断的!网线被拔掉后, 掉用 recv 仍然继续阻塞等待数据到来, 如果是阻塞模式。异步的话, 会返回 SOCKET_ERROR, WSAGetLastError 返回 WSAEWOULDBLOCK只有 send WSASend 能发现网络不通
      

  12.   

    我做过网卡底层的操作(用单片机),网卡肯定可以知道网线是否接好的,你试着检查一下网卡状态,另外,win xp中system tray上的图标也能反映网线是否接好,不知怎么实现的,知道了别忘了告诉我一声 [email protected]
      

  13.   

    我用的是应答,比方说我给对方发一条消息,必须等对方应答后我才能继续发送后面的数据,否则就等待超时,效率很低,主要考虑必须确认对方收到。to: vtable9999(肝肝肝肝) 
    发第二次出错,程序有什么表现没有?比方说非法操作、或者死机什么。
      

  14.   

    感谢各位的帮助,大家的意见我觉得都很正确,唯一令我疑惑的是,在我拔掉网线之后,第一次用send或WSASend,程序并不能检查出错误,可是如果第二次再发送的话,系统就能判断出网络断开了,这是怎莫回事呢?即然第一次判断不出来,第二次又怎莫能判断出来呢。
      

  15.   

    这需要server和client两方面的配合,你可以做个定时器每隔多长时间就给server端发送一个在线信息,server端收到后给一个应答信息,如果连续3次都收不到,不就是掉线了吗。
      

  16.   

    回复人: 2ndboy(丢丢) (  ) 信誉:100  2002-08-26 18:41:00  得分:0 
    前段时间有两个帖子刚讨论过这个问题,不过最后用的是ping
    ------------------------------------------------------------------
    谁能给一下这个贴子的链结?
      

  17.   

    to xlander(阿富) :第二次时,send函数会返回网络crash的错误代码。在非阻塞socket中,send返回的是把数据拷贝到核心buffer的结果,具体发送的结果只能在下一次send时才能知道。
      

  18.   

    to xlander(阿富) :当然,只有在网络环境好时第二次Send才会马上有错误代码返回,网络环境不好时,可能需要Send好几次后才有,最极端情况,要把发送缓存全塞满了才会报错!!
      

  19.   

    To: vtable9999(肝肝肝肝) 
    谢谢,你很专业阿。
      

  20.   

    好问题!密切关注!因为下一步我也开始要着手SOCKET部分了。
      

  21.   

    // local system uses a modem to connect to the Internet.
    const DWORD INTERNET_CONNECTION_MODEM      = 1;
    // local system uses a local area network to connect to //the Internet.
    const DWORD INTERNET_CONNECTION_LAN        = 2;
    // local system uses a proxy server to connect to the Internet.
    const DWORD INTERNET_CONNECTION_PROXY      = 4;
    // local system's modem is busy with a non-Internet connection.
    const DWORD INTERNET_CONNECTION_MODEM_BUSY = 8;BOOL TestConnectState()
    {
      DWORD dwConnectionTypes;  dwConnectionTypes = INTERNET_CONNECTION_MODEM +                               INTERNET_CONNECTION_LAN +  
                          INTERNET_CONNECTION_PROXY;  return InternetGetConnectedState(&dwConnectionTypes, 0);
    }//每隔一定时间调用此函数看是否连接了网络
    ================================================================曾经有一碗热辣辣的烧猪手面放在我面前,我没有珍惜,等到晾凉了之后才后悔莫及。