summaryrefslogtreecommitdiff
path: root/docs/tutorials/015/page09.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/015/page09.html')
-rw-r--r--docs/tutorials/015/page09.html226
1 files changed, 0 insertions, 226 deletions
diff --git a/docs/tutorials/015/page09.html b/docs/tutorials/015/page09.html
deleted file mode 100644
index e85bb37813d..00000000000
--- a/docs/tutorials/015/page09.html
+++ /dev/null
@@ -1,226 +0,0 @@
-<!-- $Id$ -->
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="Author" CONTENT="James CE Johnson">
- <TITLE>ACE Tutorial 015</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER>
-
-<P>
-<HR WIDTH="100%">
-Like any other event handler, the handle_input() method will be
-responsible for getting data from the peer() and doing something with
-it. In this case, we have a Protocol_Stream to deal with. We'll use
-the stream for the actual I/O but we are ultimately responsible for
-processing the data from the peer. To do that, we've created a
-Handler_Task that fits within the Protocol_Stream framework to process
-data that has been received. Handler::handle_input() will tell the stream that
-it's time to read data and that data will eventually show up at
-Handler_Task::recv() where we'll process it as required by our
-application logic.
-<HR>
-<PRE>
-
-<font color=red>// $Id$</font>
-
-<font color=blue>#include</font> "<font color=green>Handler.h</font>"
-<font color=blue>#include</font> "<font color=green>Protocol_Task.h</font>"
-
-<font color=red>/* The Protocol_Stream gives us the option to insert a Protocol_Task
- to process data received by the stream. We'll get into the details
- more when we talk about the stream in detail. For now it's enough
- to know that <font color=#008888>Handler_Task::recv</font>() will be invoked by the stream
- after data from the client has been received and processed (eg --
- decrypted, uncompressed, and whatever else the protocol requires.)
-*/</font>
-class Handler_Task : public Protocol_Task
-{
-public:
-
- <font color=red>// Typical...</font>
- typedef Protocol_Task inherited;
-
- <font color=red>// Simple...</font>
- Handler_Task(void);
- ~Handler_Task(void);
-
-protected:
-
- <font color=red>// recv() is invoked after received data has been fully</font>
- <font color=red>// processed by the protocol rules. Data processing typically </font>
- <font color=red>// done in handle_input() can then be done here.</font>
- int recv(ACE_Message_Block * message,
- ACE_Time_Value *timeout = 0);
-};
-
-<font color=#008888>Handler::Handler</font>(void)
-{
- ;
-}
-
-<font color=#008888>Handler::~Handler</font>(void)
-{
- ;
-}
-
-<font color=red>/* The Acceptor will open() us once the peer() connection is
- established. There are a couple of things we have to do here
- before we're ready to receive data from the client.
-*/</font>
-int <font color=#008888>Handler::open</font> (void *)
-{
- ACE_INET_Addr addr;
-
- <font color=red>// Make sure that we can get the peer's address. If we can't</font>
- <font color=red>// then there may be a network error or something else that</font>
- <font color=red>// will prevent communicating with the client. This is</font>
- <font color=red>// something you'll want to do in every event handler you create.</font>
- if (this->peer ().get_remote_addr (addr) == -1)
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Cannot get remote addr\n</font>"), -1);
-
- <font color=red>// Announce the client</font>
- ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) connected with %s\n</font>", addr.get_host_name() ));
-
- <font color=red>// Here's the first new twist to the old event handler.</font>
- <font color=red>// Before we can use the Protocol_Stream to communicate with</font>
- <font color=red>// the peer, we must open() it. We provide the stream with</font>
- <font color=red>// the peer() so that it will have a valid socket on which to</font>
- <font color=red>// read client requests and send our responses. We also</font>
- <font color=red>// provide a Handler_Task instance that will ultimately be</font>
- <font color=red>// responsible for processing any client data we receive.</font>
- int rval = stream().open( this->peer(), new Handler_Task() );
-
- <font color=red>// Of course, we have to account for the chance that the</font>
- <font color=red>// stream's open() may fail.</font>
- if( rval == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Cannot open the protocol stream.\n</font>"), -1);
- }
-
- <font color=red>// Now that we know the client is valid and that the stream is </font>
- <font color=red>// ready for business we can register with the gloabl reactor</font>
- <font color=red>// instance. Here again is an opportunity for improvement if</font>
- <font color=red>// we expect to have mulitple Server object instances.</font>
- if (<font color=#008888>ACE_Reactor::instance</font>()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1)
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Cannot register with reactor\n</font>"), -1);
-
- return rval;
-}
-
-<font color=red>/* This is a fairly typical destroy() method that can be shared by
- both close() and handle_close().
-*/</font>
-void <font color=#008888>Handler::destroy</font> (void)
-{
- <font color=#008888>ACE_Reactor::instance</font>()->remove_handler(this,ACE_Event_Handler::READ_MASK|ACE_Event_Handler::DONT_CALL);
-
- this->peer ().close ();
-
- delete this;
-}
-
-<font color=red>/* In this simple application we just forward the close() and
- handle_close() requests right on to the destroy() method.
-*/</font>
-
-int <font color=#008888>Handler::close</font> (u_long)
-{
- this->destroy ();
- return 0;
-}
-
-int <font color=#008888>Handler::handle_close</font>(ACE_HANDLE, ACE_Reactor_Mask _mask)
-{
- this->destroy();
- return 0;
-}
-
-<font color=red>/* Unlike a "<font color=green>traditional</font>" handle_input() ours is very simple. Because
- of the use of the protocol stream, we delegate the read function to
- the stream's get() and rely on our Handler_Task to do the real work.
-*/</font>
-int <font color=#008888>Handler::handle_input</font> (ACE_HANDLE)
-{
- ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Activity from client\n</font>" ));
-
- <font color=red>// This will cause a blocking read from the peer(). The data</font>
- <font color=red>// will then be pushed through the protocol stream.</font>
- if( stream().get( ) == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Cannot get data from protocol stream\n</font>"), -1);
- }
-
- return 0;
-}
-
-<font color=red>/* A Protocol_Task is derived from ACE_Task and has the option of
- running in one or more threads. I've chosen here to construct the
- baseclass with no threads but it should work just fine with one or
- more if you need. Unless you're sharing the Handler_Task with
- several peers, however, you're probably just wasting a thread to
- activate it. On the other hand, if your reactor is running in a
- single thread (as in this example) then you can easily implement
- thread-per-connection concurrency by giving the baseclass one thread.
-*/</font>
-<font color=#008888>Handler_Task::Handler_Task</font>(void)
- : inherited()
-{
- ;
-}
-
-<font color=#008888>Handler_Task::~Handler_Task</font>(void)
-{
- ;
-}
-
-<font color=red>/* When installed into the protocol stream, the Handler_Task's recv()
- method will be called when data is ready for processing.
- */</font>
-int <font color=#008888>Handler_Task::recv</font>(ACE_Message_Block * message,
- ACE_Time_Value *timeout )
-{
- <font color=red>// Announce the request we got from the client</font>
- ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) <font color=#008888>Handler_Task::recv</font>() got (%s)\n</font>", message->rd_ptr() ));
-
- <font color=red>// Create a response message to send to the client</font>
- ACE_Message_Block * response = new ACE_Message_Block( 128 );
-
- <font color=red>// Nothing very original about this I'm afraid...</font>
- <font color=#008888>ACE_OS::sprintf</font>( response->wr_ptr(), "<font color=green>You Said: (%s)</font>", message->rd_ptr() );
- response->wr_ptr( strlen(response->wr_ptr())+1 );
-
- <font color=red>// Release the original message block now that we're through</font>
- <font color=red>// "<font color=green>processing</font>" it.</font>
- message->release();
-
- <font color=red>// Turn the message around and send it back down the Stream.</font>
- <font color=red>// In other words, we invoke the put() method on the</font>
- <font color=red>// Protocol_Stream without having to have a direct reference</font>
- <font color=red>// to the stream object.</font>
- return this->reply( response, timeout );
-}
-</PRE>
-<HR>
-<P>
-That's it for the server-specific code. I think I've been fairly
-successful in keeping it simple and to the point. There are a couple
-of places where the as-yet-undescribed Protocol_Stream pops up and may
-cause confusion. We're going to discuss that mystery now but before
-we do here's the list of server files if you want to review:
-
-<UL>
-<LI><A HREF="Makefile.server">Server Makefile</A>
-<LI><A HREF="server.cpp">server.cpp</A>
-<LI><A HREF="Server_i.h">Server_i.h</A>
-<LI><A HREF="Server_i.cpp">Server_i.cpp</A>
-<LI><A HREF="Handler.h">Handler.h</A>
-<LI><A HREF="Handler.cpp">Handler.cpp</A>
-</UL>
-<P>
-<P><HR WIDTH="100%">
-<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page10.html">Continue This Tutorial</A>]</CENTER>