|  | 
 
| In a WEB application server program, it is specifically responsible for handling the browser client's request. When receiving a user's request to download a file, it calls a DLL function to the file server to obtain the requested file. File transfer functions are implemented using Socket. There was no problem when transmitting the first file. When the second download request came, the web server called the function in the DLL.
 
 What went wrong is in sockscore.cpp
 BOOL CAsyncSocket :: AsyncSelect (long lEvent) method:
 
 ASSERT (pState-> m_hSocketWindow! = NULL);
 
 Checked some posts on the Internet, saying that it is a problem with multi-thread calling Socket, use Attach and Detach
 To deal with. My Socket call is encapsulated in a DLL, as follows:
 
 How can I modify it? !! !!
 
 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 may not be useful
 sockClient.Close ();
 
 return nRet;
 }
 | 
 |