求助贴?

coolshui 2012-05-09 02:51:57
小弟作为一个网络编程的初学者,现在用WSAAsyncSelect套接字做文件传输的程序。但是接收的文件把一段话重复出现。不知道什么原因。求高手相助。

void CFile_TransferDlg::OnSocket(WPARAM wparam,LPARAM lparam)
{

CString str;
int res;
str=inet_ntoa(comaddr.sin_addr);
if(lparam==FD_READ)
{
recv(comsock,message,100,0);
if(memcmp(message,"RECEIVE1RECEIVE2RECEIVE3",sizeof("RECEIVE1RECEIVE2RECEIVE3"))==0)
{
memset(message,0,100);
str+="向您发送文件";
res=MessageBox(str+",接收OR放弃?","询问",MB_OKCANCEL);
if(res==IDOK)
{
CFile_TransferDlg::OnRecFile();
}
else if(res==IDCANCEL)
{
CFile_TransferDlg::OnDisFile();
}
}
else if(memcmp(message,"MESSAGE",7)==0)
{
memset(message,0,100);
AfxGetApp()->m_pMainWnd->SendMessage(WM_MESSAGE,0,0);
}
}
return;
}


发送函数

char sendtext[100]={0};
CString path,str,str1;
unsigned long len;
unsigned int yushu;
unsigned long num;
send(comsock,"RECEIVE1RECEIVE2RECEIVE3",sizeof("RECEIVE1RECEIVE2RECEIVE3"),0);
LOOP:
recv(comsock,sendtext,100,0);
if(memcmp(sendtext,"NO",sizeof("NO"))==0)
{
LogList.InsertString(-1,"对方拒绝接受文件");
return;
}
else if(memcmp(sendtext,"YES",sizeof("YES"))!=0)
goto LOOP;
else
{
CFileDialog sendfile(true);
if(sendfile.DoModal()==IDOK)
{
path=sendfile.GetPathName();
CFile send_file(path,CFile::modeReadWrite|CFile::typeBinary);
len=send_file.GetLength();
str.Format("%d",len);
str1="START";
str1+=str;
send(comsock,str1.GetBuffer(1),100,0);
num=len/100;
yushu=len%100;
for(unsigned long i=1;i<=num;i++)
{
memset(sendtext,0,100);
send_file.Read(sendtext,100);
send(comsock,sendtext,100,0);

}
if((i==num+1)&&(yushu!=0))
{
memset(sendtext,0,100);
send_file.Read(sendtext,yushu);
send(comsock,sendtext,yushu,0);

}
send_file.Close();
LogList.InsertString(-1,"发送完毕");
}
}
接收函数
CString path,title;
char rectext[100]={0};
char len[50];
unsigned long lenth=0;
unsigned int yushu;
unsigned long num;
CFileDialog savefile(false);
if(savefile.DoModal()==IDOK)
{
path=savefile.GetPathName();
CFile recfile(path,CFile::modeReadWrite|CFile::modeCreate|CFile::typeBinary);
send(comsock,"YES",sizeof("YES"),0);
loop:
recv(comsock,rectext,100,0);
if(memcmp(rectext,"START",sizeof("START")-1)!=0)
goto loop;
else
{
memcpy(len,rectext+5,40);
lenth=atoi(len);
memset(rectext,0,100);
num=lenth/100;
yushu=lenth%100;
Sleep(10);
for(unsigned long i=1;i<=num;i++)
{
memset(rectext,100,0);
(recv(comsock,rectext,100,0);
recfile.Write(rectext,100);

}
if((i==num+1)&&(yushu!=0))
{
memset(rectext,100,0);
recv(comsock,rectext,yushu,0);
recfile.Write(rectext,yushu);

}
LogList.InsertString(-1,"接收完毕");
recfile.Close();
}
}
else if(savefile.DoModal()==IDCANCEL)
{
CFile_TransferDlg::OnDisFile() ;
}
}
...全文
140 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
coolshui 2012-05-09
  • 打赏
  • 举报
回复
我也做过对recv返回值的判断。但是我的recv是在FD_READ之外调用的。接受数据超时和接受缓冲区满无法接受时候返回的都是WSAEWOULDBLOCK。不能尽可能准确的判断。
Eleven 2012-05-09
  • 打赏
  • 举报
回复
判断recv函数的返回值,一般都是循环接收
coolshui 2012-05-09
  • 打赏
  • 举报
回复
那应该怎么发?怎么收?
高手指教呀! 那用异步套接字怎么实现文件传输呀
youngwolf 2012-05-09
  • 打赏
  • 举报
回复
为什么所有网络编程的初学者都这样用:
recv(comsock,message,100,0);
//这里判断message的内容

流式套节字,会出现粘包与分包,你怎么知道你一次recv,一定可以不多不少的收到
RECEIVE1RECEIVE2RECEIVE3
这个字符串?

并不是怎么发,就一定怎么收,绝多数情况下,这种假设都是错误的,可能运气好能对几次。
如果你想怎么发,就怎么收,只能用udp才能搞定。

18,356

社区成员

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

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