首先重要纠正一点,在网上找方案发现很多人在误导别人,说TCP传输文件用C++写会丢,让采用应答模式,自己没搞清楚就不要发出来误导别人。
TCP是稳定可靠顺序传输,网络正常不会丢包,而且发送和接收顺序一样,出现丢得不过是粘包处理不当而已。
本文测试基础是C++ QT5环境
做一个即时聊天工具带文件传输,结果发现文件传输总是出错,做了个研究,有解决方案了,基本传输速度取决于网络带宽。
做测试使用应答模式 每个文件大小固定发8008大小得包(采用一个int头,表示包大小,后面跟QBYTEARRAY),采用应答模式,发200M文件,有九成会发到一部分停止了,就算底层采用每个包,没收到得包重发,结果依然,而且重发得包,服务器也可以接受,但是读取数据全是是错的。详细查看该结果,发现接收错误得包接受int值是正常得,但是接受后面跟得QBYTEARRAY长度为0。(而这种情况要基本上要每个包发送后用SLEEP(50)才能基本杜绝,但是效率可想而知)
后来单独做了一个小测试程序,客户端发10000个8008(一个int加一个8000长度得QBYTEARRAY)大小的包(不是底层,是QT封装得,QT限制每个包最大8K,道理都一样,相信你可以看到怎么解决得),服务器采用相应readyread每次读取一个int和一个qbytearray;结果服务器固定相应readyread9979,而且查看包内容发现只有最后21一个包没收到,前面包都正常接受,这说明TCP 发送没有丢包,只是服务器数据处理有问题,服务器解析包得时候没把最后得包最好处理。然后做个各种测试,测试结果就不说了,后面跟理论结果外加一段测试小代码。
我们发送时候每个包都是8008,密集发送,但是服务器读取时候每次readyread到得长度为8192(非固定,个别因为TCP底层时效问题,导致会读到一个特别短得包,几率大约万分之1左右,代码中也有处理这种情况),就是每次QT从TCP底层拿走8192长度得数据,但是我们做解读得时候只读了8008个字节而这剩下得长度就在QT中不断积累,一万个正好擦不多21*8008得长度,自己测试可以用这两个函数查看一下是不是[url=qthelp://com.trolltec