| |

VerySource

 Forgot password?
 Register
Search
View: 1178|Reply: 7

Help: ASSERT problem when calling Socket in DLL!

[Copy link]

1

Threads

2

Posts

3.00

Credits

Newbie

Rank: 1

Credits
3.00

 China

Post time: 2020-3-15 19:30:02
| Show all posts |Read mode
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;
}
Reply

Use magic Report

0

Threads

30

Posts

22.00

Credits

Newbie

Rank: 1

Credits
22.00

 China

Post time: 2020-7-28 19:00:01
| Show all posts
Add in the function header
AfxManageModuleState
Reply

Use magic Report

0

Threads

2

Posts

3.00

Credits

Newbie

Rank: 1

Credits
3.00

 China

Post time: 2020-7-28 20:15:01
| Show all posts
CAsyncSocket and CSocket need a window object for message processing, so you need to create a CWnd object yourself. For the specific process, you can check the previous posts, someone asked and solved it.
In fact, these two classes are not easy to use, it is recommended that you use Winsock2 API.
Reply

Use magic Report

1

Threads

2

Posts

3.00

Credits

Newbie

Rank: 1

Credits
3.00

 China

 Author| Post time: 2020-8-7 19:00:01
| Show all posts
to:北冥唐

Jiangzi, but I call this DLL for java (through JNI), so...
It seems to be difficult to create CWnd objects...
How to use Winsock2 API? Please give a code example
Reply

Use magic Report

0

Threads

24

Posts

19.00

Credits

Newbie

Rank: 1

Credits
19.00

 China

Post time: 2020-8-8 15:15:01
| Show all posts
Socket API? You can read "Windows Network Programming"
Reply

Use magic Report

0

Threads

7

Posts

7.00

Credits

Newbie

Rank: 1

Credits
7.00

 China

Post time: 2020-8-8 16:00:01
| Show all posts
CAsyncSocket and CSocket are not thread safe
Reply

Use magic Report

0

Threads

2

Posts

3.00

Credits

Newbie

Rank: 1

Credits
3.00

 China

Post time: 2020-8-16 14:15:01
| Show all posts
Just create an invisible window, because it is only used for message processing.
toyexilove:
The thread safety of CAsyncSocket and CSocket is achieved through CWnd for message processing.
Reply

Use magic Report

0

Threads

2

Posts

3.00

Credits

Newbie

Rank: 1

Credits
3.00

 China

Post time: 2020-8-16 14:45:01
| Show all posts
I have encountered similar problems before, using CAsyncSocket and CSocket classes will cause exceptions, and finally solved the problem with the winsock socket API.
Reply

Use magic Report

You have to log in before you can reply Login | Register

Points Rules

Contact us|Archive|Mobile|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

Quick Reply To Top Return to the list