|
在一个WEB应用服务器程序里,专门负责处理Browser客户端的请求,当接收到用户下载文件的请求后,调用一个DLL的函数去文件服务器获取所请求的文件。
文件传输的函数是用Socket实现的。在传第一个文件的时候没问题,当第二个下载请求到来后,WEB服务器调DLL里的函数出错了,
出错的地方在sockcore.cpp
的BOOL CAsyncSocket::AsyncSelect(long lEvent)方法:
ASSERT(pState->m_hSocketWindow != NULL);
查了网上一些帖子,说是多线程调用Socket出的问题,要使用Attach和Detach
来处理。我的Socket调用是封装在一个DLL里的,如下:
请问该如何修改?!!
int getRemoteFile(CString strIP, CString fName,int port)
{
int nRet = 0; // return value
AfxSocketInit(NULL);//should comment this line?
CSocket sockClient;
sockClient.Create();
sockClient.Connect( strIP, port);
int dataLength, cbBytesRet, cbLeftToReceive;
// pointer to buffer for receiving data
// (memory is allocated after obtaining file size)
BYTE* recdData = NULL;
CFile destFile;
CFileException fe;
BOOL bFileIsOpen = FALSE;
// open/create target file that receives the transferred data
if( !( bFileIsOpen = destFile.Open( fName, CFile::modeCreate |
CFile::modeWrite | CFile::typeBinary, &fe ) ) )
{
TCHAR strCause[256];
fe.GetErrorMessage( strCause, 255 );
TRACE( "GetFileFromRemoteSender encountered an error ");
//AfxMessageBox(strCause);
/* you should handle the error here */
nRet = -1;
goto PreReturnCleanup;
}
// get the file's size first
cbLeftToReceive = sizeof( dataLength );
do
{
BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;
cbBytesRet = sockClient.Receive( bp, cbLeftToReceive );
// test for errors and get out if they occurred
if ( cbBytesRet == SOCKET_ERROR || cbBytesRet == 0 )
{
int iErr = ::GetLastError();
//TRACE( "GetFileFromRemoteSite returned a socket error");
/* you should handle the error here */
nRet = -2;
goto PreReturnCleanup;
}
// good data was retrieved, so accumulate
// it with already-received data
cbLeftToReceive -= cbBytesRet;
}
while ( cbLeftToReceive > 0 );
dataLength = ntohl( dataLength );
// now get the file in RECV_BUFFER_SIZE chunks at a time
recdData = new byte[RECV_BUFFER_SIZE];
cbLeftToReceive = dataLength;
do
{
int iiGet, iiRecd;
iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ?
cbLeftToReceive : RECV_BUFFER_SIZE ;
iiRecd = sockClient.Receive( recdData, iiGet );
// test for errors and get out if they occurred
if ( iiRecd == SOCKET_ERROR || iiRecd == 0 )
{
int iErr = ::GetLastError();
//TRACE( "returned a socket error");
CString errMsg;
errMsg.Format("%d",iErr);
/* you should handle the error here */
nRet = -3;
goto PreReturnCleanup;
}
destFile.Write( recdData, iiRecd); // Write it
cbLeftToReceive -= iiRecd;
}
while ( cbLeftToReceive > 0 );
PreReturnCleanup: // labelled "goto" destination
delete[] recdData;
if ( bFileIsOpen )
destFile.Close();
// only close file if it's open (open might have failed above)
sockClient.Detach();//detach 或许没用
sockClient.Close();
return nRet;
}
|
|