本帖最后由 VisualEleven 于 2014-05-05 11:23:43 编辑

解决方案 »

  1.   

    猜的不一定正确
    1,看看协议有没有问题
    2,看看断点续传时偏移位置是否正确
    3,发送的时候在本地目录WriteFile一份,校验一下MD5
      

  2.   

    你好,关于1,你说协议有没有问题是说TCP协议么?
    2.这个应该没有问题,因为大多数情况下文件都是好的,只是偶尔会出现这个问题。
    3.我现在试试,发送时保存一份,看看是否是否是发出时就已经错了。
    谢谢你的提议。
      

  3.   

    还有  我收到的那32个字节的坏数据是 OK..Server: nginx/0.6.39..Date:
    这是什么东西?
      

  4.   

    tcp一般不会出现坏数据,因为如果传输错误tcp层就会将其抛除并要求重传,并且 OK..Server: nginx/0.6.39..Date:之类的数据肯定不是传输的坏数据的形式,仔细检查一下自己的收发逻辑
      

  5.   

    你好  你有qq么 我加你 咱们讨论一下 帮帮忙。我的qq是641709408
      

  6.   


    一个50多M的文件  发送过来以后  就坏了 
    上面是好的 下面是坏的 就这32个字节不一样 
    不知道为什么这32个字节会变成OK..Server: nginx/0.6.39..Date:这样的数据?
      

  7.   

    数据看着像服务器返回的包头等信息,是不是接收端处理的时候操作有什么bug
      

  8.   

    long x=0;
    char recvBuf[SENDBUF]={0};
    int temp1=0; while((x<con))
    {
    memset(recvBuf,0,SENDBUF);
    temp1=recv(sock1,recvBuf,SENDBUF,0);
    if (temp1>0)
    {
    out.Write(recvBuf,temp1);
    }
    else 
    {
    out.Close();
    closesocket(sock1);
    WaitForSingleObject(hMutex,INFINITE);
    theApp.iTransThreadNum--;
    ReleaseMutex(hMutex);
    CString ss;
    ss.Format("TIME OUT 4");
    theApp.addlog(ss);
    cba--;
    return -1;//未正常接收完毕,客户端断开了连接
    }
    x+=temp1;
    WaitForSingleObject(theApp.hMutex,INFINITE);
    theApp.llDownByte+=temp1;
    ReleaseMutex(theApp.hMutex);
    }
    这是接收端的代码 能不能帮忙看看?谢谢。
      

  9.   

    多谢版主的提醒,现在看着就是recv到了包头的数据然后当初文件数据流写入了文件。请问这是怎么回事啊啊啊?
      

  10.   

    程序是用http协议吗? , 如果不是http, OK..Server: nginx/0.6.39..Date  这些数据应该是系统弄过来的我以前也出现过类似问题, 最后发现是无线网卡的问题, 更新网卡的驱动就好了, 搞了好久的, 
    你可以把程序换个机器去测试看看
      

  11.   

    不是 没有用到应用层的协议,就是普通的TCP\IP传输。
    我在别的N台机器上测试了N多遍,没有出现这个问题,传过去的文件都是好的。
    貌似就是你说的问题啊。但是出问题的机器没有用无线网卡啊。难不成是集成网卡的问题?
    我先更新下驱动试试。
    我qq是641709408,方便加我一下么?以后可以互相交流一下,谢谢。
      

  12.   

    我再弱弱的问句,可能不可能跟网络有关系呢?我更新了下驱动还是不管用。我在别的机器上测试没有一次压缩包损坏的,是光纤的网络,这台出问题的机器是ADSL拨号上网的。
      

  13.   


    http://msdn.microsoft.com/en-us/library/windows/desktop/ms740565(v=vs.85).aspx
      

  14.   

    这个还上升到了驱动一级?搞不好就是out.Write(recvBuf,temp1);有问题。
      

  15.   

    设计编写过TCP文件传输和断点恢复的功能, 
    没有详细看你的代码. 但是看到了那张对比图. 所以说个大概.1.如果是自己设计的文件传输, 用固定的结构体通知双方, 让其知道要传输的文件有多大.
     然后在SOKET里一个发一个接, 在最后完成后, 再进行一次确认, 好像我的这种设计从来没出过问题.2. 如果你是从HTTP服务器下载东西, 要了解HTTP协议的细节, 也编写过纯SOCKET的函数用于和WEB服务器
    通讯和下载文件. 关键两个, 你也要知道你要下载的文件有多大; 什么时候开始创建文件和写文件和关闭文件句柄.
    有些WEB服务器会告诉你你要下载的文件有多大, 而有些则不会.看你的对比图, 好像你把HTTP头里的一些内容写入了文件. 这是错误的起点. 也就是你何时开始写入本地文件文件的判断代码
    有问题.还有,不要轻易怀疑驱动以及协议. 这些东西都比你我古老可靠多了. 
      

  16.   

    不知道有多少前人掉在TCP Socket
    send(人多)send(病少)send(财富)
    recv(人多病)recv(少财富)
    陷阱里面啊!
    http://bbs.csdn.net/topics/380167545
      

  17.   

    不好意思 最近没有上CSDN 谢谢您耐心的回答 关于您提的两点:
    1.这段代码是我自己设计的用来传输文件的,发送文件之前会有一个固定长度的结构体发送给接收端,包含文件大小,文件名等,接收端通过判断结构里的信息反馈给发送端该文件是不存在还是已存在还是已接收一部分需要续传等,然后发送端根据情况循环发送,接收端根据需要接收的大小循环接收,接收完成后会有一个确认符反馈给发送端。就是这个简单的逻辑。
    2.我的这段程序没有涉及到应用层的任何协议,就是单纯的TCP\IP传输。连接服务器,发送文件,断开连接。我调试的时候,将send每次发送成功的数据都写入了一个缓存文件中,等到发送完成后,观察这个缓存文件的二进制和原文件是一样的,但是就是接收端收到的就是要出错,还偏偏都是32个字节的错,上图列出来的只是某一次损坏截取到的错误的32字节流(实际情况是每次收到的错误的32个字节并都不是这写数据,还有别的一些),我观察是http的包头信息的一部分,关键是我这个程序中根本没有用到http协议啊。我再跟您说一下运行情况,我在公司里试验过几十次了,找的都是不同的文件,传过去以后没有一次是损坏的 ,然后我在家里试的时候,不定时的就会出现这样的问题,文件会有32个字节的错误。我也不敢轻易怀疑是驱动或者协议的问题,因为我是实在没办法了。实在找不到问题了,没有调用上层的应用层协议,怎么会就给我出来了这么一段数据了呢。我的qq是641709408  您空闲的时候  可不可以加下我  我们来共同探讨一下呢?谢谢
      

  18.   

    memset(recvBuf,0,SENDBUF);
                    temp1=recv(sock1,recvBuf,SENDBUF,0);
                    if (temp1>0)
                    {
                        out.Write(recvBuf,temp1);
                    }SENDBUF的值是?
      

  19.   

    SENDBUF 是一个宏 1024*4  4KB
      

  20.   

    SENDBUF 是一个宏 1024*4  4KB4096会导致MTU的问题, 也就是大部分的网络MTU值下的传输下都不可能是一次收发数据报文就完成4K的传输.
    但从代码逻辑看, 好像又没有问题. 去翻看了下我古老的代码库, 这个地方的定义的大小才1024, 而不是4096. 你可以尝试修改下这个值再测试.
      

  21.   

    如果发送端和接收端都是个EXE, 可以通过调试来发现问题.1. 确认双方的编译选项不会影响双方获取的结构体大小而出现不一致.
         这个是非常常见又隐蔽的一种BUG. 这个会影响第一次的通讯确认过程. 结构体内容可能因此不同步.2. 在接收开始前确认要获取的文件大小是否有问题, 
        write也有可能出现得到长度和写入结果不一致的情况, 应该加以判断.
    如果是DLL, 那就花点时间, 改造成EXE, 或做个外部的LOADER, 用F11来进入DLL调试.