Hauptseite | Klassenhierarchie | Alphabetische Liste | Auflistung der Klassen | Auflistung der Dateien | Klassen-Elemente

# TCPIPCommReceive.cpp

    00001 //*****************************************************************************
    00002 // project   : ANALYTICA Class Library
    00003 // part      : Communication class for simple TCP/IP
    00004 // file name : TCPIPCommReceive.h
    00005 // version   : $Id: TCPIPCommReceive.cpp,v 1.7 2001/07/17 06:55:14 AxelSchmidt Exp $
    00006 // author    : Udo Weber
    00007 // platform  : MS VC++ 6.0
    00008 //
    00009 //-----------------------------------------------------------------------------
    00010 // Description:
    00011 // =============
    00012 // implementation of the class CTCPIPComm to encapsulate simple TCP/IP
    00013 // communications
    00014 // Part : Receiving of messages
    00015 //
    00016 //-----------------------------------------------------------------------------
    00017 // Revisionhistory:
    00018 // $Log: TCPIPCommReceive.cpp,v $
    00019 // Revision 1.7  2001/07/17 06:55:14  AxelSchmidt
    00020 // class destructor hangs if Thead is not already started
    00021 //
    00022 // Revision 1.6  2001/07/09 14:53:19  IngoFroehlich
    00023 // Destruction modified
    00024 //
    00025 // Revision 1.5  2001/07/06 05:40:25  AxelSchmidt
    00026 // File-Header geändert
    00027 //
    00028 // Revision 1.4  2001/07/05 16:17:58  IngoFroehlich
    00029 // receive now always byte-wise form socket
    00030 //
    00031 // 20.07.1998 UWe  Some bug fixes
    00032 // 20.04.1998 UWe  first version
    00033 //*****************************************************************************
    00034
    00035 //---- includes ---------------------------------------------------------------
    00036 #include "stdafx.h"
    00037
    00038 #include "TCPIPCommReceive.h"
    00039
    00040 //---- defines/const ----------------------------------------------------------
    00041
    00042
    00043
    00044 //---- classes -----------------------------------------------------------------
    00045
    00046
    00047 //******************************************************************************
    00048 // Methods of class 'CTCPIPCommReceive'
    00049 //******************************************************************************
    00050
    00051 // Static attributes and operations
    00052
    00053
    00054 //------------------------------------------------------------------------------
    00055 // Description:
    00056 //   Constructs the class CTCPIPCommConnect and creates a thread for the connection
    00057 //   establishment
    00058 //
    00059 // Input:
    00060 //   MaxRecvBufferLen   :  Maximum length for receiving messages
    00061 //
    00062 // Output: ----
    00063 //
    00064 // Return: ----
    00065 //
    00066 //------------------------------------------------------------------------------
    00067 CTCPIPCommReceive::CTCPIPCommReceive( const long  MaxRecvBufferLen )
    00068 {
    00069     m_pRecvBuffer             = NULL;
    00070     m_ThreadHandle            = NULL;
    00071     m_hEventTerminate         = NULL;
    00072     m_hEventTerminateFinished = NULL;
    00073     m_hEventStartReceiving    = NULL;
    00074
    00075     // if no Bufferlen is specified, the InitializeClass function has to be called by the derived class
    00076    if ( MaxRecvBufferLen > 0 )
    00077    {
    00078       InitializeClass( MaxRecvBufferLen );
    00079    }
    00080 }
    00081
    00082 //------------------------------------------------------------------------------
    00083 // Description:
    00084 //   Initializes the basic class object, can bei called by the derived class, if
    00085 //   the constructed with parameter -1.
    00086 //
    00087 // Input:
    00088 //   MaxRecvBufferLen   :  Maximum length for receiving messages
    00089 //
    00090 // Output: ----
    00091 //
    00092 // Return: ----
    00093 //
    00094 //------------------------------------------------------------------------------
    00095 void CTCPIPCommReceive::InitializeClass( const long MaxRecvBufferLen )
    00096 {
    00097    if ( m_pRecvBuffer != NULL )
    00098    {
    00099       return;  // Initialization already done, ignore call
    00100    }
    00101
    00102    m_Terminating      = false;
    00103    m_MaxRecvBufferLen = MaxRecvBufferLen;
    00104    m_pRecvBuffer      = new char[m_MaxRecvBufferLen];
    00105
    00106
    00107    // Create the Semaphore(s) for the child (receive) thread
    00108    m_hEventTerminate         = CreateEvent( NULL,               // Security Attributes
    00109                                             FALSE,              // Automatic Reset
    00110                                             FALSE,              // Initial to non signaled
    00111                                             NULL );             // Name of Semaphore
    00112    m_hEventTerminateFinished = CreateEvent( NULL,               // Security Attributes
    00113                                             FALSE,              // Automatic Reset
    00114                                             FALSE,              // Initial to non signaled
    00115                                             NULL );             // Name of Semaphore
    00116    m_hEventStartReceiving    = CreateEvent( NULL,               // Security Attributes
    00117                                             FALSE,              // Automatic Reset
    00118                                             FALSE,              // Initial to non signaled
    00119                                             NULL );             // Name of Semaphore
    00120
    00121    // Create the receive thread
    00122    m_ThreadHandle = CreateThread( NULL,                         // Security Attributes
    00123                                   0,                            // Default Stack size
    00124                                   (LPTHREAD_START_ROUTINE)RecvThread, // Thread function
    00125                                   this,                         // Pointer to this class
    00126                                   0,                            // Thread starts immediatly
    00127                                   &m_ThreadID );                 // Returns the Thread ID
    00128 }
    00129
    00130 //------------------------------------------------------------------------------
    00131 // Description:
    00132 //   Destructs the CTCPIPCommConnect class
    00133 //
    00134 // Input:  ----
    00135 //
    00136 // Output: ----
    00137 //
    00138 // Return: ----
    00139 //
    00140 //------------------------------------------------------------------------------
    00141 CTCPIPCommReceive::~CTCPIPCommReceive()
    00142 {
    00143     m_Terminating = TRUE;
    00144
    00145     // Stop the receive thread
    00146     SetEvent( m_hEventTerminate );
    00147
    00148     // wait until connect thread has terminated
    00149     if ( m_ThreadHandle  != NULL )   //ASc, 17.07.2001, wait, if Thread is started
    00150     {
    00151       WaitForSingleObject( m_hEventTerminateFinished, INFINITE );
    00152
    00153       CloseHandle( m_ThreadHandle );
    00154     }
    00155     CloseHandle( m_hEventTerminate );
    00156     CloseHandle( m_hEventTerminateFinished );
    00157     CloseHandle( m_hEventStartReceiving );
    00158
    00159     m_Terminating = FALSE;
    00160
    00161     delete [] m_pRecvBuffer;
    00162 }
    00163
    00164
    00165 //------------------------------------------------------------------------------
    00166 // Description:
    00167 //   Performs the general initialization of the class parameters
    00168 //
    00169 // Input:
    00170 //    Socket           : The socket handle to be used for the communication
    00171 //
    00172 // Output: ----
    00173 //
    00174 // Return: ----
    00175 //
    00176 //------------------------------------------------------------------------------
    00177 void CTCPIPCommReceive::Initialize( const SOCKET       Socket )
    00178 {
    00179    // Save some parameters
    00180    m_Socket = Socket;
    00181 }
    00182
    00183
    00184 //------------------------------------------------------------------------------
    00185 // Description:
    00186 //   Start the "real" receiving part of this thread
    00187 //
    00188 // Input:  ----
    00189 //
    00190 // Output: ----
    00191 //
    00192 // Return:
    00193 //    TRUE if function call was successful
    00194 //
    00195 //------------------------------------------------------------------------------
    00196 bool CTCPIPCommReceive::StartReceiving( void )
    00197 {
    00198     // Indicate the receive thread to start receiving data
    00199    if ( ! SetEvent( m_hEventStartReceiving ) )
    00200    {
    00201       m_LastSocketError = GetLastError();
    00202       return false;
    00203    }
    00204
    00205    return true;
    00206 }
    00207
    00208
    00209
    00210
    00211 //------------------------------------------------------------------------------
    00212 // Description:
    00213 //   Thread starting routine
    00214 //
    00215 // Input:
    00216 //    pClass           : Pointer to the local class
    00217 //
    00218 // Output: ----
    00219 //
    00220 // Return: ----
    00221 //
    00222 //------------------------------------------------------------------------------
    00223 void CTCPIPCommReceive::RecvThread( CTCPIPCommReceive  *pClass )
    00224 {
    00225    long     DataLen = 0 ;
    00226    long     RecvBytes;
    00227    HANDLE   Events[2];
    00228
    00229
    00230    Events[ 0 ] = pClass->m_hEventStartReceiving;
    00231    Events[ 1 ] = pClass->m_hEventTerminate;
    00232
    00233
    00234    // Loop until thread should be terminated
    00235    // 1. Wait for the command to start receiving or to terminate thread
    00236    // 2. Loop until connection lost or thread should be terminated
    00237    // 2.1. Receive always 1 Byte
    00238    // 2.2. Call Receive
    00239    // 2.3. goto 2.1
    00240    // 3. Call DisInd
    00241    // goto 1.
    00242    for ( ; ; )
    00243    {
    00244       // Wait for the Request to start receiving data
    00245       // WaitForMultipleObjects returns 0 for Events[0] = pClass->hEventStartReceiving_
    00246       if ( WaitForMultipleObjects( 2, Events, FALSE, INFINITE ) != 0 )
    00247          break;
    00248
    00249       // Receiving data from the socket interface
    00250       for ( ; ; )
    00251       {
    00252          // Read now the "real" data of the message
    00253          char *pData            = (char *)pClass->m_pRecvBuffer;
    00254
    00255          // read only 1 Byte
    00256          RecvBytes = recv( pClass->m_Socket,
    00257                             pData,
    00258                             1,
    00259                             0 );
    00260
    00261          // if errors during receiption --> break loop --> disconnect connection
    00262          if ( RecvBytes == SOCKET_ERROR || RecvBytes == 0 ) // ASc, 05.07.2001, 0 = Socket Connection closed
    00263          {
    00264             break;
    00265          }
    00266          // signal the receiption of data to the user
    00267          // IFr, 09.07.01, do not call virtual func when destructed
    00268          if ( pClass->Terminating() )
    00269          {
    00270             break;
    00271          }
    00272          pClass->Receive( pClass->m_pRecvBuffer, 1 );
    00273
    00274       }
    00275       if ( ! pClass->Terminating() )
    00276       {
    00277          pClass->RecvDisInd();
    00278       }
    00279    }
    00280
    00281    SetEvent( pClass->m_hEventTerminateFinished );
    00282 }
    00283
    00284
    00285
    00286