SOCKET recv接收数据不完整!

ang3659467 2010-10-08 04:11:46
发送端:
DWORD dwRead=0;
char ch[4096];
do
{
dwRead=file.Read(ch,4096);
if(dwRead!=0)
send(nSock,ch,dwRead,0);
}
while(dwRead>0);
file.Close();

接收端:

char ch[4096];
do
{
memset(ch,0,4096);
if(file.GetLength()==u2.szfile) //u2.szfile 是文件长度
break;
get=recv(sockConn,ch,4096,0);
if(get!=0)
file.Write(ch,get);
}
while(get!=0);

本机测试,多线程里发送多个文件,接收端时不时出现数据接收不完整情况。不是比原来大了就是小了。打开接收到了文件提示数据不完整无法打开。单个文件发送出错几率就很小。
错在哪里,求助!
...全文
1363 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 lijianli9 的回复:]
循环发送leng长度的数据,循环接收leng的数据。
[/Quote]

UP
lijianli9 2010-10-09
  • 打赏
  • 举报
回复
循环发送leng长度的数据,循环接收leng的数据。
mayudong1 2010-10-09
  • 打赏
  • 举报
回复
回复于:2010-10-09 03:10:55 夜猫子

还有一个可能是发送的太快了,可能发送缓冲满了,这个时候send调用可能会失败

发送的时候应该用select查看一下该socket是否可写,如果可写再调用send发送
coolcoffee4051982 2010-10-09
  • 打赏
  • 举报
回复
每次发送完sleep(10)
mxdzhangyang 2010-10-09
  • 打赏
  • 举报
回复
这个大概是粘包的问题吧 。。自己去找找文章看看 。。。
liwu12345 2010-10-09
  • 打赏
  • 举报
回复
建议 加上数据长度校验,还有你接受端 接受的数据 !=0 就结束 很有问题
ang3659467 2010-10-09
  • 打赏
  • 举报
回复
按照 mayudong1 说法:

代码改为
ULONGLONG FileLen=0;
UINT uRead=0;
int Rint;
char ch[4096];
do
{
memset(ch,0,4096);
uRead=file.Read(ch,4096);
FileLen+=uRead;
if(uRead>0)
Rint=send(nSock,ch,uRead,0);
if(Rint!=uRead && uRead>0)
{
file.Seek(FileLen-uRead+Rint,CFile::begin);
}
}
while(uRead>0);


还是出现个别文件接收不完整,什么原因呢????
会不会是同时发生多个文件问题?
looklzg1108 2010-10-09
  • 打赏
  • 举报
回复
个人建议吧:要想文件或者数据传输得准确,最还还是采用握手协议,每次发送后,接收端返回接收信息,然后再发送。。。
charles_y 2010-10-09
  • 打赏
  • 举报
回复
发送端的问题,发送完需要根据send的返回值来判断发送成功没有,如果成功发送了多少,如果发送出去的数据长度跟自己预想的长度(即实际要发送的长度)不一致的话,需要把剩下的数据重新发送。
ang3659467 2010-10-08
  • 打赏
  • 举报
回复
接收端不是也要做相应调整吗?





[Quote=引用 14 楼 mayudong1 的回复:]

发送完了之后,把发送的数据长度和从文件中读出的数据长度比较一下,如果不一样,调整一下文件指针,使下次读出来的数据是紧连着已经发送了的数据
[/Quote]
xgPaul 2010-10-08
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 ang3659467 的回复:]
引用 11 楼 mayudong1 的回复:

举个例子吧
文件内容是1234567890
第一次读文件读出12345
但是发送的时候send的返回值是3,说明只发送了3个字节,即只发送了123

然后进入下次循环
读文件,读出67890
发送67890

这时候接收方接收到的东西是12367890
这不是出错了吗?
循环发送。。。

int CSendWork::SendData(char pBuf[],int iLength) // 发送数据
{
int nLeft=iLength;
int nIndex=0;
BOOL bResult=TRUE;
while (nLeft > 0)
{
int nRet=::send(m_socket,pBuf+nIndex,nLeft,0);
if (SOCKET_ERROR == nRet || WSAETIMEDOUT ==nRet || 0 == nRet)
{
int err=WSAGetLastError();
TRACE1("socket send data error is %d",err);
TRACE0("socket send data error");
bResult=FALSE;
break;
}
nIndex += nRet;
nLeft -= nRet;
}
return bResult;

}





怎么解决??
[/Quote]
mayudong1 2010-10-08
  • 打赏
  • 举报
回复
发送完了之后,把发送的数据长度和从文件中读出的数据长度比较一下,如果不一样,调整一下文件指针,使下次读出来的数据是紧连着已经发送了的数据
ang3659467 2010-10-08
  • 打赏
  • 举报
回复
照你的说法,发送端发送数据长度 要跟 接收端 收到长度一样时才不会出错!
ang3659467 2010-10-08
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 mayudong1 的回复:]

举个例子吧
文件内容是1234567890
第一次读文件读出12345
但是发送的时候send的返回值是3,说明只发送了3个字节,即只发送了123

然后进入下次循环
读文件,读出67890
发送67890

这时候接收方接收到的东西是12367890
这不是出错了吗?
[/Quote]



怎么解决??
mayudong1 2010-10-08
  • 打赏
  • 举报
回复
举个例子吧
文件内容是1234567890
第一次读文件读出12345
但是发送的时候send的返回值是3,说明只发送了3个字节,即只发送了123

然后进入下次循环
读文件,读出67890
发送67890

这时候接收方接收到的东西是12367890
这不是出错了吗?
ang3659467 2010-10-08
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 mayudong1 的回复:]

没人理会我说的吗?
[/Quote]

do
{
dwRead=file.Read(ch,4096);
if(dwRead!=0)
send(nSock,ch,dwRead,0);
}
while(dwRead>0);


这里的send不一定会把dwRead长度的数据全部发送出去的,有可能发送的会比它少
这时候再继续读文件,发送,就会少一部分数据

我在接收端这样写:
get=recv(sockConn,ch,4096,0);
if(get!=0)
file.Write(ch,get);

看不出有什么问题啊???
mayudong1 2010-10-08
  • 打赏
  • 举报
回复
没人理会我说的吗?
stone1116 2010-10-08
  • 打赏
  • 举报
回复
看不出来
ang3659467 2010-10-08
  • 打赏
  • 举报
回复
#4
通常while里添加Sleep能暂时解决问题,貌似和socket缓冲区有关

这样的话传输速度大减。。
ang3659467 2010-10-08
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 stjay 的回复:]

多线程公用一个socket?还是每线程单独一个?
通常while里添加Sleep能暂时解决问题,貌似和socket缓冲区有关
[/Quote]

每个线程用一个socket
加载更多回复(5)

18,363

社区成员

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

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