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
1.3.7