socket编程如何发送大文件

xshch111 2013-05-09 04:28:42
最近需要做网络传输的项目,需要通过IP多播实现1M左右的Excel文件在多播组成员之间的传输。
我的发送代码是
if(filedlg.DoModal()==IDOK)//选择了要发送的文件
{
CString filename;
filename=filedlg.GetPathName();
CFile file(filename,CFile::modeRead|CFile::shareDenyWrite);
long count=file.GetLength();//得到文件以字节为单位的大小
char buffer[1024*1024];
int a=file.Read(buffer,count);//读取文件中的内
int nReturnCode = sendto(m_hGroupSocket, buffer, count, 0,
(sockaddr*)&srcaddr, sizeof(sockaddr));
if(nReturnCode == SOCKET_ERROR){
AfxMessageBox("Error in send packets to the network!\n");
return ;
}
file.Close();//发送问文件以后关闭文件
}
要发送的文件500KB左右可是当我发送时sendto()函数的错误代码10040 说是发送的数据包过大 请问对于这样1M左右的文件如何实现分段去发送 接收端如何分段接受,最好有代码参考 ,谢谢大家了
...全文
679 47 打赏 收藏 转发到动态 举报
写回复
用AI写文章
47 条回复
切换为时间正序
请发表友善的回复…
发表回复
xshch111 2013-05-22
  • 打赏
  • 举报
回复
引用 46 楼 u010116861 的回复:
这哥们的结贴率...
不好意思这几天有点事情
随风随恨 2013-05-17
  • 打赏
  • 举报
回复
这哥们的结贴率...
随风随恨 2013-05-15
  • 打赏
  • 举报
回复
偶可不是神马大神,偶是菜鸟的说。。。上面不是给你说了么,excel文件也是文件,发送的时候人家不管的,我只知道读取发送,可能在发送二进制文件的时候需要注意点东西吧,不懂就找高手问呗,呵呵
随风随恨 2013-05-14
  • 打赏
  • 举报
回复
引用 32 楼 xshch111 的回复:
[quote=引用 31 楼 u010116861 的回复:] 简单来说如下: 包头:数据类型,数据大小,文件类型(图片啦,视频啦) 1,定义一个数组,不要太大,10000应该没问题 2,获取文件路径(知道吧) 3,利用while循环(以文件结尾结束)读取文件数据,一次读取你自己定义的数组大小,存入数组,然后发送 4,将存储数据的数组发送出去,并记录发送数据大小 5,判断是否全部发送(比较文件总大小和发送数据大小即可) 大致步骤就这样,以前我从客户端发送视频都没事,另外我是开辟了一个发送线程做的
我的发送函数 if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*800]; int a=file.Read(buffer,count);//读取文件中的内 //当a为零时不就是数据读取完毕么,你判断这个就行 while(a ) { int nReturnCode= sendto(m_hGroupSocket, buffer, count, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { AfxMessageBox("Error in send packets to the network!\n"); return ; } } file.Close();//发送问文件以后关闭文件 } 能不能指导下 如何修改这段代码 实现您说的分包循环发送[/quote] 你的数组是不是太大了?我记得发送buffer默认没那么大的啊。还有就是如果你这个是单个发送线程的话就直接while(true){}就行,没必要判断,你调试下看吧,以前我直接是客户端服务器一起调试发送字节的,呵呵
xshch111 2013-05-14
  • 打赏
  • 举报
回复
引用 31 楼 u010116861 的回复:
简单来说如下: 包头:数据类型,数据大小,文件类型(图片啦,视频啦) 1,定义一个数组,不要太大,10000应该没问题 2,获取文件路径(知道吧) 3,利用while循环(以文件结尾结束)读取文件数据,一次读取你自己定义的数组大小,存入数组,然后发送 4,将存储数据的数组发送出去,并记录发送数据大小 5,判断是否全部发送(比较文件总大小和发送数据大小即可) 大致步骤就这样,以前我从客户端发送视频都没事,另外我是开辟了一个发送线程做的
我的发送函数 if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*800]; int a=file.Read(buffer,count);//读取文件中的内 int nReturnCode= sendto(m_hGroupSocket, buffer, count, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { AfxMessageBox("Error in send packets to the network!\n"); return ; } file.Close();//发送问文件以后关闭文件 } 能不能指导下 如何修改这段代码 实现您说的分包循环发送
随风随恨 2013-05-14
  • 打赏
  • 举报
回复
简单来说如下: 包头:数据类型,数据大小,文件类型(图片啦,视频啦) 1,定义一个数组,不要太大,10000应该没问题 2,获取文件路径(知道吧) 3,利用while循环(以文件结尾结束)读取文件数据,一次读取你自己定义的数组大小,存入数组,然后发送 4,将存储数据的数组发送出去,并记录发送数据大小 5,判断是否全部发送(比较文件总大小和发送数据大小即可) 大致步骤就这样,以前我从客户端发送视频都没事,另外我是开辟了一个发送线程做的
xshch111 2013-05-14
  • 打赏
  • 举报
回复
引用 29 楼 u010116861 的回复:
[quote=引用 14 楼 tiger9991 的回复:] 自定义通信协议还是很有必要的。
同意帮主意见,自己打包自己解析,注意下buffer就行了,不要一次读取数据太大即可[/quote]能不能给点具体的指导啊,如何打包解析,如何循环发送出这些包。一点思路都没有,求大神指点下
随风随恨 2013-05-14
  • 打赏
  • 举报
回复
引用 14 楼 tiger9991 的回复:
自定义通信协议还是很有必要的。
同意帮主意见,自己打包自己解析,注意下buffer就行了,不要一次读取数据太大即可
xshch111 2013-05-14
  • 打赏
  • 举报
回复
引用 26 楼 jinqian_ki 的回复:
想要速度快的话,发送策略,修补策略都会很复杂,不过说起来你那1m的文件太小了,算不上大文件
请问我能否一次性发送大小在1M左右的文件呢?该如何做能否给点提示
xshch111 2013-05-14
  • 打赏
  • 举报
回复
引用 23 楼 yaozhiyong110 的回复:
int nSendBuf=800*1024;//设置为800K setsockopt(m_hGroupSocket,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
我按照您的指点设置了发送缓冲区和接收缓冲区的大小为800K可是发送还是失败 错误代码10040
xshch111 2013-05-14
  • 打赏
  • 举报
回复
引用 43 楼 u010116861 的回复:
引用 42 楼 xshch111 的回复:
[quote=引用 39 楼 xhz8000 的回复:] 我以为是多大的文件! 才1M
很惭愧没做过网络编程 所以发送1M左右的文件对我来说就算是大文件了
兄弟,发张图片都不止四M的好吧~~~[/quote]我发送的是一个Excel文件 没有多大 能不能给点指导 大神
随风随恨 2013-05-14
  • 打赏
  • 举报
回复
引用 42 楼 xshch111 的回复:
引用 39 楼 xhz8000 的回复:
我以为是多大的文件! 才1M
很惭愧没做过网络编程 所以发送1M左右的文件对我来说就算是大文件了
兄弟,发张图片都不止四M的好吧~~~
xshch111 2013-05-14
  • 打赏
  • 举报
回复
引用 39 楼 xhz8000 的回复:
我以为是多大的文件! 才1M
很惭愧没做过网络编程 所以发送1M左右的文件对我来说就算是大文件了
dahaiI0 2013-05-14
  • 打赏
  • 举报
回复
建议用TCP,封装个包头,包含一些文件名,文件长度等信息,发送端读取文件不断发数据,接收端不断接收写入文件,用个变量保存接收的总数据,然后比较下包头里表示文件长度的值是否一样,一样就表示文件接收完整。大文件还可以配合内存映射文件来对文件操作
xshch111 2013-05-14
  • 打赏
  • 举报
回复
引用 38 楼 u010116861 的回复:
[quote=引用 37 楼 xshch111 的回复:] [quote=引用 35 楼 u010116861 的回复:] [quote=引用 34 楼 xshch111 的回复:] [quote=引用 33 楼 u010116861 的回复:] [quote=引用 32 楼 xshch111 的回复:] [quote=引用 31 楼 u010116861 的回复:] 简单来说如下: 包头:数据类型,数据大小,文件类型(图片啦,视频啦) 1,定义一个数组,不要太大,10000应该没问题 2,获取文件路径(知道吧) 3,利用while循环(以文件结尾结束)读取文件数据,一次读取你自己定义的数组大小,存入数组,然后发送 4,将存储数据的数组发送出去,并记录发送数据大小 5,判断是否全部发送(比较文件总大小和发送数据大小即可) 大致步骤就这样,以前我从客户端发送视频都没事,另外我是开辟了一个发送线程做的
我的发送函数 if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*800]; int a=file.Read(buffer,count);//读取文件中的内 //当a为零时不就是数据读取完毕么,你判断这个就行 while(a ) { int nReturnCode= sendto(m_hGroupSocket, buffer, count, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { AfxMessageBox("Error in send packets to the network!\n"); return ; } } file.Close();//发送问文件以后关闭文件 } 能不能指导下 如何修改这段代码 实现您说的分包循环发送[/quote] 你的数组是不是太大了?我记得发送buffer默认没那么大的啊。还有就是如果你这个是单个发送线程的话就直接while(true){}就行,没必要判断,你调试下看吧,以前我直接是客户端服务器一起调试发送字节的,呵呵[/quote]int a=file.Read(buffer,count);//读取文件中的内容,下面用while(true) {}循环发送 只读取一次下面循环发送出去 这样发送的不还是一次读取到的内容吗[/quote] 哦, 不好意思,搞错了,那你循环读取啊大哥,你不循环读取数据当然只能发送第一次读的了[/quote] if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*8]; int count2=1024*8; //int a=file.Read(buffer,count2);//读取文件中的内 int a=0; while(a<count) { int b=file.Read(buffer,count2); a=a+b; int nReturnCode; if(b==count2) nReturnCode= sendto(m_hGroupSocket, buffer, count2, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); else nReturnCode= sendto(m_hGroupSocket, buffer, b, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { int b=WSAGetLastError(); CString str; str.Format("%d",b); MessageBox(str); return ; } } file.Close();//发 }您看我这样写发送函数行不行[/quote] 可以啊,怎么不可以呢,思路正确着呢,如果发送的和总大小一致就说明发送没问题了。建议加断点调试,调试几次你就知道是怎么回事了,呵呵[/quote]那我再接收端如何接收这些数据并将其组合成一个完整的文件呢
xhz8000 2013-05-14
  • 打赏
  • 举报
回复
我以为是多大的文件! 才1M
随风随恨 2013-05-14
  • 打赏
  • 举报
回复
引用 37 楼 xshch111 的回复:
[quote=引用 35 楼 u010116861 的回复:] [quote=引用 34 楼 xshch111 的回复:] [quote=引用 33 楼 u010116861 的回复:] [quote=引用 32 楼 xshch111 的回复:] [quote=引用 31 楼 u010116861 的回复:] 简单来说如下: 包头:数据类型,数据大小,文件类型(图片啦,视频啦) 1,定义一个数组,不要太大,10000应该没问题 2,获取文件路径(知道吧) 3,利用while循环(以文件结尾结束)读取文件数据,一次读取你自己定义的数组大小,存入数组,然后发送 4,将存储数据的数组发送出去,并记录发送数据大小 5,判断是否全部发送(比较文件总大小和发送数据大小即可) 大致步骤就这样,以前我从客户端发送视频都没事,另外我是开辟了一个发送线程做的
我的发送函数 if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*800]; int a=file.Read(buffer,count);//读取文件中的内 //当a为零时不就是数据读取完毕么,你判断这个就行 while(a ) { int nReturnCode= sendto(m_hGroupSocket, buffer, count, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { AfxMessageBox("Error in send packets to the network!\n"); return ; } } file.Close();//发送问文件以后关闭文件 } 能不能指导下 如何修改这段代码 实现您说的分包循环发送[/quote] 你的数组是不是太大了?我记得发送buffer默认没那么大的啊。还有就是如果你这个是单个发送线程的话就直接while(true){}就行,没必要判断,你调试下看吧,以前我直接是客户端服务器一起调试发送字节的,呵呵[/quote]int a=file.Read(buffer,count);//读取文件中的内容,下面用while(true) {}循环发送 只读取一次下面循环发送出去 这样发送的不还是一次读取到的内容吗[/quote] 哦, 不好意思,搞错了,那你循环读取啊大哥,你不循环读取数据当然只能发送第一次读的了[/quote] if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*8]; int count2=1024*8; //int a=file.Read(buffer,count2);//读取文件中的内 int a=0; while(a<count) { int b=file.Read(buffer,count2); a=a+b; int nReturnCode; if(b==count2) nReturnCode= sendto(m_hGroupSocket, buffer, count2, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); else nReturnCode= sendto(m_hGroupSocket, buffer, b, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { int b=WSAGetLastError(); CString str; str.Format("%d",b); MessageBox(str); return ; } } file.Close();//发 }您看我这样写发送函数行不行[/quote] 可以啊,怎么不可以呢,思路正确着呢,如果发送的和总大小一致就说明发送没问题了。建议加断点调试,调试几次你就知道是怎么回事了,呵呵
xshch111 2013-05-14
  • 打赏
  • 举报
回复
引用 35 楼 u010116861 的回复:
[quote=引用 34 楼 xshch111 的回复:] [quote=引用 33 楼 u010116861 的回复:] [quote=引用 32 楼 xshch111 的回复:] [quote=引用 31 楼 u010116861 的回复:] 简单来说如下: 包头:数据类型,数据大小,文件类型(图片啦,视频啦) 1,定义一个数组,不要太大,10000应该没问题 2,获取文件路径(知道吧) 3,利用while循环(以文件结尾结束)读取文件数据,一次读取你自己定义的数组大小,存入数组,然后发送 4,将存储数据的数组发送出去,并记录发送数据大小 5,判断是否全部发送(比较文件总大小和发送数据大小即可) 大致步骤就这样,以前我从客户端发送视频都没事,另外我是开辟了一个发送线程做的
我的发送函数 if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*800]; int a=file.Read(buffer,count);//读取文件中的内 //当a为零时不就是数据读取完毕么,你判断这个就行 while(a ) { int nReturnCode= sendto(m_hGroupSocket, buffer, count, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { AfxMessageBox("Error in send packets to the network!\n"); return ; } } file.Close();//发送问文件以后关闭文件 } 能不能指导下 如何修改这段代码 实现您说的分包循环发送[/quote] 你的数组是不是太大了?我记得发送buffer默认没那么大的啊。还有就是如果你这个是单个发送线程的话就直接while(true){}就行,没必要判断,你调试下看吧,以前我直接是客户端服务器一起调试发送字节的,呵呵[/quote]int a=file.Read(buffer,count);//读取文件中的内容,下面用while(true) {}循环发送 只读取一次下面循环发送出去 这样发送的不还是一次读取到的内容吗[/quote] 哦, 不好意思,搞错了,那你循环读取啊大哥,你不循环读取数据当然只能发送第一次读的了[/quote] if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*8]; int count2=1024*8; //int a=file.Read(buffer,count2);//读取文件中的内 int a=0; while(a<count) { int b=file.Read(buffer,count2); a=a+b; int nReturnCode; if(b==count2) nReturnCode= sendto(m_hGroupSocket, buffer, count2, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); else nReturnCode= sendto(m_hGroupSocket, buffer, b, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { int b=WSAGetLastError(); CString str; str.Format("%d",b); MessageBox(str); return ; } } file.Close();//发 }您看我这样写发送函数行不行
随风随恨 2013-05-14
  • 打赏
  • 举报
回复
这样吧,也别判断a值了,直接while(true)吧
随风随恨 2013-05-14
  • 打赏
  • 举报
回复
引用 34 楼 xshch111 的回复:
[quote=引用 33 楼 u010116861 的回复:] [quote=引用 32 楼 xshch111 的回复:] [quote=引用 31 楼 u010116861 的回复:] 简单来说如下: 包头:数据类型,数据大小,文件类型(图片啦,视频啦) 1,定义一个数组,不要太大,10000应该没问题 2,获取文件路径(知道吧) 3,利用while循环(以文件结尾结束)读取文件数据,一次读取你自己定义的数组大小,存入数组,然后发送 4,将存储数据的数组发送出去,并记录发送数据大小 5,判断是否全部发送(比较文件总大小和发送数据大小即可) 大致步骤就这样,以前我从客户端发送视频都没事,另外我是开辟了一个发送线程做的
我的发送函数 if(filedlg.DoModal()==IDOK) { CString filename; filename=filedlg.GetPathName(); CFile file(filename,CFile::modeRead|CFile::shareDenyWrite); long count=file.GetLength();//得到文件以字节为单位的大小 char buffer[1024*800]; int a=file.Read(buffer,count);//读取文件中的内 //当a为零时不就是数据读取完毕么,你判断这个就行 while(a ) { int nReturnCode= sendto(m_hGroupSocket, buffer, count, 0, (sockaddr*)&srcaddr, sizeof(sockaddr)); if(nReturnCode == SOCKET_ERROR) { AfxMessageBox("Error in send packets to the network!\n"); return ; } } file.Close();//发送问文件以后关闭文件 } 能不能指导下 如何修改这段代码 实现您说的分包循环发送[/quote] 你的数组是不是太大了?我记得发送buffer默认没那么大的啊。还有就是如果你这个是单个发送线程的话就直接while(true){}就行,没必要判断,你调试下看吧,以前我直接是客户端服务器一起调试发送字节的,呵呵[/quote]int a=file.Read(buffer,count);//读取文件中的内容,下面用while(true) {}循环发送 只读取一次下面循环发送出去 这样发送的不还是一次读取到的内容吗[/quote] 哦, 不好意思,搞错了,那你循环读取啊大哥,你不循环读取数据当然只能发送第一次读的了
加载更多回复(26)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧