读书人

DLL中调用Socket出现ASSERT有关问题

发布时间: 2012-01-26 19:40:46 作者: rapoo

求助:DLL中调用Socket出现ASSERT问题!
在一个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;
}




[解决办法]
创建一个不可见的窗口即可,因为只是用它做消息处理。
to ouyh12345() :
CAsyncSocket和CSocket的线程安全是通过CWnd做消息处理实现的。
[解决办法]
我以前也遇到过类似问题,使用CAsyncSocket和CSocket类都会出异常,最后还是用winsock套接字的api解决的问题.

读书人网 >VC/MFC

热点推荐