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

TCPIPCommConnect.cpp

00001 //***************************************************************************** 00002 // project : ANALYTICA Class Library 00003 // part : Communication class for simple TCP/IP 00004 // file name : TCPIPCommConnect.h 00005 // version : $Revision: 1.9 $ 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 : Connection establishment 00015 // 00016 //----------------------------------------------------------------------------- 00017 // Revisionhistory: 00018 // $Log: TCPIPCommConnect.cpp,v $ 00019 // Revision 1.9 2003/02/06 14:16:52 UdoWeber 00020 // - Funktion Über/Untertoleranz hinzugefügt 00021 // - Fehler beim Beenden der Anwendung (TCPIPComm::DisInd beim terminieren) 00022 // - Berechnungsfehler bei Konvertierung mm/mV beseitigt 00023 // 00024 // Revision 1.8 2002/02/22 16:26:37 IngoFroehlich 00025 // fixed: Problem beim Beenden der Threads 00026 // 00027 // Revision 1.7 2001/08/23 11:21:34 AxelSchmidt 00028 // neue Funktion ConvToInAddr( 00029 // 00030 // Revision 1.6 2001/07/18 15:58:58 AxelSchmidt 00031 // Bug beseitigt, Connect-Thrad wird bei er Erzeugung der TCP-IP-Klasse nicht gestartet 00032 // 00033 // Revision 1.5 2001/07/17 06:55:05 AxelSchmidt 00034 // class destructor hangs if Thead is not already started 00035 // 00036 // Revision 1.4 2001/07/12 14:35:59 AxelSchmidt 00037 // virtuelle Basis-Klasse CTraceObject hinzugefügt 00038 // 00039 // 20.07.1998 UWe Some bug fixes 00040 // 20.04.1998 UWe first version 00041 //***************************************************************************** 00042 00043 //---- includes --------------------------------------------------------------- 00044 #include "stdafx.h" 00045 00046 #include "TCPIPCommConnect.h" 00047 00048 00049 //---- defines/const ---------------------------------------------------------- 00050 00051 00052 00053 //---- classes ----------------------------------------------------------------- 00054 00055 00056 //****************************************************************************** 00057 // Methods of class 'CTCPIPCommConnect' 00058 //****************************************************************************** 00059 00060 // Static attributes and operations 00061 00062 00063 //------------------------------------------------------------------------------ 00064 // Description: 00065 // Constructs the class CTCPIPCommConnect and creates a thread for the connection 00066 // establishment 00067 // 00068 // Input: ---- 00069 // 00070 // Output: ---- 00071 // 00072 // Return: ---- 00073 // 00074 //------------------------------------------------------------------------------ 00075 CTCPIPCommConnect::CTCPIPCommConnect( void ) 00076 { 00077 m_Terminating = false; 00078 m_Socket = INVALID_SOCKET; 00079 m_PassiveSocket = INVALID_SOCKET; 00080 m_ThreadHandle = NULL; //ASc, 17.07.2001 00081 00082 // Create the Semaphore for the child (connect) thread 00083 m_hEventTerminate = CreateEvent( NULL, // Security Attributes 00084 FALSE, // Automatic Reset 00085 FALSE, // Initial to non signaled 00086 NULL ); // Name of Semaphore 00087 m_hEventTerminateFinished = CreateEvent( NULL, // Security Attributes 00088 FALSE, // Automatic Reset 00089 FALSE, // Initial to non signaled 00090 NULL ); // Name of Semaphore 00091 m_hEventConnecting = CreateEvent( NULL, // Security Attributes 00092 FALSE, // Automatic Reset 00093 FALSE, // Initial to non signaled 00094 NULL ); // Name of Semaphore 00095 00096 // Create the connect thread 00097 m_ThreadHandle = CreateThread( NULL, // Security Attributes 00098 0, // Default Stack size 00099 (LPTHREAD_START_ROUTINE)ConnectThread, // Thread function 00100 this, // Pointer to this class 00101 0, // Thread starts immediatly 00102 &m_ThreadID ); // Returns the Thread ID 00103 } 00104 00105 00106 //------------------------------------------------------------------------------ 00107 // Description: 00108 // Destructs the CTCPIPCommConnect class 00109 // 00110 // Input: ---- 00111 // 00112 // Output: ---- 00113 // 00114 // Return: ---- 00115 // 00116 //------------------------------------------------------------------------------ 00117 CTCPIPCommConnect::~CTCPIPCommConnect() 00118 { 00119 m_Terminating = TRUE; 00120 00121 DisconnectRequest(); 00122 00123 // Stop the connect thread 00124 SetEvent( m_hEventTerminate ); 00125 00126 // wait until connect thread has terminated 00127 if ( m_ThreadHandle != NULL ) //ASc, 17.07.2001, wait, if Thread is started 00128 { 00129 WaitForSingleObject( m_hEventTerminateFinished, INFINITE ); 00130 00131 CloseHandle( m_ThreadHandle ); 00132 } 00133 CloseHandle( m_hEventTerminate ); 00134 CloseHandle( m_hEventTerminateFinished ); 00135 CloseHandle( m_hEventConnecting ); 00136 } 00137 00138 00139 //------------------------------------------------------------------------------ 00140 // Description: 00141 // Performs the general initialization of the class parameters 00142 // 00143 // Input: 00144 // TCPport : TCP port number to be used for the connection 00145 // pIPAddress : C string in the form "139.20.29.32" or Name which can be 00146 // resolved. If NULL the address of local machin will be used 00147 // PassiveConnection: True if awaiting a connection from the partner 00148 // 00149 // Output: ---- 00150 // 00151 // Return: ---- 00152 // 00153 //------------------------------------------------------------------------------ 00154 void CTCPIPCommConnect::Initialize( const short TCPport, 00155 const char *pIPAddress, 00156 const bool PassiveConnection ) 00157 { 00158 BOOL ReUseAddr = TRUE; 00159 00160 // Save some parameters 00161 m_PassiveConnection = PassiveConnection; 00162 m_RemoteAddr = ConvTCPAddrToSocketAddr( TCPport, pIPAddress ); 00163 00164 if ( PassiveConnection ) 00165 { 00166 /* ASc, Disabled, why create a second socket ?? 00167 m_PassiveSocket = socket( AF_INET, SOCK_STREAM, 0 ); 00168 00169 if ( setsockopt( m_PassiveSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&ReUseAddr, 00170 sizeof( ReUseAddr ) ) == SOCKET_ERROR ) 00171 { 00172 m_LastSocketError = WSAGetLastError(); 00173 printf( "Error setsockopt : %d\n", m_LastSocketError ); 00174 return; 00175 } 00176 00177 if ( bind( m_PassiveSocket, (PSOCKADDR) &m_RemoteAddr, 00178 sizeof( m_RemoteAddr ) ) == SOCKET_ERROR ) 00179 { 00180 m_LastSocketError = WSAGetLastError(); 00181 printf( "Error bind : %d\n", m_LastSocketError ); 00182 return; 00183 } 00184 00185 if ( listen( m_PassiveSocket, SOMAXCONN ) == SOCKET_ERROR ) 00186 { 00187 m_LastSocketError = WSAGetLastError(); 00188 printf( "Error listen : %d\n", m_LastSocketError ); 00189 return; 00190 } 00191 */ 00192 } 00193 } 00194 00195 00196 struct in_addr CTCPIPCommConnect::ConvToInAddr( unsigned long nIPAddress ) const 00197 { 00198 struct in_addr sAddr; 00199 sAddr.S_un.S_addr = nIPAddress; 00200 return sAddr; 00201 } 00202 //------------------------------------------------------------------------------ 00203 // Description: 00204 // Generate the SOCKADDR_IN out of the Port and the IP Address 00205 // 00206 // Input: 00207 // TCPport : TCP port number to be used for the connection 00208 // pIPAddress : C string in the form "139.20.29.32" or Name which can be 00209 // resolved. If NULL the address of local machin will be used 00210 // 00211 // Output: ---- 00212 // 00213 // Return: 00214 // TCP/IP address in socket format 00215 // 00216 //------------------------------------------------------------------------------ 00217 SOCKADDR_IN CTCPIPCommConnect::ConvTCPAddrToSocketAddr( const short TCPport, 00218 const char *pIPAddr ) 00219 { 00220 IN_ADDR IPAddress; 00221 SOCKADDR_IN SocketAddr; 00222 00223 if ( pIPAddr == NULL ) 00224 { 00225 // get address of local machine 00226 struct hostent *host; 00227 char hostname[128]; 00228 00229 gethostname( hostname, sizeof( hostname ) ); 00230 host = gethostbyname( hostname ); 00231 memcpy( &IPAddress.s_addr, host->h_addr_list[0], host->h_length ); 00232 } 00233 else 00234 { 00235 struct hostent *pAddr = NULL; 00236 00237 if ( ! isdigit( pIPAddr[0] ) ) 00238 pAddr = gethostbyname( pIPAddr ); 00239 00240 if ( pAddr == NULL ) 00241 IPAddress.s_addr = inet_addr( pIPAddr ); 00242 else 00243 IPAddress.s_addr = *((unsigned long *)(pAddr->h_addr_list[0])); 00244 00245 } 00246 00247 memset( &SocketAddr, 0, sizeof( SocketAddr ) ); 00248 00249 SocketAddr.sin_family = AF_INET; 00250 SocketAddr.sin_port = htons( TCPport ); 00251 SocketAddr.sin_addr = IPAddress; 00252 00253 return SocketAddr; 00254 } 00255 00256 00257 00258 //------------------------------------------------------------------------------ 00259 // Description: 00260 // Try to establish the connection to the specified communication partner 00261 // 00262 // Input: 00263 // PassiveSocket : The socket to be used for passive connections 00264 // 00265 // Output: ---- 00266 // 00267 // Return: TRUE if function succeeded 00268 // 00269 //------------------------------------------------------------------------------ 00270 bool CTCPIPCommConnect::ConnectRequest( SOCKET PassiveSocket ) 00271 { 00272 //Original Code : 00273 m_PassiveSocket = PassiveSocket; 00274 00275 // Signal the connect thread to establish/await the connection 00276 if ( ! SetEvent( m_hEventConnecting ) ) 00277 { 00278 m_LastSocketError = GetLastError(); 00279 return false; 00280 } 00281 00282 return true; 00283 } 00284 00285 00286 //------------------------------------------------------------------------------ 00287 // Description: 00288 // Close the connection to the communication partner 00289 // 00290 // Input: ---- 00291 // 00292 // Output: ---- 00293 // 00294 // Return: TRUE if function succeeded 00295 // 00296 //------------------------------------------------------------------------------ 00297 bool CTCPIPCommConnect::DisconnectRequest( void ) 00298 { 00299 if ( m_Socket != INVALID_SOCKET ) 00300 { 00301 closesocket( m_Socket ); 00302 } 00303 00304 m_Socket = INVALID_SOCKET; 00305 return false; 00306 } 00307 00308 00309 //------------------------------------------------------------------------------ 00310 // Description: 00311 // Awaits the connection from the communication partner (passive connection) 00312 // 00313 // Input: ---- 00314 // 00315 // Output: ---- 00316 // 00317 // Return: TRUE if function succeeded 00318 // 00319 //------------------------------------------------------------------------------ 00320 bool CTCPIPCommConnect::AwaitConnection( void ) 00321 { 00322 // Hier ist noch ein Hund begraben. Manchmal bleibt er hier stehen 00323 // => kann keine Verbindung herstellen. 00324 if ( ( m_Socket = accept( m_PassiveSocket, NULL, NULL ) ) == INVALID_SOCKET ) 00325 { 00326 m_LastSocketError = WSAGetLastError(); 00327 return false; 00328 } 00329 00330 return true; 00331 } 00332 00333 00334 //------------------------------------------------------------------------------ 00335 // Description: 00336 // Establishes the connection to the communication partner (active connection) 00337 // 00338 // Input: ---- 00339 // 00340 // Output: ---- 00341 // 00342 // Return: TRUE if function succeeded 00343 // 00344 //------------------------------------------------------------------------------ 00345 bool CTCPIPCommConnect::EstablishConnection( void ) 00346 { 00347 if ( ( m_Socket = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET ) 00348 { 00349 m_LastSocketError = WSAGetLastError(); 00350 return FALSE; 00351 } 00352 00353 if ( connect( m_Socket, 00354 (PSOCKADDR) & m_RemoteAddr, 00355 sizeof( m_RemoteAddr ) ) == SOCKET_ERROR ) 00356 { 00357 m_LastSocketError = WSAGetLastError(); 00358 return FALSE; 00359 } 00360 00361 return TRUE; 00362 } 00363 00364 00365 //------------------------------------------------------------------------------ 00366 // Description: 00367 // Thread starting routine 00368 // 00369 // Input: 00370 // pClass : Pointer to the local class 00371 // 00372 // Output: ---- 00373 // 00374 // Return: ---- 00375 // 00376 //------------------------------------------------------------------------------ 00377 void CTCPIPCommConnect::ConnectThread( CTCPIPCommConnect *pClass ) 00378 { 00379 char ConnectionEstablished; 00380 HANDLE Events[2]; 00381 00382 Events[ 0 ] = pClass->m_hEventConnecting; 00383 Events[ 1 ] = pClass->m_hEventTerminate; 00384 00385 // Loop until thread should be terminated 00386 // 1. Wait for the command to establish/await the connection or to terminate thread 00387 // 2. Establish/await the connection 00388 // 3. Call ConInd or DisInd 00389 // goto 1. 00390 for ( ; ; ) 00391 { 00392 // Wait for the Request to establish/await the connection 00393 // WaitForMultipleObjects returns 0 for Events[0] = pClass->hEventConnecting 00394 if ( WaitForMultipleObjects( 2, Events, FALSE, INFINITE ) != 0 ) 00395 { 00396 break; // Terminate connect thread 00397 } 00398 if ( pClass->m_PassiveConnection ) 00399 ConnectionEstablished = pClass->AwaitConnection(); 00400 else 00401 ConnectionEstablished = pClass->EstablishConnection(); 00402 00403 // if connection established indicate state to user 00404 if ( ConnectionEstablished ) 00405 { 00406 // Set the Keep Alive Flag in order to observe permanent the connection state 00407 BOOL KeepAlive = TRUE; 00408 BOOL DisableNagle = TRUE; 00409 int SendBuffer = 1200; 00410 int RecvBuffer = 1200; 00411 /* 00412 int OptLen; 00413 00414 OptLen = sizeof( DisableNagle ); 00415 if ( getsockopt( pClass->m_Socket, IPPROTO_TCP, TCP_NODELAY, (char *)&DisableNagle, &OptLen ) ) 00416 pClass->m_LastSocketError = WSAGetLastError(); 00417 00418 printf( "Nagle Algorithm activated : %s\n", DisableNagle ? "NO" : "YES" ); 00419 DisableNagle = TRUE; 00420 */ 00421 if ( setsockopt( pClass->m_Socket, SOL_SOCKET, SO_KEEPALIVE, 00422 (char *)&KeepAlive, sizeof( KeepAlive ) ) ) 00423 pClass->m_LastSocketError = WSAGetLastError(); 00424 /* 00425 if ( setsockopt( pClass->m_Socket, IPPROTO_TCP, TCP_NODELAY, (char *)&DisableNagle, sizeof( DisableNagle ) ) ) 00426 pClass->m_LastSocketError = WSAGetLastError(); 00427 00428 if ( setsockopt( pClass->m_Socket, SOL_SOCKET, SO_SNDBUF, (char *)&SendBuffer, sizeof( SendBuffer ) ) ) 00429 pClass->m_LastSocketError = WSAGetLastError(); 00430 00431 00432 OptLen = sizeof( DisableNagle ); 00433 if ( getsockopt( pClass->m_Socket, IPPROTO_TCP, TCP_NODELAY, (char *)&DisableNagle, &OptLen ) ) 00434 pClass->m_LastSocketError = WSAGetLastError(); 00435 00436 printf( "Nagle Algorithm activated : %s\n", DisableNagle ? "NO" : "YES" ); 00437 */ 00438 00439 /* 00440 if ( setsockopt( pClass->m_Socket, SOL_SOCKET, SO_RCVBUF, (char *)&RecvBuffer, sizeof( RecvBuffer ) ) ) 00441 pClass->m_LastSocketError = WSAGetLastError(); 00442 */ 00443 00444 // Retrieve the IP Address of the communication partner for later use 00445 struct sockaddr_in RemName; 00446 int RemNameLen = sizeof( RemName ); 00447 00448 if ( getpeername( pClass->m_Socket, (sockaddr *)&RemName, &RemNameLen ) ) 00449 pClass->m_LastSocketError = WSAGetLastError(); 00450 pClass->m_RemoteIPAddr = RemName.sin_addr.s_addr; 00451 00452 /* 00453 printf( "Connection established : %d.%d.%d.%d. pClass = %08X\n", 00454 HIBYTE( HIWORD( pClass->m_RemoteIPAddr ) ), 00455 LOBYTE( HIWORD( pClass->m_RemoteIPAddr ) ), 00456 HIBYTE( LOWORD( pClass->m_RemoteIPAddr ) ), 00457 LOBYTE( LOWORD( pClass->m_RemoteIPAddr ) ), 00458 pClass ); 00459 */ 00460 00461 // Signal connect indication to user 00462 if ( ! pClass->Terminating() ) //ASC, 12.09.2001, added 00463 pClass->ConInd(); 00464 } 00465 else 00466 if ( ! pClass->Terminating() ) 00467 pClass->DisInd(); 00468 } 00469 SetEvent( pClass->m_hEventTerminateFinished ); 00470 } 00471 00472 00473 00474

Erzeugt am Tue Mar 11 14:25:07 2008 für AnalyticaTCPIP-COMMclass von doxygen 1.3.7