Solved

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

Posted on 2000-03-08
8
575 Views
Last Modified: 2013-11-20
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
Comment
Question by:jayLi
  • 4
  • 3
8 Comments
 
LVL 30

Expert Comment

by:Zoppo
Comment Utility
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
 
LVL 9

Accepted Solution

by:
ShaunWilde earned 100 total points
Comment Utility
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
 

Author Comment

by:jayLi
Comment Utility
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
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:jayLi
Comment Utility
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
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
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
 

Author Comment

by:jayLi
Comment Utility
Shauwhilde:

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

Thank you for your valuable help!

JAY
0
 
LVL 9

Expert Comment

by:ShaunWilde
Comment Utility
Glad to help
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now