用send来发送的是面向连接的传输,所以成功后才会返回正确的,也就是说已经送到了对方,至于对方是否能正确接收,就不是本问题所问的事了,不过如果用sendto的话,它才是面向无连接的,不能确保送到,也就是你说的情况了。

解决方案 »

  1.   

    "假如SOCKET建立后,切断双方的物理连接.此时调用send返回正确",不可能吧。
        TCP是面向连接的服务,他必须保证链路畅通,如果你在SOCKET建立后切断物理链接,TCP服务一定会监测到的,你不可能调用send成功的。在TCP中,你每发送一个分组,都会启动超时定时器等待对方的确认,如果在规定的时间内不到确认,将重发该分组,所过重发超过一定的次数,就会认为链路不通,所以你这种情况不可能出现的,实际上,由于网络的不可靠性,别人在设计TCP/IP是就已经考虑到你这种情况了。
        另外,在链路层也有相似的重发机制。
      

  2.   

    to FireAngel:
       不信您可以试试.
       再引用MSDN(send:re)一句话:
      “The successful completion of a send does not indicate that the data was successfully delivered.“
      

  3.   

    我说得很清楚,send只保证数据被放到发送缓冲区内。到是最后一次send后,过一两分钟
    KEEP-ALIVE会检测到错误并使随后的操作返回WSAENETRESET。但最后一个包已经丢了。
      

  4.   

    to zhq2000:
       我无法确定那个包是最后一个。可能每个包都是最后一个,也可能都不是。
      

  5.   

    同意FireAngel的说法,事实上TCP/IP就是这样作的,MSDN上的表示是比尔的一贯作风,Send应与使用协议链结在一起讨论才有意义,如果在UDP传输时MSDN的说法是必然的(Send也可以用在UDP上),在Tcp协议上使用就因满足协议要求
      

  6.   

    我的分析:
    问题的关键在于你的SOCK_STREAM类型,这个类型的特点是:在发送点断开以后,ReceiveFrom也会有一个返回,不过为0字节罢了!也就是说,这个类型并不保证数据一定到达!要进一步判定还得进一步处理.
    一个解决方法:
    你可以另建一个指针,或者在你的数据传送结构指针中加入一个ID用来标志这个数据,这样在接收端,就会知道时哪些数据到达,那些数据没有到达!仅供参考!
     
      

  7.   

    我的分析:
    问题的关键在于你的SOCK_STREAM类型,这个类型的特点是:在发送点断开以后,ReceiveFrom也会有一个返回,不过为0字节罢了!也就是说,这个类型并不保证数据一定到达!要进一步判定还得进一步处理.
    一个解决方法:
    你可以另建一个指针,或者在你的数据传送结构指针中加入一个ID用来标志这个数据,这样在接收端,就会知道时哪些数据到达,那些数据没有到达!仅供参考!
     
      

  8.   

    如果是仅仅是线路断开的话,Send会发到发送缓冲区,不会检测到错误,当线路重新连好后缓冲区中的内容会继续发往对方,不会丢包,不过会出现几个包连在一起的情况。
    如果想知道每个包对方是否收到的话,可以在发完一个包后再调用PING例程测试一下,如果正常的话,由于SOCK_STREAM是面向连接的,数据就一定能发到对方;如果PING失败就不能保证刚才发的数据能否到对方了,但这样只有一个数据包不能肯定。
      

  9.   

    to dingsg:
       1.SOCK_STREAM 是面向连接的.
       2.您的说法不太明确.winsock api send 在将数据送达发送缓冲区内后立即返回.至于随后TCP协议保证在物理连接完好的情况下将数据送至对端接收缓冲区内,不至于因为瞬时故障或数据淹没等而导致数据丢失.而在物理连接不能保证的情况下,TCP协议也能够检测到硬件故障.但由于send已经返回了,所以阻塞模式下应用程序无法得到通知.只能在下一次的套接字操作中返回错误:
    WSAENETRESET 
    (10052) 
    Network dropped connection on reset. 
    The connection has been broken due to "keep-alive" activity detecting a failure while the operation was in progress. It can also be returned by setsockopt if an attempt is made to set SO_KEEPALIVE on a connection that has already failed.
       3.您的解决方案在下也曾考虑过.感谢您的回答.恳请各位继续出谋划策.