服务器是TCP协议,如果服务器发送一条信息,而且已经发送出去,但是客户端没有收到,那服务器怎么知道客户端没有收到数据,即丢包

解决方案 »

  1.   

    嗯,tcp协议栈会自动通知应用层的
      

  2.   

    TCP应该不会丢包,你怎么确定客户端没有收到数据不是自身程序的问题呢?
      

  3.   

    我的问题TCP通过什么机制来确认数据没有发给客户端
    就是说服务器已经发出去了,但是在传输过程中被丢失了,但是客户端不知道服务器有没有发,
    那么服务器怎么知道客户端没有收到数据
      

  4.   


    TCP没有这个机制吧,一般是自己定义服务器和客户端通讯的应答协议来判断的,服务器发出指令,如果一段时间没有客户端的应答,则认为客户端没有收到数据噢
      

  5.   

    TCP程序里调用一个send发送数据,即使是阻塞式的,当函数返回时也不代表已经发送成功了。返回仅仅代表数据已经从到了下层(Windows的协议栈、网卡驱动之类的地方)由于TCP的特性,也就是滑动窗口,Windows会允许用户继续发送数据,如果前面的数据丢了,那么协议栈会在后来自动负责重发的工作。如果一直失败就一直重发。所以LZ的问题,我的建议是在应用层设置ACK。由于应用层ACK的存在,其附近的传输效率会受到影响,不过其它地方依然可以享受TCP带来的传输优势。
      

  6.   

    发送方发送一个包之后,即等待ack,同时开启一个定时器,定时器超时,说明没有在规定时限内获得ack,按丢包处理——重发此包。
      

  7.   


    你检查检查你的程序是不是有问题,TCP一般不会丢包的
      

  8.   


    我说的是TCP实现的机制:TCP是如何判断丢包的。  就是依赖定时器。
      

  9.   

    tcp 服务器发送完成,客户端没收到,这种情况我都没遇到过,俺在局域网,没在广域网上试过。
      

  10.   

    从协议层看
    tcp 协议会保证发出去的包到达目的地(客户端),如果超时或其他原因,协议层会尝试重发,直至客户端接收到为止,如果客户端由于某种原因收不到包,send函数(应用层)会接收到通知(send函数返回失败)
    从应用层看,tcp协议不会掉包的,即使丢了,应用层会收到通知。
      

  11.   

    TCP是可靠传输协议,如果你抓一下包就会发现,在连接建立后每发送一个包,都会收到对方的应答包,如果超时没有收到应答包,会重发该包。这些都在TCP内部完成,你并不需要知道,你只要关心TCP连接是否断开。
      

  12.   

    TCP要么就是发送失败, 要么就是发送成功, 不可能丢数据了你还可以继续工作正常, 没有收到任何的错误.
    TCP是面向流, 你所认为的丢包, 百分百肯定出自于你解释流的时候解释错误.
    假如你用的是包头 + 内容 + 包尾的流检测形式, 这种错误很常见. 假如你用的是 长度 + 内容 + 长度 + 内容 的这种流形式, 很经常错误是出自于你没有把长度收完整(例如长度定义为4B, 你只收到2B)的时候, 你就认为内容是这个长度了, 然后造成解释错误. TCP流只要不返回错误, 流传送就肯定是正确的, 错误只会发生成自身的数据分解.
      

  13.   

    The successful completion of a send function does not indicate that the data was successfully delivered and received to the recipient. This function only indicates the data was successfully sent.通常应用层无需关注这个问题。
      

  14.   

    与楼主一样,本人也遇到此问题,使用TCP通信,客户端连接、发送数据成功,但在接收时出现阻塞现象,有时阻塞会5分钟(连接、发送、接收动作都会有日志记录),但服务器段显示已经返回成功,代码如下,也可帮楼主缕缕思路=,=:
    接收方:
    if ( INVALID_SOCKET == ( svc_socket = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED ) ) )
    { return -1; }
    int nRet = setsockopt(svc_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeout, sizeof( int ));
    if ( SOCKET_ERROR == connect( svc_socket, ( struct sockaddr*)&sa, sizeof( struct sockaddr ) ) )
    { return -1; }
    if ( SOCKET_ERROR == send( svc_socket, sendMsg, sendMsgLen+1, 0 ) )
    { return -1; }
    recv_cnt = recv( svc_socket, recvbuf, 10240, 0 ); // 一直阻塞或程序假死。(日志显示发送成功,但接收记录无)
    if ( strlen( recvbuf ) <= 0 )
    { return -1; }
    else
    { return 0; }