MFC大文件传输

MFC大文件传输

MFC大文件传输核心思想(C/C++程序员之家自己研究的,请大家指出不当之处,以便更正):

首先先给下CSDN上论坛对TCP大文件传输的讨论:

TCP发送端速度过快,有可能造成堵塞,发送缓冲区满之后就会丢数据,然后就造成数据不准确了。

  1. 解决方法一、设置发送缓冲区成更大的值(不提倡)。
  2. 解决方法二、使用确认包,每次只发一个小包,客户端收到后向服务端发“确认”反馈,服务端等收到“完成”后再发下一个包。
  3. 解决方法三、采用完成端口技术……

所以我们要考虑大文件的时候,是否数据正常接收。这里,最好采用“确认机制”,或者是“文件分割编号机制”,文件分割方法个人感觉较好,在客户端可以方便组装!如果还是不能正常接收文件建议大家检查数据是否丢包(或者服务器线程简单的休眠(Sleep),调试程序)。

大文件传输结构体模型

1typedef struct tagPic
2{
3UINT FileLength;//文件大小
4BYTE data[1024];//图片数据buff
5int id; //分块id号
6int Count;//分块数量
7int last;//每次最终成功发送的数据量
8}PIC;

1、接下来思路是:服务器文件传输线程分块儿读取文件发包,然后封装成普通消息发给客户端。客户端接收来自服务器端的消息,判断是否是文件传输消息,如果是文件传输消息,直接交给客户端文件传输线程,最后判断id和last只需分块而写入文件即可!

2、理论上支持大文件传输,测试了200M以上的无压力,更大的文件的没有测试,BYTE data[1024],可以根据消息容纳字节数,自己调整buff缓冲区。

备注:TCP可能的丢包现象:

简单写了一个传输JPG图片的程序,图片但是只能显示一半,下半部分图片无法正常显示(花屏)!因为会发生阻塞,所以研究了好长时间,结果加上一个Sleep(300),服务器发过一次数据之后休眠,解决了此问题。

服务器端:

01AfxSocketInit(NULL);
02CSocket sockSrvr;
03sockSrvr.Create(PORT);
04sockSrvr.Listen();
05CSocket sockRecv;
06sockSrvr.Accept(sockRecv);
07CFile tFile;
08tFile.Open(_T("C:\\Cache.jpg"), CFile::modeRead | CFile::typeBinary);
09ULONGLONG myFileLength = tFile.GetLength();
10sockRecv.Send(&myFileLength, 8); //先发送文件大小
11 
12byte buff[1024];intreVal;
13memset(buff,0,1024);
14int Count = myFileLength/1024+1;
15if(myFileLength%1024==0) --Count;
16for (inti=0;i<Count;i++) //移位、读取1024字节、发送真实字节数
17{
18tFile.Seek(i*1024,CFile::begin);
19reVal=tFile.Read(buff,1024);
20sockRecv.Send(buff,reVal);
21Sleep(300); //TCP发包过快,会产生丢包现象。
22}
23 
24tFile.Close();
25sockRecv.Close();

客户端:

01AfxSocketInit(NULL);
02CSocket sockClient;
03sockClient.Create();
04sockClient.Connect(_T("192.168.4.78"), PORT);
05ULONGLONG dataLength;
06sockClient.Receive(&dataLength, 8);
07 
08byte buff[1024];
09int Count = dataLength/1024+1;
10if(dataLength%1024==0) --Count;
11CFile tFile(_T("C:\\Cache.jpg"), CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
12for (inti=0;i<Count;i++)//会发生阻塞,所以用 了for循环监听
13{
14if (i==Count-1)//最后一次数据
15{
16sockClient.Receive(buff,dataLength-i*1024);
17tFile.Seek(i*1024,CFile::begin);
18tFile.Write(buff,dataLength-i*1024);
19}
20else
21{
22sockClient.Receive(buff,1024);
23tFile.Seek(i*1024,CFile::begin);
24tFile.Write(buff,1024);
25}
26}
27tFile.Close();
28sockClient.Close();

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值