为什么我的一个软件,每隔大概10秒就要给对方发送一些数据,使用TCP,数据丢失的很严重。为什么?如何才能保证数据不丢失?

解决方案 »

  1.   

    多看看有关的代码,
    bool RecvData(SOCKET sd,char* buf,int length)
    {
    int total = 0;
    if(length<=0)
    return true;
    if(buf==NULL)
    return false;
    int readi = 1;
    while(total<length&&readi>0)
    {
    readi = recv(sd,buf+total,length-total,0);
    // if(readi==0)//the connection has been gracefully closed
    // {
    // return false;
    // }
            if (readi == SOCKET_ERROR) 
    {
                return false;
            }
    else
    if(readi>0)
    total  +=readi;
    }
    if(total==length)
    return true;
    else
    return false;
    }
    int SendData(SOCKET sd,char* buf,int length)
    { //return 0: OK
    //return -1: totalsent out ! = length
    //return -2: SOCKET_ERROR
    //return 1 : Socket was closed.
    int totalsent=0;
    int sentnum = 0;
    while(totalsent<length)
    {
    sentnum=send(sd,buf+totalsent,length-totalsent,0);
    if(sentnum>0)
    totalsent +=sentnum;
    else if (sentnum == SOCKET_ERROR) 
    {
    return -2;
    }
    else 
    {
    // Client closed connection before we could reply to
    // all the data it sent, so bomb out early.
    return 1;
    }
    }
    if(totalsent == length)
    return 0;
    else
    return -1;
    }
      

  2.   

    楼主,tcp本身造成数据丢失的概率比你中500万的机会还要小得多,你现在的情况很明显是你自己程序的问题,在检查一下自己的程序吧。
      

  3.   

    网络没有问题的话,tcp是不会丢数的.很可能是你发送的时候出错了检查每次发送的返回值
      

  4.   

    TCP协议本身是不会丢包的,网络丢包都由协议处理了,对于你而言,更本不可能出现丢包所以,很明显,你的程序有问题我曾经用一台FTTB的机器和一台无线通讯的电脑P2P通讯,网络状况很糟糕,速度很慢很慢,但绝对没有在我的程序中出现丢包!
      

  5.   

    TCP网络连接会断,但不会丢失数据,如果包丢失了,TCP协议层会自动重发,你的应用程序不可能遇到丢包的情况,应该是你程序本身逻辑有错误。
      

  6.   

    看看你程序,tcp传输时候,接送端要循环接受,因为tcp会自动分片的
    并不是说你组装多大的数据包,在接受端一次就可以接受到(可能也可以,如果网络好)
    所以接受段的程序一定要check package 的 size.
      

  7.   

    我用的是CSocket,发送和接收都 try 了。使用的是非阻塞模式,受到消息自会调用我的函数,然而有时候根本就不调用,说明没有受到消息。如果是程序的问题,会出在哪?因为并不是所有消息都丢失,只是偶尔,但概率比我中500万高的多,这是为什么?程序出了什么问题的情况下可能会发生这种事情?因为丢失情况随机发生,所以有没有什么好的调试方法?
      

  8.   

    呵呵,今天晚上遇到了同样的问题,解决了.我只用了一个线程去给所有的客户端发数据,当数据发送相当频繁(比如说一次性给所有的客户端发送数据)时,数据丢失很严重,后来在循环里加了个Sleep(10),一切正常了
      

  9.   

    我前段时间用TCP时,发现接收数据有“粘包”现象,即假设我发送的定长包是100字节,但接收时经常是100字节的N倍,需要处理,尤其快速发时。
    我是8ms发送近100字节。(要求较精确时间,用多媒体定时器,所以不能用sleep)
      

  10.   

    只要成功发送,不会丢的,丢的那是UDP,就不叫TCP了,可能是你程序自己的问题,再说你是不是在局域网里测试的?网络正常的话就算UDP也不会老丢包
      

  11.   

    http://www.somade.com/是个很专业的技术社区,去那里找找吧,或许有你要的答案~
      

  12.   

    我的服务端客户端和客户端都用EventSelect模型,Server循环接收,也是超出中500万几率地接收不到Client的数据(虽然Client发送数据成功了),到最后也没有检查出Server的编码哪有问题。后来把Client改为阻塞模式,好像可以了。
    我没有解决这个问题,失败!
      

  13.   

    楼主接收端处理有问题,TCP不象UDP是按照一个个包发送的,你接收端接收UDP的话是按照发送端发出的包一个一个收回来的,而TCP是面向流的,发送端的一个多个send调用可能才会发出一个包来,这是TCP为了提高效率设置的策略,这样在接收端收到的一个包可能是发送端发出的多个包,你必须要按照处理流的方式来处理你的数据,而不能简单认为你收到的一个包就对应你发送端发送的那个包。当然也可以在发送端做设置,可以使没有send马上就发送数据,而不等待。  CString strMsg;        
    BOOL bOption = TRUE;
    int  nRet = -1;
    nRet = setsockopt(hCtrlSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&bOption, sizeof(bOption));
    if(nRet == SOCKET_ERROR)
    {
    Msg.Format("设置控制Socket的NODELAY出错,错误号为:%d",GetLastError());
    ShowMsg(Msg);
    }
      

  14.   

    可以使没有send马上就发送数据,
    写错了,是send后马上就发送数据
      

  15.   

    我使用的是  CSocketFile::Flush() 不知这个函数的功能是不是就是立即发送?