summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjcej <jcej@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-10-23 00:19:56 +0000
committerjcej <jcej@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-10-23 00:19:56 +0000
commit79f576a39064cf440305c4d83c4e0da8825432e0 (patch)
tree722fe714706ce3176f3c96f4d943e91ab17b7d40
parentc6c07c533f01572a7196f918852d63aa044733df (diff)
downloadATCD-79f576a39064cf440305c4d83c4e0da8825432e0.tar.gz
*** empty log message ***
-rw-r--r--docs/tutorials/015/Client_i.cpp60
-rw-r--r--docs/tutorials/015/Client_i.h74
-rw-r--r--docs/tutorials/015/Server_i.cpp71
-rw-r--r--docs/tutorials/015/Server_i.h52
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