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

# TCPIPComm.cpp

    00001 //*****************************************************************************
    00002 // project   : ANALYTICA Class Library
    00003 // part      : Communication class for simple TCP/IP
    00004 // file name : TCPIPComm.h
    00005 // version   : 1.2
    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 // Contains the main part of the communication classes. Organizes the
    00015 // handling of the three lower classes CTCPIPCommConnect, CTCPIPCommRecv and
    00016 // CTCPIPCommSend.
    00017 //
    00018 //-----------------------------------------------------------------------------
    00019 // Revisionhistory:
    00020 // 03.07.2001 ASc  Deferred Initialization added
    00021 // 20.07.1998 UWe  Some bug fixes
    00022 // 20.04.1998 UWe  first version
    00023 //*****************************************************************************
    00024
    00025 //---- includes ---------------------------------------------------------------
    00026 #include "stdafx.h"
    00027
    00028 #include "TCPIPComm.h"
    00029
    00030
    00031 //---- defines/const ----------------------------------------------------------
    00032
    00033
    00034
    00035 //---- classes -----------------------------------------------------------------
    00036
    00037
    00038 //******************************************************************************
    00039 // Methods of class 'CTCPIPComm'
    00040 //******************************************************************************
    00041
    00042 // Static attributes and operations
    00043
    00044 int    CTCPIPComm::m_NumOfInstances = 0;
    00045 //SOCKET CTCPIPComm::m_PassiveSocket  = INVALID_SOCKET;
    00046 bool          CTCPIPComm::m_bArrayUsed[]     = { false, false };
    00047 SOCKADDR_IN   CTCPIPComm::m_ArrayRemoteAddr[]= { 0, 0 };
    00048 SOCKET        CTCPIPComm::m_ArrayPassiveSocket[]= { INVALID_SOCKET, INVALID_SOCKET };
    00049
    00050
    00051 //------------------------------------------------------------------------------
    00052 // Description:
    00053 //   Constructs the class CTCPIPComm and creates a new communication instance.
    00054 //   A new instance is necessary for every communication partner
    00055 //
    00056 // Input:
    00057 //   TCPport          : Port number to be used for the communication
    00058 //   pIPAddress       : NULL terminated string containing IP Address or Name of partner
    00059 //   PassiveConnection: true if awaiting the connection from the partner
    00060 //   MaxSendDataLen   : Maximum length for sending messages
    00061 //   MaxRecvDataLen   : Maximum length for receiving messages
    00062 //
    00063 // Output: ----
    00064 //
    00065 // Return: ----
    00066 //
    00067 //------------------------------------------------------------------------------
    00068 CTCPIPComm::CTCPIPComm( const short TCPport,
    00069                         const char  *pIPAddress,
    00070                         const bool  PassiveConnection,
    00071                         const long  MaxSendBufferLen,
    00072                         const long  MaxRecvBufferLen )
    00073                       : CTCPIPCommReceive( -1 ),
    00074                         CTCPIPCommSend( -1 ),
    00075                         CTCPIPCommConnect()
    00076 {
    00077    m_bInitialized = false;
    00078    m_bTerminating = false;
    00079    Initialize( TCPport, pIPAddress, PassiveConnection, MaxSendBufferLen, MaxRecvBufferLen );
    00080 }
    00081
    00082 //------------------------------------------------------------------------------
    00083 // Description:
    00084 //   Constructs the class CTCPIPComm. The communication instance must bei created by a
    00085 //   call to the Initialize function (only available in a derived class)
    00086 //
    00087 // Input:  ----
    00088 //
    00089 // Output: ----
    00090 //
    00091 // Return: ----
    00092 //
    00093 //------------------------------------------------------------------------------
    00094 CTCPIPComm::CTCPIPComm( void )
    00095                       : CTCPIPCommReceive( -1 ),
    00096                         CTCPIPCommSend( -1 ),
    00097                         CTCPIPCommConnect()
    00098 {
    00099    m_bInitialized = false;
    00100 }
    00101
    00102 //------------------------------------------------------------------------------
    00103 // Description:
    00104 //   Initialization-Routine for object construction.
    00105 //
    00106 // Input:
    00107 //   TCPport          : Port number to be used for the communication
    00108 //   pIPAddress       : NULL terminated string containing IP Address or Name of partner
    00109 //   PassiveConnection: true if awaiting the connection from the partner
    00110 //   MaxSendDataLen   : Maximum length for sending messages
    00111 //   MaxRecvDataLen   : Maximum length for receiving messages
    00112 //
    00113 // Output: ----
    00114 //
    00115 // Return: ----
    00116 //
    00117 //------------------------------------------------------------------------------
    00118 void CTCPIPComm::Initialize( const short  TCPport,
    00119                              const char   *pIPAddress,
    00120                              const bool   PassiveConnection,
    00121                              const long   MaxSendDataLen,
    00122                              const long   MaxRecvDataLen )
    00123 {
    00124    bool        SocketFound;
    00125    int         i;
    00126
    00127    if ( m_bInitialized == true )
    00128    {
    00129       return;
    00130    }
    00131
    00132    m_bInitialized = true;
    00133
    00134    // Initialize Receive and Send-classes
    00135    CTCPIPCommReceive::InitializeClass( MaxRecvDataLen );
    00136    CTCPIPCommSend::InitializeClass( MaxSendDataLen );
    00137
    00138    m_LineConnected     = false;
    00139    m_LastSocketError   = 0;
    00140    m_PassiveConnection = PassiveConnection;
    00141    m_PassiveSocket     = INVALID_SOCKET;
    00142
    00143    if ( m_NumOfInstances++ == 0 )
    00144    {
    00145       // If the first instance of this class is created, the
    00146       // socket for the passive connections (await function)
    00147       // has to be created. PXROS does not support more than
    00148       // one socket for the same TCP/IP address.
    00149       WSADATA         WsaData;
    00150       if ( WSAStartup( 0x0101, &WsaData ) == SOCKET_ERROR )
    00151       {
    00152          m_LastSocketError = GetLastError();
    00153          return;
    00154       }
    00155    }
    00156
    00157    if ( PassiveConnection )
    00158    {
    00159
    00160       m_RemoteAddr = ConvTCPAddrToSocketAddr( TCPport, pIPAddress );
    00161
    00162       for ( i = 0, SocketFound = false; i < MAX_DIF_ADDR; i++ )
    00163          if ( m_bArrayUsed[ i ] )
    00164             if ( memcmp( &m_RemoteAddr, &m_ArrayRemoteAddr[ i ], sizeof( m_RemoteAddr ) ) == 0 )
    00165             {
    00166                SocketFound = true;
    00167                break;
    00168             }
    00169
    00170       if ( SocketFound )
    00171          m_PassiveSocket = m_ArrayPassiveSocket[ i ];
    00172       else
    00173       {
    00174          for ( i = 0; i < MAX_DIF_ADDR; i++ )
    00175             if ( ! m_bArrayUsed[ i ] )
    00176             {
    00177                m_PassiveSocket = socket( AF_INET, SOCK_STREAM, 0 );
    00178                bind( m_PassiveSocket, (PSOCKADDR) &m_RemoteAddr, sizeof( m_RemoteAddr ) );
    00179                listen( m_PassiveSocket, SOMAXCONN );
    00180                m_ArrayPassiveSocket[i] = m_PassiveSocket;
    00181                m_ArrayRemoteAddr[i]    = m_RemoteAddr;
    00182                m_bArrayUsed[i]         = true;
    00183                break;
    00184             }
    00185       }
    00186
    00187    }
    00188
    00189    // Initialize the Connect class
    00190    CTCPIPCommConnect::Initialize( TCPport, pIPAddress, m_PassiveConnection );
    00191 }
    00192
    00193 //------------------------------------------------------------------------------
    00194 // Description:
    00195 //   Destructs the CTCPIPComm class
    00196 //
    00197 // Input:  ----
    00198 //
    00199 // Output: ----
    00200 //
    00201 // Return: ----
    00202 //
    00203 //------------------------------------------------------------------------------
    00204 CTCPIPComm::~CTCPIPComm()
    00205 {
    00206    m_bTerminating = true;
    00207
    00208    if ( --m_NumOfInstances == 0 )
    00209    {
    00210       // Attention !!!
    00211       // WSACleanup should be called after last instance of CTCPIPComm is deleted
    00212       //WSACleanup();
    00213    }
    00214
    00215    // close the global passive socket --> All threads waiting in the "accept" call
    00216    // will be released
    00217    if ( m_PassiveSocket != INVALID_SOCKET )
    00218    {
    00219       SOCKET      TmpSocket = m_PassiveSocket;
    00220
    00221       m_PassiveSocket = INVALID_SOCKET;
    00222       closesocket( TmpSocket );
    00223
    00224       if ( m_NumOfInstances > 0 )
    00225       {
    00226          // if other instances still exists create again the socket for the passive
    00227          // connections.
    00228          m_PassiveSocket = socket( AF_INET, SOCK_STREAM, 0 );
    00229          bind( m_PassiveSocket, (PSOCKADDR) &m_RemoteAddr, sizeof( m_RemoteAddr ) );
    00230          listen( m_PassiveSocket, SOMAXCONN );
    00231       }
    00232    }
    00233
    00234    // signal the threads Receive/Send to terminate and wait for their termination
    00235    CTCPIPCommReceive::Terminating( true );
    00236    CTCPIPCommSend::Terminating( false );
    00237 }
    00238
    00239
    00240
    00241 //------------------------------------------------------------------------------
    00242 // Description:
    00243 //   Try to establish the connection to the communication partner
    00244 //
    00245 // Input:  ----
    00246 //
    00247 // Output: ----
    00248 //
    00249 // Return: true if function call successful
    00250 //         does not mean that the connection was connected --> ConnectIndication
    00251 //
    00252 //------------------------------------------------------------------------------
    00253 bool CTCPIPComm::ConnectRequest( void )
    00254 {
    00255    return CTCPIPCommConnect::ConnectRequest( m_PassiveSocket );
    00256 }
    00257
    00258
    00259 //------------------------------------------------------------------------------
    00260 // Description:
    00261 //   Transmits the given data to the communication partner
    00262 //
    00263 // Input:
    00264 //   pData        : Pointer to the data to be sent
    00265 //   DataLen      : Length of the data
    00266 //
    00267 // Output: ----
    00268 //
    00269 // Return: ----
    00270 //
    00271 //------------------------------------------------------------------------------
    00272 bool CTCPIPComm::Send( const void    *pData,
    00273                        const long    DataLen )
    00274 {
    00275    if ( ! IsConnected() )
    00276       return FALSE;
    00277
    00278    return CTCPIPCommSend::Send( pData, DataLen );
    00279 }
    00280
    00281
    00282 //------------------------------------------------------------------------------
    00283 // Description:
    00284 //   called from CTCPIPCommConnect in order to indicate the connect indication
    00285 //
    00286 // Input:  ----
    00287 //
    00288 // Output: ----
    00289 //
    00290 // Return: ----
    00291 //
    00292 //------------------------------------------------------------------------------
    00293 void CTCPIPComm::ConInd( void )
    00294 {
    00295    m_LineConnected = TRUE;
    00296
    00297    // Send to the Receive and Send Thread the Init command in order
    00298    // to tell them the socket handle to be used.
    00299    CTCPIPCommSend::Initialize( GetSocket() );
    00300    CTCPIPCommReceive::Initialize( GetSocket() );
    00301
    00302    // Signal to the user the connect indication
    00303    ConnectIndication();
    00304
    00305    // Signal to the receive thread that the receiving part can now be started
    00306    // Attention: This has to be done after the "ConnectIndication" that the user
    00307    //            is informed first of the connected line.
    00308    CTCPIPCommReceive::StartReceiving();
    00309 }
    00310
    00311
    00312 //------------------------------------------------------------------------------
    00313 // Description:
    00314 //   called from CTCPIPCommConnect in order to indicate the disconnect indication
    00315 //
    00316 // Input:  ----
    00317 //
    00318 // Output: ----
    00319 //
    00320 // Return: ----
    00321 //
    00322 //------------------------------------------------------------------------------
    00323 void CTCPIPComm::DisInd( void )
    00324 {
    00325    if ( m_LineConnected )
    00326    {
    00327       m_LineConnected = FALSE;
    00328
    00329       CTCPIPCommConnect::DisconnectRequest();
    00330    }
    00331
    00332
    00333    if ( ! m_bTerminating )
    00334    {
    00335       // Inform "user" of this class always (to be able to try to connect again)
    00336       DisconnectIndication();
    00337    }
    00338 }
    00339
    00340 //------------------------------------------------------------------------------
    00341 // Description:
    00342 //   called by CTCPIPComRecv in order to indicate the disconnect indication
    00343 //
    00344 // Input:  ----
    00345 //
    00346 // Output: ----
    00347 //
    00348 // Return: ----
    00349 //
    00350 //------------------------------------------------------------------------------
    00351 void CTCPIPComm::RecvDisInd( void )
    00352 {
    00353    DisInd();
    00354 }
    00355
    00356 //------------------------------------------------------------------------------
    00357 // Description:
    00358 //   called by CTCPIPComSend in order to indicate the disconnect indication
    00359 //
    00360 // Input:  ----
    00361 //
    00362 // Output: ----
    00363 //
    00364 // Return: ----
    00365 //
    00366 //------------------------------------------------------------------------------
    00367 void CTCPIPComm::SendDisInd( void )
    00368 {
    00369    DisInd();
    00370 }
    00371