home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 10 / ioProg_10.iso / soft / optima / samples.z / ServerWorker.wxc < prev    next >
Encoding:
Text File  |  1996-08-14  |  7.9 KB  |  317 lines

  1. Save Format v1.3
  2. @begin ClassFile "ServerWorker"
  3.  Exported 0;
  4.  
  5. @begin-code BaseClassList
  6.  
  7. public WObject
  8.  
  9. @end-code;
  10.  
  11.  @begin UserFunction "ServerWorker()"
  12.   GencodeSrcLine 19;
  13.   FunctionName "ServerWorker::ServerWorker()";
  14.  @end;
  15.  
  16.  @begin UserFunction "Prototype for ServerWorker()"
  17.   Private 1;
  18.   GencodeSrcLine 32;
  19.   FunctionName "ServerWorker::Prototype for ServerWorker()";
  20.  @end;
  21.  
  22.  @begin UserFunction "~ServerWorker()"
  23.   GencodeSrcLine 26;
  24.   FunctionName "ServerWorker::~ServerWorker()";
  25.  @end;
  26.  
  27.  @begin UserFunction "Prototype for ~ServerWorker()"
  28.   Private 1;
  29.   GencodeSrcLine 34;
  30.   FunctionName "ServerWorker::Prototype for ~ServerWorker()";
  31.  @end;
  32.  
  33.  @begin UserFunction "Create( Form1 * displayWindow )"
  34.   GencodeSrcLine 33;
  35.   FunctionName "ServerWorker::Create( Form1 * displayWindow )";
  36.  @end;
  37.  
  38.  @begin UserFunction "Prototype for Create( Form1 * displayWindow )"
  39.   Private 1;
  40.   GencodeSrcLine 36;
  41.   FunctionName "ServerWorker::Prototype for Create( Form1 * displayWindow )";
  42.  @end;
  43.  
  44.  @begin UserFunction "Destroy()"
  45.   GencodeSrcLine 46;
  46.   FunctionName "ServerWorker::Destroy()";
  47.  @end;
  48.  
  49.  @begin UserFunction "Prototype for Destroy()"
  50.   Private 1;
  51.   GencodeSrcLine 38;
  52.   FunctionName "ServerWorker::Prototype for Destroy()";
  53.  @end;
  54.  
  55.  @begin UserFunction "Server( void * )"
  56.   Private 1;
  57.   GencodeSrcLine 58;
  58.   FunctionName "ServerWorker::Server( void * )";
  59.  @end;
  60.  
  61.  @begin UserFunction "Prototype for Server( void * )"
  62.   Private 1;
  63.   GencodeSrcLine 40;
  64.   FunctionName "ServerWorker::Prototype for Server( void * )";
  65.  @end;
  66.  
  67.  @begin HPPPrefixBlock
  68. @begin-code HPPPrefix
  69.  
  70. // Declarations added here will be included at the top of the .HPP file
  71. #include "ClientWorker.hpp"
  72.  
  73.  
  74. template WVector< WSocket >;
  75. template WVector< ClientWorker >;
  76. class Form1;
  77.  
  78. @end-code;
  79.   GencodeSrcLine 11;
  80.  @end;
  81.  
  82.  @begin CPPPrefixBlock
  83. @begin-code CPPPrefix
  84.  
  85. // Code added here will be included at the top of the .CPP file
  86. #include "Form1.hpp"
  87. WVector< WSocket > ServerWorker::_client_sockets;
  88. WVector< ClientWorker > ServerWorker::_client_workers;
  89. WCriticalSection ServerWorker::_client_sockets_cs;
  90.  
  91. //  Include definitions for resources.
  92. #include "WRes.h"
  93.  
  94. @end-code;
  95.   GencodeSrcLine 11;
  96.  @end;
  97.  
  98.  @begin ClassContentsBlock
  99. @begin-code ClassContents
  100.  
  101.     public:
  102.         static WVector< WSocket > _client_sockets;
  103.         static WVector< ClientWorker > _client_workers;
  104.         static WCriticalSection _client_sockets_cs;
  105.         
  106.     private:
  107.         Form1 *         _displayWindow;
  108.         WBool           _dyingNow;
  109.         WThread         _thread;
  110.         WServerSocket * _server_sock;
  111.  
  112. @end-code;
  113.   GencodeSrcLine 22;
  114.  @end;
  115.  
  116. @begin-code GeneratedClassContents
  117.  
  118.  
  119. @end-code;
  120.  
  121. @begin-code Code "ServerWorker::ServerWorker()"
  122.  
  123. @@CLASSNAME@::@CLASSNAME@()
  124.     : _displayWindow( NULL ),
  125.       _dyingNow( FALSE ),
  126.       _server_sock( NULL )
  127. {
  128.     
  129. }
  130.  
  131. @end-code;
  132.  
  133. @begin-code Code "ServerWorker::Prototype for ServerWorker()"
  134.  
  135.     public:
  136.         @@CLASSNAME@();
  137.  
  138. @end-code;
  139.  
  140. @begin-code Code "ServerWorker::~ServerWorker()"
  141.  
  142. @@CLASSNAME@::~@CLASSNAME@()
  143. {
  144.     if( _server_sock ) {
  145.         delete _server_sock;
  146.         _server_sock = NULL;
  147.     }
  148. }
  149.  
  150. @end-code;
  151.  
  152. @begin-code Code "ServerWorker::Prototype for ~ServerWorker()"
  153.  
  154.     public:
  155.         ~@CLASSNAME@();
  156.  
  157. @end-code;
  158.  
  159. @begin-code Code "ServerWorker::Create( Form1 * displayWindow )"
  160.  
  161. WBool @CLASSNAME@::Create( Form1 * displayWindow )
  162. {
  163.     WBool success;
  164.     
  165.     _displayWindow = displayWindow;
  166.     success = _thread.Create( this,
  167.                               (WThreadRoutine)&@CLASSNAME@::Server,
  168.                               NULL );
  169.     if( success ) {
  170.         _displayWindow->AddLog( WTEXT( "Created server thread." ) );
  171.     }
  172.     return success;
  173. }
  174.  
  175. @end-code;
  176.  
  177. @begin-code Code "ServerWorker::Prototype for Create( Form1 * displayWindow )"
  178.  
  179.     public:
  180.         WBool Create( Form1 * displayWindow );
  181.  
  182. @end-code;
  183.  
  184. @begin-code Code "ServerWorker::Destroy()"
  185.  
  186. WBool @CLASSNAME@::Destroy()
  187. {
  188.     WBool result;
  189.     
  190.     _dyingNow = TRUE;
  191.     result = _server_sock->Close( TRUE, 1 );
  192.     _thread.Wait();
  193.     if( result ) {
  194.         _displayWindow->AddLog( WTEXT( "Server thread gracefully done." ) );
  195.     }
  196.     return TRUE;
  197. }
  198.  
  199. @end-code;
  200.  
  201. @begin-code Code "ServerWorker::Prototype for Destroy()"
  202.  
  203.     public:
  204.         WBool Destroy();
  205.  
  206. @end-code;
  207.  
  208. @begin-code Code "ServerWorker::Server( void * )"
  209.  
  210. WDWord @CLASSNAME@::Server( void * )
  211. {
  212.     WSocket         client;
  213.     WSocket         *new_client;
  214.     ClientWorker    *client_worker;
  215.     WBool           success;
  216.     WInt            i;
  217.     WString         msg;
  218.     
  219.     WCurrentThread::SetName( WTEXT( "Chat Server" ) );
  220.     
  221.     /*  Create and initialize the server socket
  222.     */
  223.     _server_sock = new WServerSocket();
  224.     if( _server_sock == NULL ) {
  225.         _displayWindow->AddLog( WTEXT( "Could not create server socket!" ) );
  226.         return 0;
  227.     }
  228.     if( !_server_sock->Create() ) {
  229.         _displayWindow->AddLog( WTEXT( "Could not create server socket!" ) );
  230.         return 0;
  231.     }
  232.     if ( !_server_sock->SetLocalPort( 1777 ) ) {
  233.         _displayWindow->AddLog( WTEXT( "Could not set local port!" ) );
  234.         return 0;
  235.     }
  236.     _server_sock->Listen();
  237.   //if( _server_sock->Listen() == 0 ) {
  238.         msg.Sprintf( WTEXT("Server %s listening on port 1777."),
  239.                      _server_sock->GetLocalHostName().GetText() );
  240.         _displayWindow->AddLog( msg );
  241.   //} else {
  242.   //    _server_sock->Close( FALSE );
  243.   //    _displayWindow->AddLog( WTEXT( "Listen failed!" ) );
  244.   //    return 0;
  245.   //}
  246.     
  247.     /*  Process requests
  248.     */
  249.     while( TRUE ) {
  250.         /*  Wait for a chat client to connect to the server
  251.         */
  252.         _displayWindow->AddLog( WTEXT( "Waiting for connection..." ) );
  253.         client = _server_sock->Accept();
  254.         if( _dyingNow ) {
  255.             _displayWindow->AddLog( WTEXT( "Server shutting down." ) );
  256.             break;
  257.         }
  258.         if( _server_sock->GetState() == WSockStateError ) {
  259.             msg.Sprintf( WTEXT( "Server shutting down.  Error %d."),
  260.                          _server_sock->GetLastError() );
  261.             _displayWindow->AddLog( msg.GetText() );
  262.             break;
  263.         }
  264.  
  265.         /*  Open a socket to talk back to the client
  266.         */
  267.         success = FALSE;
  268.         new_client = new WSocket( client );
  269.         if( new_client == NULL ) {
  270.             _displayWindow->AddLog( WTEXT( "Invalid connection." ) );
  271.         } else {
  272.             _displayWindow->AddLog( WTEXT( "Connected." ) );
  273.             _client_sockets_cs.Enter();
  274.             i = _client_sockets.Append( new_client );
  275.             client_worker = new ClientWorker();
  276.             if( client_worker != NULL ) {
  277.                 _client_workers.Append( client_worker );
  278.                 success = TRUE;
  279.             } else {
  280.                 new_client->Close( FALSE );
  281.                 _client_sockets.RemoveAt( i );
  282.                 delete new_client;
  283.             }
  284.             _client_sockets_cs.Exit();
  285.         }
  286.         
  287.         /*  Spawn a new thread to handle client interaction
  288.         */
  289.         if( success ) {
  290.             success = client_worker->Create( _displayWindow, i );
  291.             if( success ) {
  292.                 msg.Sprintf( WTEXT( "Client %d started." ), i );
  293.                 _displayWindow->AddLog( msg.GetText() );
  294.             } else {
  295.                 new_client->Close( FALSE );
  296.                 _client_sockets_cs.Enter();
  297.                 _client_sockets.RemoveAt( i );
  298.                 _client_workers.RemoveAt( i );
  299.                 _client_sockets_cs.Exit();
  300.                 delete new_client;
  301.                 delete client_worker;
  302.             }
  303.         }
  304.     }
  305.     return 0;
  306. }
  307.  
  308. @end-code;
  309.  
  310. @begin-code Code "ServerWorker::Prototype for Server( void * )"
  311.  
  312.     private:
  313.         WDWord Server( void * );
  314.  
  315. @end-code;
  316. @end;
  317.