socket 大文件传输丢失数据

wangshuiqing 2009-10-17 03:31:14
最近刚接触socket编程,使用TCP协议,阻塞式的socket点对点传输文件。当服务器和客户端都运行在一台电脑上,多大的文件都没问题(我最大试过700多兆的),但是把客户端放到另一个电脑上运行时,稍微大一点的文件只能传5K左右,也没有任何异常,求高手帮忙解答一下,问题可能出在哪里
服务器端程序:
void CPPServerDlg::OnBtnsendfile()
{
// TODO: Add your control notification handler code here
UpdateData(true);
CFile myFile;
if(!myFile.Open(m_filename, CFile::modeRead | CFile::typeBinary))
{
AfxMessageBox("文件不存在!",MB_OK|MB_ICONERROR);
return;
}
SOCKET_STREAM_FILE_INFO StreamFileInfo;
WIN32_FIND_DATA FindFileData; //记载当前文件的基本信息
FindClose(FindFirstFile(m_filename,&FindFileData)); //把文件信息放在了FindFileData
memset(&StreamFileInfo,0,sizeof(SOCKET_STREAM_FILE_INFO));
strcpy(StreamFileInfo.szFileTitle,myFile.GetFileTitle());
StreamFileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
StreamFileInfo.ftCreationTime = FindFileData.ftCreationTime;
StreamFileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
StreamFileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
StreamFileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
StreamFileInfo.nFileSizeLow = FindFileData.nFileSizeLow;
//发送文件基本信息
send(g_hAcceptSocket,(const char *)&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO),0);
UINT dwRead=0;
UINT dw=0;
byte* data = new byte[1024];
int ret=0;

while(true)
{
dw=myFile.Read(data,1024);
if (dw<1024)
{
if ((send(g_hAcceptSocket,(char*)data,dw,0))==SOCKET_ERROR)
{
AfxMessageBox("发送文件失败!");
}
break;
}
ret=send(g_hAcceptSocket,(const char*)data,1024,0);
if (ret==0)
{
break;
}
if (ret==SOCKET_ERROR)
{
break;
}
}

myFile.Close();
delete []data;
AfxMessageBox("发送完毕!");
}

客户端程序:

UINT dwRecv = 0;
byte* data = new byte[1024];
while(TRUE)
{
memset(data,0,1024);
dwRecv=recv(m_hSocket,(char*)data,1024,0);
if (dwRecv<1024)
{
destFile.Write(data,dwRecv);
break;
}
if (dwRecv==0)
{
break;
}
else if (dwRecv==SOCKET_ERROR)
{
break;
}
destFile.Write(data,dwRecv);
}
SetFileTime((HANDLE)destFile.m_hFile,&StreamFileInfo.ftCreationTime,
&StreamFileInfo.ftLastAccessTime,&StreamFileInfo.ftLastWriteTime);
destFile.Close();
delete []data;
SetFileAttributes(StreamFileInfo.szFileTitle,StreamFileInfo.dwFileAttributes);
closesocket(m_hSocket);
AfxMessageBox("接收完毕!");

连接部分的代码省略
...全文
444 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangshuiqing 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 oyster2008 的回复:]
引用 7 楼 wangshuiqing 的回复:
引用 6 楼 oyster2008 的回复:
发送文件之前先把文件的字节数传递过去,客户端根据字节数在一个循环中接收数据

我要传送的文件比较大,int型的文件字节数最大不是65535字节吗,也就是65K左右,大文件该怎么传呢

65536是无符号short的最大值,4字节的unsigned int包含的文件长度是4GB,即使超过这个数,也可以使用8字节把文件长度传递过去的
[/Quote]

文件大小是以高低两个双字分别保存的,该怎么将两个DWORD转换成一个ULONG呢?
wangshuiqing 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 jourbin 的回复:]
客户端程序:

        UINT dwRecv = 0;
byte* data = new byte[1024];
while(TRUE)
{
memset(data,0,1024);
dwRecv=recv(m_hSocket,(char*)data,1024,0);
if (dwRecv <1024)
{
destFile.Write(data,dwRecv);
break;
}

怎么就退出接收了呢??????除非recv返回0或SOCKET_ERROR才退出
(因为你发送是发送1024,但是可能网络慢,接收端收了n次才收满你的1024)

[/Quote]
你的意思是接收1024字节的时候也要循环接收是吗?好的,我试试
jourbin 2009-10-17
  • 打赏
  • 举报
回复
客户端程序:

UINT dwRecv = 0;
byte* data = new byte[1024];
while(TRUE)
{
memset(data,0,1024);
dwRecv=recv(m_hSocket,(char*)data,1024,0);
if (dwRecv <1024)
{
destFile.Write(data,dwRecv);
break;
}


怎么就退出接收了呢??????除非recv返回0或SOCKET_ERROR才退出
(因为你发送是发送1024,但是可能网络慢,接收端收了n次才收满你的1024)
yc20050923 2009-10-17
  • 打赏
  • 举报
回复
谢谢
学习了
pcboyxhy 2009-10-17
  • 打赏
  • 举报
回复
send返回值是什么?
send能保证实际发送字节跟你需要的一样吗?
wangshuiqing 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 oyster2008 的回复:]
发送文件之前先把文件的字节数传递过去,客户端根据字节数在一个循环中接收数据
[/Quote]
小文件我也试过先把文件大小传递过去,然后根据字节数循环接收,同样失败,关键问题是:不管文件多大,只要客户端和服务器在一台电脑上,就没问题,放到不同电脑上运行,就失败
oyster2008 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wangshuiqing 的回复:]
引用 6 楼 oyster2008 的回复:
发送文件之前先把文件的字节数传递过去,客户端根据字节数在一个循环中接收数据

我要传送的文件比较大,int型的文件字节数最大不是65535字节吗,也就是65K左右,大文件该怎么传呢
[/Quote]
65536是无符号short的最大值,4字节的unsigned int包含的文件长度是4GB,即使超过这个数,也可以使用8字节把文件长度传递过去的
wangshuiqing 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 oyster2008 的回复:]
发送文件之前先把文件的字节数传递过去,客户端根据字节数在一个循环中接收数据
[/Quote]
我要传送的文件比较大,int型的文件字节数最大不是65535字节吗,也就是65K左右,大文件该怎么传呢
oyster2008 2009-10-17
  • 打赏
  • 举报
回复
发送文件之前先把文件的字节数传递过去,客户端根据字节数在一个循环中接收数据
wangshuiqing 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lklwlklw 的回复:]
是的
[/Quote]
这个结构体中,除了这些数据还放些什么呢?我的文件信息已经提前发送了,而且也成功了。还有,发送结构体就不会丢失了吗?
很奇怪,我的while循环好像是意外终止了,每次不管什么格式的文件总是发送5K左右就停止,是不是有什么其他的因素终止传输了呢?
我把360关了之后,传输的字节量回答一些,不知如何让解答
lklwlklw 2009-10-17
  • 打赏
  • 举报
回复
是的
wangshuiqing 2009-10-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lklwlklw 的回复:]
发送结构体
[/Quote]
1楼能麻烦您说清楚一些吗?是把每次读到的字节流封装到结构体中吗
qingchunzhe 2009-10-17
  • 打赏
  • 举报
回复
强!
lklwlklw 2009-10-17
  • 打赏
  • 举报
回复
发送结构体

18,356

社区成员

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

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