Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

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

Posted on 2000-03-08
8
586 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 31

Expert Comment

by:Zoppo
ID: 2599934
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
ID: 2600068
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
ID: 2605608
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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 9

Expert Comment

by:ShaunWilde
ID: 2607236
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
 

Author Comment

by:jayLi
ID: 2612256
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
ID: 2612426
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
ID: 2630487
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
ID: 2630973
Glad to help
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
repeateFront java challenge 31 94
Adapt this command to show who installed 29 111
wait notify demo infinite loop 3 124
sumHeights2  challenge 7 117
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
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.

837 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