Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 618
  • Last Modified:

Assertion Error When Send Data Using CArchive with CSocket/CSocketFile in Multi-thread!!!

Hi, All:

I have a serious problem to send data using a CArchive object with a CSocket object. The data sending process MUST be in a work thread and CArchive objects MUST be used in my data sending client application.

What I did in my code is described / shown as below:

1) Declare and implement my CConnectThread class derived from CWinThread;

2) In my CconnectThread class, there is a CSendSocket object m_sockSend as a data member. The class  

CSendSocket is derived from CSocket class;

3) In my Dialog class, I have a pointer to a CConnectThread object m_pConnectThread as the dialog box

class data member.

4) When the dialog box connects to a server, I created a temporary CConnectThread object to establish a

connection to a server through its data member m_sockSend and then assign it to the dialog box data

member:

// Button "Connect" clicking message handler in MyDlg
void MyDlg::OnConnect()
{
   // Create a thread to handle the connection. The thread is created suspended so that we can
   // set variables in CClientThread before it starts executing.
   CConnectThread* pThread =
        ( CConnectThread* )AfxBeginThread( RUNTIME_CLASS( CConnectThread ), THREAD_PRIORITY_NORMAL
, 0, CREATE_SUSPENDED );

   // Check if the thread object is well created
   if ( pThread )
   {
      // The thread that CSendSocket object lives
      pThread->sockSend.m_pThread = pThread;

      // let the dialog box keep a pointer to the work thread
      m_pConnectThread = pThread;

      // Now start the thread.
      pThread->ResumeThread();
   }

}// MyDlg::OnConnect()


5) In overloaded function InitInstance() of the CConnectThread, SendSocket connects to the server, and

connection was establish successfully. It was comfirmed by checking the server side.

So far, so good.

6) When I attempt to send data to the server by calling m_pConnectThread->sockSend.SendData():

void CSendSocket::SendData( const CString& strSentData )
{
   // Check if the connection has established well
   if( m_bConnected )
   {
      // Create local objects to send message to the server
      CsocketFile    File ( this );
      CArchive        arOut( &File, CArchive::store );      // AN ASSERTION ERROR OCCURS!!!
            
      // Send the message to the server
      arOut << strSentData;

   }// if( m_bConnected )

}// CSendSocket::SendData( void )

AN ASSERT ERROR occurs when code  
CArchive   arOut( &File, CArchive::store );
 was executed.

If follow debugging, the problem points to ASSERT macro in source file SOCKCORE.CPP:

void CAsyncSocket::AssertValid() const
{
      CObject::AssertValid();
      ASSERT( m_hSocket == INVALID_SOCKET
                             || CAsyncSocket::FromHandle(m_hSocket) != NULL);
}

It seems that something wrong with the sockSend. I have been working around but have no idea WHY and HOW

to solve the problem. Please give me your hand if you have any idea about such problem.

Thank you very much in advance!  

JAY
0
jayLi
Asked:
jayLi
  • 4
  • 3
1 Solution
 
ZoppoCommented:
Hi jayLi,

I'm not sure, but MSDN articles ID: Q140527, ID: Q175668, ID: Q193101 tells a bit about problems using sockets in multiple threads (mostly the problem that each thread has its own socket handle map).

perhaps you find some interesting infos there.

hope that helps,

ZOPPO
0
 
ShaunWildeCommented:
it looks like you are trying to send the data from a thread other than the one your socket resides on.

you must pass the data to the other thread (maybe a list of data to be sent protected by a critical section object) and then you must notify the thread that your socket belongs, to send the data (maybe using a post thread message)

eg (pseudo code)

m_pConnectThread->AddDataToList(data);

m_pConnectThread->PostThreadMessage(MM_SENDDATA,0,0L);


CConnectThread::OnSendData(...)
{
while(TRUE==SomeDataToSend())
{
data=GetData();
sockSend.SendData(data):
}
}

HTH

Shaun Wilde

0
 
jayLiAuthor Commented:
Zoppo,

Thank you for your info. I read these documents and they are helpful for solving my problem. Actually, I did my multithread server application as what the document mentioned. But In my client application, I use a CSocket object in a work thread to connect to server and send data. It is different from one in Server side.

Shauwhilde,

Thank you for your idea. As the connected socket in the thread holds the connection to the server, I can not see why it is not good to send data by invoking it directly from the thread object. If a message/message handler is needed, the connected socket is only one to send data anyway.  I am going to try your idea, if anyone has an idea, please let me know. I really want to solve this problem as soon as possible.

Thanks!

JAY
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ShaunWildeCommented:
from which thread were you calling
m_pConnectThread->sockSend.SendData(); ?

Just because you are accessing an object via a CWinThread pointer doesn't mean that you have moved from the original thread to the new thread.

0
 
jayLiAuthor Commented:
From MainThread, I have a call:
m_pConnectThread->sockSend.SendData();

The m_pConnectThread is a data member of dialog box that sends data. It suppose to connect the server and send data. Are you saying that it is not good for sening data? if so, Will message method do the job well?

Thanks!
0
 
ShaunWildeCommented:
yes - that is what I am saying. you are tying to send the data from your dialogs thread and not the thread to which the socket is attached - this is one of the main problems with MFCs CSocket

The posting message method has worked for me in the past however when placing your data in and out of the list of data to send don't forget to protect the list with a criticalsection
0
 
jayLiAuthor Commented:
Shauwhilde:

The problem is solved by the message method that you suggested.

Thank you for your valuable help!

JAY
0
 
ShaunWildeCommented:
Glad to help
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now