diff options
author | jcej <jcej@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-10-23 00:19:56 +0000 |
---|---|---|
committer | jcej <jcej@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-10-23 00:19:56 +0000 |
commit | 79f576a39064cf440305c4d83c4e0da8825432e0 (patch) | |
tree | 722fe714706ce3176f3c96f4d943e91ab17b7d40 | |
parent | c6c07c533f01572a7196f918852d63aa044733df (diff) | |
download | ATCD-79f576a39064cf440305c4d83c4e0da8825432e0.tar.gz |
*** empty log message ***
-rw-r--r-- | docs/tutorials/015/Client_i.cpp | 60 | ||||
-rw-r--r-- | docs/tutorials/015/Client_i.h | 74 | ||||
-rw-r--r-- | docs/tutorials/015/Server_i.cpp | 71 | ||||
-rw-r--r-- | docs/tutorials/015/Server_i.h | 52 |
4 files changed, 257 insertions, 0 deletions
diff --git a/docs/tutorials/015/Client_i.cpp b/docs/tutorials/015/Client_i.cpp new file mode 100644 index 00000000000..6415fed1966 --- /dev/null +++ b/docs/tutorials/015/Client_i.cpp @@ -0,0 +1,60 @@ + +// $Id$ + +#include "Client_i.h" +#include "ace/Message_Block.h" +#include "ace/INET_Addr.h" +#include "ace/SOCK_Connector.h" + +// Simple constructor just remembers the endpoint information for use by open. +Client::Client( u_short _port, const char * _server) + : port_(_port), server_(_server) +{ + ; +} + +/* Do nothing. This should probably call close() if we can make sure + that it's OK to close() multiple times. +*/ +Client::~Client(void) +{ + ; +} + +/* Open the connection to the server. This is traditional ACE. We + simply construct an endpoint and use a connector to establish the + link. +*/ +int Client::open( void ) +{ + ACE_INET_Addr addr(port_,server_); + ACE_SOCK_Connector con; + + if( con.connect(peer(),addr) == -1 ) + { + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_SOCK_Connector::connect()"), -1); + } + + // Something new here... We have to use the protocol stream + // to ensure that our data is in the correct format when + // received by the server. Thus, we open the stream and + // transfer ownership of the peer. + return stream().open( peer() ); +} + +// The remainder of the functions just delegate to the stream. + +int Client::close( void ) +{ + return stream().close(); +} + +int Client::put( ACE_Message_Block * _message ) +{ + return stream().put(_message,0); +} + +int Client::get( ACE_Message_Block * & _response ) +{ + return stream().get(_response); +} diff --git a/docs/tutorials/015/Client_i.h b/docs/tutorials/015/Client_i.h new file mode 100644 index 00000000000..c9f4e496bf2 --- /dev/null +++ b/docs/tutorials/015/Client_i.h @@ -0,0 +1,74 @@ + +// $Id$ + +#ifndef CLIENT_H +#define CLIENT_H + +#include "ace/SOCK_Stream.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Protocol_Stream.h" + +class ACE_Message_Block; + +/* Hide the details of connection and protocol-conformance from the + application-level logic. +*/ +class Client +{ +public: + // Provide the server information when constructing the + // object. This could (and probably should) be moved to the + // open() method. + Client( u_short _port, const char * _server ); + + // Cleanup... + ~Client(void); + + // Open the connection to the server. + int open(void); + + // Close the connection to the server. Be sure to do this + // before you let the Client go out of scope. + int close(void); + + // Put a message to the server. The Client assumes ownership + // of _message at that point and will release() it when done. + // Do not use _message after passing it to put(). + int put( ACE_Message_Block * _message ); + + // Get a response from the server. The caller becomes the + // owner of _response after this call and is responsible for + // invoking release() when done. + int get( ACE_Message_Block * & _response ); + +private: + // Protocol_Stream hides the protocol conformance details from + // us. + Protocol_Stream stream_; + + // We create a connection on the peer_ and then pass ownership + // of it to the protocol stream. + ACE_SOCK_Stream peer_; + + // Endpoing information saved by the constructor for use by open(). + u_short port_; + const char * server_; + + // Accessors for the complex member variables. + + Protocol_Stream & stream(void) + { + return this->stream_; + } + + ACE_SOCK_Stream & peer(void) + { + return this->peer_; + } +}; + +#endif // CLIENT_H diff --git a/docs/tutorials/015/Server_i.cpp b/docs/tutorials/015/Server_i.cpp new file mode 100644 index 00000000000..dedbcd720f6 --- /dev/null +++ b/docs/tutorials/015/Server_i.cpp @@ -0,0 +1,71 @@ + +// $Id$ + +#include "Server_i.h" + +/* We have to allocate space for our static finished_ flag. We also + initialize it to 'false' so that we don't exit immediately. +*/ +sig_atomic_t Server::finished_ = 0; + +/* The simple constructor and destructor don't do anything but give us + a place to expand in the future if we want. +*/ +Server::Server(void) +{ + ; +} + +Server::~Server(void) +{ + ; +} + +/* Opening the server is as simple as opening the acceptor with the + default ACE_Reactor instance. If we want to allow multiple + instances of Server objects then we should have an ACE_Reactor + member variable that we can register with. +*/ +int Server::open(void) +{ + if (acceptor_.open (ACE_INET_Addr (ACE_DEFAULT_SERVER_PORT), ACE_Reactor::instance()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + + return(0); +} + +/* Running the server just means that we execute the basic event + loop for the reactor. Again, if we had a private reactor then we + could have multiple server's in their run() method. +*/ +int Server::run(void) +{ + ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server daemon\n")); + + ACE_Time_Value timeout(2); + + // Here's the basic event loop. I have a 2-second timeout on + // the handle_events() so that we don't have to wait too long + // when we set the finished_ flag. + while (!finished_) + { + ACE_Reactor::instance()->handle_events (&timeout); + } + + // Close the acceptor when we're done. This may be handled by + // the framework but it's good practice to be explicit about things. + acceptor_.close(); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server daemon\n")); + + return 0; +} + +/* The close() method simply sets the finished_ flag so that run() + will leave the event loop and exit. +*/ +int Server::close(void) +{ + finished_ = 1; + return(0); +} diff --git a/docs/tutorials/015/Server_i.h b/docs/tutorials/015/Server_i.h new file mode 100644 index 00000000000..6b1eecf05e5 --- /dev/null +++ b/docs/tutorials/015/Server_i.h @@ -0,0 +1,52 @@ + +// $Id$ + +#ifndef SERVER_H +#define SERVER_H + +#include "ace/Acceptor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/SOCK_Acceptor.h" +#include "Handler.h" + +/* Anytime I have templates I try to remember to create a typedef for + the parameterized object. It makes for much less typing later! +*/ +typedef ACE_Acceptor < Handler, ACE_SOCK_ACCEPTOR > Acceptor; + +class Server +{ +public: + // Our simple constructor takes no parameters. To make the + // server a bit more useful, you may want to pass in the + // TCP/IP port to be used by the acceptor. + Server(void); + ~Server(void); + + // Open the server for business + int open(void); + + // Close all server instances by setting the finished_ flag. + // Actually, the way this class is written, you can only have + // one instance. + static int close(void); + + // Run the server's main loop. The use of the gloabl + // ACE_Reactor by this method is what limits us to one Server + // instance. + int run(void); + +private: + // This will accept client connection requests and instantiate + // a Handler object for each new connection. + Acceptor acceptor_; + + // Our shutdown flag + static sig_atomic_t finished_; +}; + +#endif // SERVER_H |