home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / wfc007.000 / src / lsockets.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-22  |  6.3 KB  |  251 lines

  1. #include <wfc.h>
  2. #pragma hdrstop
  3.  
  4. /*
  5. ** Author: Samuel R. Blackburn
  6. ** CI$: 76300,326
  7. ** Internet: sammy@sed.csc.com
  8. **
  9. ** You can use it any way you like.
  10. */
  11.  
  12. #if defined( _DEBUG )
  13. #undef THIS_FILE
  14. static char BASED_CODE THIS_FILE[] = __FILE__;
  15. #endif
  16.  
  17. CListeningSocket::CListeningSocket()
  18. {
  19.    TRACE( "CListeningSocket::CListeningSocket()\n" );
  20.    m_Initialize();
  21. }
  22.  
  23. CListeningSocket::~CListeningSocket()
  24. {
  25.    TRACE( "Destroying a CListeningSocket object\n" );
  26. }
  27.  
  28. void CListeningSocket::Dump( CDumpContext &dump_context ) const
  29. {
  30.    CObject::Dump( dump_context );
  31. }
  32.  
  33. void CListeningSocket::m_Initialize( void )
  34. {
  35.    ASSERT_VALID( this );
  36.  
  37.    TRACE( "CListeningSocket::m_Initialize(), Initializing a CListeningSocket class\n" );
  38.  
  39.    /*
  40.    ** Make sure that everything is empty
  41.    */
  42.  
  43.    m_ServerSocketID                     = INVALID_SOCKET;
  44.    m_NumberOfSimultaneousSocketsToAllow = 10;
  45. }
  46.  
  47. BOOL CListeningSocket::Open( void )
  48. {
  49.    ASSERT_VALID( this );
  50.  
  51.    if ( m_ServerSocketID != INVALID_SOCKET )
  52.    {
  53.       TRACE( "CListeningSocket::Open(), server socket already created at line %d of %s\n", __LINE__, __FILE__ );
  54.       return( TRUE );
  55.    }
  56.  
  57.    if ( m_PortNumberInNetworkByteOrder == 0 )
  58.    {
  59.       TRACE( "CListeningSocket::open(), can't server socket without a port number at line %d of %s\n", __LINE__, __FILE__ );
  60.       return( FALSE );
  61.    }
  62.  
  63.    /*
  64.    ** Create the server (or listening) socket thingy
  65.    */
  66.  
  67.    m_ServerSocketID = ::socket( AF_INET, SOCK_STREAM, 0 );
  68.  
  69.    if ( m_ServerSocketID == INVALID_SOCKET )
  70.    {
  71.       TRACE( "CListeningSocket::open(), socket() failed at line %d of %s\n", __LINE__, __FILE__ );
  72.  
  73.       m_ErrorCode = ::WSAGetLastError();
  74.       return( FALSE );
  75.    }
  76.  
  77.    /*
  78.    ** We've got a socket thingy but its useless. It doesn't have an address. Let's give it one.
  79.    ** We do this by bind'ing an address and port number to it.
  80.    */
  81.  
  82.    SOCKADDR_IN socket_address;
  83.  
  84.    socket_address.sin_family      = AF_INET;
  85.    socket_address.sin_port        = m_PortNumberInNetworkByteOrder;
  86.    socket_address.sin_addr.s_addr = ::htonl( INADDR_ANY ); // We'll let anybody connect to us
  87.  
  88.    if ( ::bind( m_ServerSocketID, (LPSOCKADDR) &socket_address, sizeof( socket_address ) ) == SOCKET_ERROR )
  89.    {
  90.       TRACE( "CListeningSocket::open(), bind() failed at line %d of %s\n", __LINE__, __FILE__ );
  91.  
  92.       m_ErrorCode = ::WSAGetLastError();
  93.       return( FALSE );
  94.    }
  95.  
  96.    /*
  97.    ** Now the socket thingy has an address and port number.
  98.    */
  99.  
  100.    /*
  101.    ** Now we make it a listening socket and start listening, program execution halts here
  102.    */
  103.    
  104.    if ( ::listen( m_ServerSocketID, m_NumberOfSimultaneousSocketsToAllow ) == SOCKET_ERROR )
  105.    {
  106.       TRACE( "CListeningSocket::Open(), Can't listen() at line %d of %s\n", __LINE__, __FILE__ );
  107.  
  108.       m_ErrorCode = ::WSAGetLastError();
  109.       return( FALSE );
  110.    }
  111.  
  112.    return( TRUE );
  113. }
  114.  
  115. #pragma warning( disable : 4100 )
  116.  
  117. BOOL CListeningSocket::Open( const char *ChannelName, UINT port_number, CFileException *pError )
  118. {
  119.    ASSERT_VALID( this );
  120.  
  121.    SetPort( (short) port_number );
  122.  
  123.    return( Open() );
  124. }
  125.  
  126. #pragma warning( default : 4100 )
  127.  
  128. BOOL CListeningSocket::WaitForConnection( void )
  129. {
  130.    ASSERT_VALID( this );
  131.  
  132.    if ( m_PortNumberInNetworkByteOrder == 0 )
  133.    {
  134.       return( FALSE );
  135.    }
  136.  
  137.    if ( m_ServerSocketID == INVALID_SOCKET )
  138.    {
  139.       if ( Open() == FALSE )
  140.       {
  141.          TRACE( "CListeningSocket::WaitForConnection(), Can't open() at line %d of %s\n", __LINE__, __FILE__ );
  142.          return( FALSE );
  143.       }
  144.    }
  145.  
  146.    SOCKADDR incoming_socket_address;
  147.  
  148.    int byte_count = 0;
  149.  
  150.    byte_count = sizeof( incoming_socket_address );
  151.  
  152.    ::ZeroMemory( &incoming_socket_address, byte_count );
  153.  
  154.    /*
  155.    ** PROGRAM EXECUTION STOPS HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  156.    **
  157.    ** accept() is a blocking call meaning that the this thread of execution is paused
  158.    ** (ie goes to sleep) until someone on the network connects to us. We will "wake up"
  159.    ** when that happens and continue along our merry way.
  160.    */
  161.  
  162.    m_SocketID = ::accept( m_ServerSocketID, &incoming_socket_address, &byte_count );
  163.  
  164.    if ( m_SocketID == INVALID_SOCKET )
  165.    {
  166.       m_ErrorCode = ::WSAGetLastError();
  167.       return( FALSE );
  168.    }
  169.  
  170.    /*
  171.    ** The method for actually converting the incoming address to something that is human
  172.    ** readable is either undocumented or extremely poorly documented. Not suprising since
  173.    ** the idea of sockets came out of the Unix world...
  174.    */
  175.  
  176.    LPSTR dotted_ip_address = (LPSTR) NULL;
  177.     
  178.    struct in_addr internet_address;
  179.  
  180.    /*
  181.    ** Aren't these structure member names intuitively obvious??
  182.    */
  183.  
  184.    internet_address.S_un.S_un_b.s_b1 = incoming_socket_address.sa_data[ 2 ];
  185.    internet_address.S_un.S_un_b.s_b2 = incoming_socket_address.sa_data[ 3 ];
  186.    internet_address.S_un.S_un_b.s_b3 = incoming_socket_address.sa_data[ 4 ];
  187.    internet_address.S_un.S_un_b.s_b4 = incoming_socket_address.sa_data[ 5 ];
  188.  
  189.    dotted_ip_address = ::inet_ntoa( internet_address );
  190.  
  191.    if ( dotted_ip_address == (LPSTR) NULL )
  192.    {
  193.       m_ErrorCode = WSAEINVAL;
  194.       return( FALSE );
  195.    }
  196.  
  197.    ULONG temp_long = 0L;
  198.  
  199.    temp_long = ::inet_addr( (LPCSTR) dotted_ip_address );
  200.  
  201.    if ( temp_long == INADDR_NONE )
  202.    {
  203.       m_ErrorCode = WSAEINVAL;
  204.       return( FALSE );
  205.    }
  206.  
  207.    LPHOSTENT host_entry_p = (LPHOSTENT) NULL;
  208.  
  209.    host_entry_p = ::gethostbyaddr( (const char *) &temp_long, 4, PF_INET );
  210.  
  211.    if ( host_entry_p == (LPHOSTENT) NULL )
  212.    {
  213.       m_ErrorCode = ::WSAGetLastError();
  214.       return( FALSE );
  215.    }
  216.  
  217.    TRACE( "%s (%s) just connected to us\n", host_entry_p->h_name, (const char *) dotted_ip_address );
  218.  
  219.    SetAddress( dotted_ip_address );
  220.  
  221.    OnNewConnection( m_SocketID, Name, dotted_ip_address );
  222.  
  223.    return( TRUE );
  224. }
  225.  
  226. BOOL CListeningSocket::WaitForConnection( const int port_number )
  227. {
  228.    ASSERT_VALID( this );
  229.    ASSERT( port_number > 0 );
  230.  
  231.    SetPort( (short) port_number );
  232.  
  233.    return( WaitForConnection() );
  234. }
  235.  
  236. BOOL CListeningSocket::WaitForConnection( const char *p_name )
  237. {
  238.    ASSERT_VALID( this );
  239.    ASSERT( p_name != NULL );
  240.  
  241.    if ( p_name == NULL )
  242.    {
  243.       m_ErrorCode = ERROR_INVALID_PARAMETER;
  244.       return( FALSE );
  245.    }
  246.  
  247.    SetPort( p_name );
  248.  
  249.    return( WaitForConnection() );
  250. }
  251.