下面是我的文件传送的函数代码,为什么在接收了大概28.7M之后就停止了,也不见线程退出。请指教
UINT ReceiveDataThread(LPVOID lpParam)
{ CJIMDlg *pDlg=(CJIMDlg *)lpParam;
CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"所有文件 (*.*)|*.*||");
while(dlg.DoModal()!=IDOK)
{
AfxMessageBox("选择文件出错,请重新选择!");
}
SOCKET sockRecv;
SOCKADDR_IN fileServerAddr;
fileServerAddr.sin_family=AF_INET;
fileServerAddr.sin_port=htons(5000);
fileServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1"); sockRecv=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
while(connect(sockRecv,(SOCKADDR) *&fileServerAddr,sizeof(SOCKADDR_IN)))
{
Sleep(50);
} CString str;
str=dlg.GetPathName();
CFile file;
file.Open(str,CFile::modeCreate|CFile::modeWrite);
BOOL bFileFail=FALSE;
UINT uiLength=pDlg->m_nFileLen;//文件的真实长度
int iBufSize = 2048;
int iSize=iBufSize;
LPBYTE pBuf= new BYTE[iBufSize];
int iNumByte;
UINT uiTotal=0;
while(uiTotal<uiLength)
{
int iEnd=0;
if(pDlg->m_bRecvEnd)
{
AfxMessageBox("接收端终止");
goto ExitLable2;
}
iNumByte=send(sockRecv,(const char *)&iEnd,sizeof(int),0);
if(iNumByte == SOCKET_ERROR)
{
AfxMessageBox("接收信号错误!");
goto ExitLable2;
}
if(iEnd==1)
{
AfxMessageBox("发送端终止!");
goto ExitLable2;
} if((int)(uiLength - uiTotal) < iBufSize)
iSize = uiLength - uiTotal;
int iCount=0;
while(iCount<iSize)
{
iNumByte = recv(sockRecv,(char *)pBuf, (iSize-iCount),0);
//iNumByte = recv(sockRecv,(char *)pBuf, iSize,0);
if(iNumByte == SOCKET_ERROR)
{
AfxMessageBox("接收错误!");
goto ExitLable2;
}
iCount+=iNumByte;
file.Write(pBuf, iNumByte);
}
uiTotal += iCount;//以实际接收字节为准
pDlg->m_progress.SetPos(int(((double)uiTotal/uiLength)*100)); }
AfxMessageBox("接收文件成功!");
bFileFail=TRUE;
ExitLable2:
pDlg->m_bRecvRun=FALSE;
delete[] pBuf;
file.Close();
//文件接收失败,则删除接收文件
if(!bFileFail)
{
CFile::Remove( str );
}
closesocket(sockRecv);
pDlg->m_progress.SetPos(0);
return 0;
}
UINT ReceiveDataThread(LPVOID lpParam)
{ CJIMDlg *pDlg=(CJIMDlg *)lpParam;
CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"所有文件 (*.*)|*.*||");
while(dlg.DoModal()!=IDOK)
{
AfxMessageBox("选择文件出错,请重新选择!");
}
SOCKET sockRecv;
SOCKADDR_IN fileServerAddr;
fileServerAddr.sin_family=AF_INET;
fileServerAddr.sin_port=htons(5000);
fileServerAddr.sin_addr.s_addr=inet_addr("127.0.0.1"); sockRecv=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
while(connect(sockRecv,(SOCKADDR) *&fileServerAddr,sizeof(SOCKADDR_IN)))
{
Sleep(50);
} CString str;
str=dlg.GetPathName();
CFile file;
file.Open(str,CFile::modeCreate|CFile::modeWrite);
BOOL bFileFail=FALSE;
UINT uiLength=pDlg->m_nFileLen;//文件的真实长度
int iBufSize = 2048;
int iSize=iBufSize;
LPBYTE pBuf= new BYTE[iBufSize];
int iNumByte;
UINT uiTotal=0;
while(uiTotal<uiLength)
{
int iEnd=0;
if(pDlg->m_bRecvEnd)
{
AfxMessageBox("接收端终止");
goto ExitLable2;
}
iNumByte=send(sockRecv,(const char *)&iEnd,sizeof(int),0);
if(iNumByte == SOCKET_ERROR)
{
AfxMessageBox("接收信号错误!");
goto ExitLable2;
}
if(iEnd==1)
{
AfxMessageBox("发送端终止!");
goto ExitLable2;
} if((int)(uiLength - uiTotal) < iBufSize)
iSize = uiLength - uiTotal;
int iCount=0;
while(iCount<iSize)
{
iNumByte = recv(sockRecv,(char *)pBuf, (iSize-iCount),0);
//iNumByte = recv(sockRecv,(char *)pBuf, iSize,0);
if(iNumByte == SOCKET_ERROR)
{
AfxMessageBox("接收错误!");
goto ExitLable2;
}
iCount+=iNumByte;
file.Write(pBuf, iNumByte);
}
uiTotal += iCount;//以实际接收字节为准
pDlg->m_progress.SetPos(int(((double)uiTotal/uiLength)*100)); }
AfxMessageBox("接收文件成功!");
bFileFail=TRUE;
ExitLable2:
pDlg->m_bRecvRun=FALSE;
delete[] pBuf;
file.Close();
//文件接收失败,则删除接收文件
if(!bFileFail)
{
CFile::Remove( str );
}
closesocket(sockRecv);
pDlg->m_progress.SetPos(0);
return 0;
}
解决方案 »
- 不太懂PeekMessage
- OpenGL 光源、颜色问题
- 我的程序有内存泄漏,可是boundschecker没有指明具体的位置,它给出的信息如下,如何通过这些定位到我程序的具体位置?
- 为了实现远程桌面控制,如何高效率传输屏幕画面?我正着急呢!高手请指点啊!!!
- 为什么98可以,2000不行
- 请教:在Opengl中如何实现用鼠标画直线?
- 帮个忙!(送100分)
- 如何在程序中得到当前鼠标是否为按下状态?
- 如何较快地熟悉mfc的类库
- 救命啊,救命啊,只要你在VC中用过ADO,就能胜造7级浮屠了。分不够了,以后肯定补上
- 怎样在选择目录对话框中设定初始目录?
- GPRS 的拨号程序 还是使用RAS系的函数吗
如果把两端缓冲区都改大为两倍,就可以接收57.4M
if(iNumByte == SOCKET_ERROR)
{
AfxMessageBox("接收信号错误!");
goto ExitLable2;
}
大容量的数据发送send()会产生WSAEWOULDBLOCK错误,但是并不代表SOCKET就不能发送了!
int iError = WSAGetLastError ();
if ( iError == WSAEWOULDBLOCK )
{
// 处理!重发数据
}
文件的下载我也在做,目前多用户,大容量的数据下载已经可以实现。我在MFC下编程使用的IO模型是WSAAsyncSelect()
if ( iError == WSAEWOULDBLOCK )
{
// 处理!重发数据----> 这里不用处理了吧?直接等FD_WRITE消息再继续发
}
if (! len)
{
error...
}if (len < 0)
{
if (WSAGetLastError() != WSAWOULDBLOCK)
{
error...
} message ... 发送缓冲区满所以没有发送成功,之后就会收到 FD_WRITE
}
应用程序想接收有关是否可写的同志,以便写入数据
可以把send放在这里,就不用自己来处理大量的WSAWOULDBLOCK错误了