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