MFC大文件传输「建议收藏」

MFC大文件传输「建议收藏」MFC大文件传输MFC大文件传输核心思想(C/C++程序员之家自己研究的,请大家指出不当之处,以便更正):首先先给下CSDN上论坛对TCP大文件传输的讨论:TCP发送端速度过快,有可能造成堵塞,发送缓冲区满之后就会丢数据,然后就造成数据不准确了。解决方法一、设置发送缓冲区成更大的值(不提倡)。解决方法二、使用确认包,每次只发一个小包,客户端收到后向服务端发“确认”反馈

MFC大文件传输


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

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

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

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

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

大文件传输结构体模型

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

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

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

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

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

服务器端:

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

客户端:

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/10791.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注