socket多文件传输 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败

xuggzu 2010-03-06 03:38:20
服务端接受到客户端请求后,给客户端发送请求的多个文件。编程采用socket api阻塞式。

部分源码:
服务端:
接受客户端请求部分(消息处理函数中):
TRANSSTRUCT *uTrans=new TRANSSTRUCT;
uTrans->m_hWnd=this->m_hWnd;
uTrans->cTransSArr.Copy(sArr);
uTrans->sTransUpPath=this->sUpPath;
uTrans->sTransIP=ip;
uTrans->uTransPort=workport;
HANDLE hThreadFileTCP=::CreateThread(NULL,0,TCPSendFileThreadRecvProc,(LPVOID)uTrans,0,NULL); //启动发送线程
CloseHandle(hThreadFileTCP);

发送线程:
DWORD WINAPI TCPSendFileThreadRecvProc(LPVOID lpParameter)
{
TRANSSTRUCT *uOldTrans=(TRANSSTRUCT *)lpParameter;

FILEHEAD hf;
SOCKADDR_IN addrTarg;
CStringArray cNewUpFileInfo;
CString sNewUpPath,tmpS,sFileName,sIP;
int i=0;

HWND hWnd=uOldTrans->m_hWnd;
cNewUpFileInfo.Copy(uOldTrans->cTransSArr);
sNewUpPath=uOldTrans->sTransUpPath;
addrTarg.sin_family=AF_INET;
addrTarg.sin_port=htons(uOldTrans->uTransPort);
sIP=uOldTrans->sTransIP;
addrTarg.sin_addr.S_un.S_addr=inet_addr(sIP);

uOldTrans->cTransSArr.RemoveAll();
delete uOldTrans;

char *pBuf = new char[4096];

hf.filenum=cNewUpFileInfo.GetSize();
hf.totalfilesize=0;
for(i=0;i<hf.filenum;i++)
{
tmpS=cNewUpFileInfo.GetAt(i);
sFileName=sNewUpPath+"\\"+tmpS;
CFile cfile(sFileName,CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone);
hf.totalfilesize+=cfile.GetLength();
cfile.Close();
}

for(i=0;i<hf.filenum;i++)
{
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET)
{
cNewUpFileInfo.RemoveAll();
tmpS.Format("发送文件到%s时建立套接字失败!",sIP);
char *chErr=new char[tmpS.GetLength()+1];
memset(chErr,0,tmpS.GetLength()+1);
memcpy(chErr,tmpS,tmpS.GetLength());
::PostMessage(hWnd,UM_SENDFILE,0,(LPARAM)chErr);

return 0;
}

if(SOCKET_ERROR==connect(ConnectSocket,(SOCKADDR*)&addrTarg,sizeof(addrTarg)))
{
int nErrCode = GetLastError();
TCHAR errMsg[2048] = {0};
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL,//GetModuleHandle(TEXT("ws2_32.dll")),
nErrCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
errMsg,
sizeof(errMsg)/sizeof(TCHAR),
NULL);
//AfxMessageBox((LPCTSTR)errMsg);//显示错误信息
if(ConnectSocket) closesocket(ConnectSocket);
cNewUpFileInfo.RemoveAll();
tmpS.Format("在发送文件时连接到%s失败![%s]",sIP,errMsg);
char *chErr=new char[tmpS.GetLength()+1];
memset(chErr,0,tmpS.GetLength()+1);
memcpy(chErr,tmpS,tmpS.GetLength());
::PostMessage(hWnd,UM_SENDFILE,0,(LPARAM)chErr);

return 0;
}
CString newFile;
tmpS=cNewUpFileInfo.GetAt(i);
tmpS.Delete(tmpS.Find('|'),tmpS.GetLength()-tmpS.Find('|'));
memcpy(hf.filename,tmpS,MAX_PATH);
newFile.Format("%s\\%s",sNewUpPath,hf.filename);

CFile cfile;
cfile.Open(newFile,CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone);
hf.filesize=cfile.GetLength();

send(ConnectSocket,(char*)&hf,sizeof(hf),0);

DWORD fsize=0;
while(fsize<hf.filesize)
{
UINT dwRead=0;
dwRead=cfile.Read(pBuf,4096);
fsize+=dwRead;
send(ConnectSocket,pBuf,dwRead,0);
}

cfile.Close();
if (ConnectSocket)
{
closesocket(ConnectSocket);
}

}
delete[] pBuf;
cNewUpFileInfo.RemoveAll();

tmpS.Format("发送文件到%s完成!",sIP);
char *chErr=new char[tmpS.GetLength()+1];
memset(chErr,0,tmpS.GetLength()+1);
memcpy(chErr,tmpS,tmpS.GetLength());
::PostMessage(hWnd,UM_SENDFILE,0,(LPARAM)chErr);

return 0;
}

客户端:
接受文件线程是在请求之前开启的:
DWORD WINAPI TCPThreadListenProc(LPVOID lpParameter)
{
CCSLogonClientDlg * dlg=(CCSLogonClientDlg *)lpParameter;
HWND mainWnd=dlg->m_hWnd;
LONGLONG totalrecv=0;
int filenumber=0;
BOOL bRep=FALSE;

SOCKET acceptsocket;
while(1)
{
acceptsocket=accept(listensocket, NULL,NULL );

if (acceptsocket!=SOCKET_ERROR)
{
if(!bRep) dlg->m_cProgress.ShowWindow(SW_SHOWNORMAL);
bRep=TRUE;
filenumber++;
///**************/
if(mainWnd)
{
::PostMessage(mainWnd,UM_RECVFILE,4,0);
}
FILEHEAD headbuf;
memset(&headbuf,0,sizeof(headbuf));
int ret=0;
int current=0;
int needbyte=sizeof(FILEHEAD);
while (current!=sizeof(FILEHEAD)) //收文件信息头(总长度、数量和每次的文件名等)
{
ret=recv(acceptsocket,((char*)(&headbuf))+current,needbyte,0);
if(ret==SOCKET_ERROR)
{
AfxMessageBox("网络错误~");
if (acceptsocket)
{
closesocket(acceptsocket);
acceptsocket=INVALID_SOCKET;
}
break;
}
current+=ret;
needbyte-=ret;
}
char savepath[MAX_PATH];
memset(savepath,0,MAX_PATH);
GetModuleFileName(NULL,savepath,MAX_PATH);
CString savestr=savepath;
int index=savestr.ReverseFind('\\');
savestr=savestr.Left(index+1);
CString namestr=headbuf.filename;
CString fullpath=savestr+namestr;

char filebuf[1000000];
int p=namestr.ReverseFind('\\')+1;
if(p>0)
{
CString sDir=".\\"+namestr.Left(p);
MakeSureDirectoryPathExists(sDir);

}
CFile file(fullpath,CFile::modeCreate|CFile::modeReadWrite);

float per=(float)((totalrecv*100)/headbuf.totalfilesize);
CTime currentttime = CTime::GetCurrentTime();
int presecond= currentttime.GetSecond();
//***********************/

TRY
{
while(TRUE)
{
memset(filebuf,'\0',1000000);
int ret=recv(acceptsocket,filebuf,1000000,0);
if(ret==SOCKET_ERROR)
{
closesocket(acceptsocket);
file.Close();

CFile::Remove(fullpath.GetBuffer(fullpath.GetLength()));
if(mainWnd)
{
::PostMessage(mainWnd,UM_RECVFILE,1,0);//网络问题失败
}
break;
}
if(ret==0)
{
closesocket(acceptsocket);
file.Close();
if(mainWnd)
{
::PostMessage(mainWnd,UM_RECVFILE,2,0);//成功
}
if(filenumber==headbuf.filenum && totalrecv==headbuf.totalfilesize)
{
bRep=FALSE;
dlg->m_cProgress.ShowWindow(SW_HIDE);
dlg->m_cProgress.SetPos(0);
::PostMessage(mainWnd,UM_RECVFILE,5,0);
}

break;
}
if(ret!=SOCKET_ERROR&&ret!=0)
{

totalrecv=totalrecv+ret;
float per=(float)((totalrecv*100)/headbuf.totalfilesize);
dlg->m_cProgress.SetPos((int)(per));
file.SeekToEnd();
file.Write(filebuf,ret);
}
}

}
CATCH( CFileException, e )
{

CString errstr;
errstr.Format("File could not be opened: %d",e->m_cause);
AfxMessageBox(errstr);

}
END_CATCH
}
Sleep(100);
}

return 0;
}

程序在互联网上使用,结果是:有些客户端没有问题,有些客户端在给其传送文件时,服务端会出现"由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。"的错误。现在搞不清是程序哪不合理的缘故还是网络问题,但不管哪个原因,请各位高手给个解决方案,最好有代码。。。。谢谢!!!
...全文
1277 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuggzu 2010-03-06
  • 打赏
  • 举报
回复
呵呵,只是叫客户端,它需要接受服务端发送来的文件。
高手都躲起来了吗?。。。。。。。。。。。。。。。
WizardK 2010-03-06
  • 打赏
  • 举报
回复
没搞懂,客户端里为何有ACCEPT?

18,356

社区成员

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

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