diff options
Diffstat (limited to 'docs/tutorials/001/page04.html')
-rw-r--r-- | docs/tutorials/001/page04.html | 213 |
1 files changed, 0 insertions, 213 deletions
diff --git a/docs/tutorials/001/page04.html b/docs/tutorials/001/page04.html deleted file mode 100644 index aa420c45f50..00000000000 --- a/docs/tutorials/001/page04.html +++ /dev/null @@ -1,213 +0,0 @@ -<!-- $Id$ --> -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> - <TITLE>ACE Tutorial 001</TITLE> - <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> - -<hr> -<P>Now we begin to look at the <A HREF="logger.h">logger</A> -object. - -<P> -<HR> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>_CLIENT_HANDLER_H</font> -<font color=blue>#define</font> <font color=purple>_CLIENT_HANDLER_H</font> - -<font color=red>/* A connection handler will also be derived from ACE_Event_Handler so - that we can register with a reactor. */</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/Event_Handler.h">ace/Event_Handler.h</A>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -<font color=blue># pragma</font> <font color=purple>once</font> -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/INET_Addr.h">ace/INET_Addr.h</A>" - -<font color=red>/* Since we're doing TCP/IP, we'll need a SOCK_Stream for the - connection. */</font> -<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Stream.h">ace/SOCK_Stream.h</A>" - -class Logging_Handler : public ACE_Event_Handler -{ -public: - <font color=red>/* - Like the acceptor, we're simple enough to avoid constructor and destructor. - */</font> - - <font color=red>/* To open the client handler, we have to register ourselves with - the reactor. Notice that we don't have to "<font color=green>open</font>" our - ACE_SOCK_Stream member variable. Why? Because the call to the - acceptor's accept() method took care of those details for us. */</font> - - int open (ACE_Reactor *reactor) - { - <font color=red>/* - Remember our reactor... - */</font> - reactor_ = reactor; - - <font color=red>/* In this case we're using the READ_MASK. Like the acceptor, - handle_input() will be called due to this mask but it's a nice - piece of bookkeeping to have separate masks for the separate - types of activity. */</font> - - if (reactor->register_handler (this, - <font color=#008888>ACE_Event_Handler::READ_MASK</font>) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>(%P|%t) can't register with reactor\n</font>"), - -1); - return 0; - } - - <font color=red>/* If we're explicitly closed we'll close our "<font color=green>file handle</font>". The - net result is to close the connection to the client and remove - ourselves from the reactor if we're registered */</font> - - int close (void) - { - return this->handle_close (ACE_INVALID_HANDLE, - <font color=#008888>ACE_Event_Handler::RWE_MASK</font>); - } - - <font color=red>/* This is a bit of magic... When we call the accept() method of - the acceptor object, it wants to do work on an ACE_SOCK_Stream. - We have one of those as our connection to the client but it would - be gross to provide a method to access that object. It's much - cooler if the acceptor can just treat the Logging_Handler as an - ACE_SOCK_Stream. Providing this cast operator lets that happen - cleanly. */</font> - - operator ACE_SOCK_Stream &() - { - return this->cli_stream_; - } - -protected: - - <font color=red>/* Again, like the acceptor, we need to provide the connection - handle to the reactor. */</font> - - ACE_HANDLE get_handle (void) const - { - return this->cli_stream_.get_handle (); - } - - <font color=red>/* And here's the handle_input(). This is really the workhorse of - the application. */</font> - - virtual int handle_input (ACE_HANDLE) - { - <font color=red>/* - Create and initialize a small receive buffer. The extra byte is - there to allow us to have a null-terminated string when it's over. - */</font> - char buf[BUFSIZ + 1]; - - <font color=red>/* Invoke the recv() method of the ACE_SOCK_Stream to get some - data. It will return -1 if there is an error. Otherwise, it - will return the number of bytes read. Of course, if it read - zero bytes then the connection must be gone. How do I know - that? Because handle_input() would not be called by the reactor - if there wasn't *some* kind of activity and a closed connection - looks like a read request to the reactor. But when you read - from a closed connection you'll read zero bytes. - - Notice that in the error case or closed case we return -1. That - tells the reactor to call our handle_close() where we'll take - care of shutting down cleanly. - - Although we don't make use of them, there are additional - parameters you can use with the recv() call. One of these is an - ACE_Time_Value that allows you to limit the amount of time - blocking on the recv(). You would use that if you weren't sure - if data was available. Since we only get to handle_input() when - data is ready, that would be redundant. On the other hand, if - you use recv_n() to read *exactly* a number of bytes then - limiting the time you wait for those bytes might be good. The - other paramter that may come in handy is an integer - <i>flags</i>. This is passed directly to the underlying OS - recv() call. See the man page recv(2) and the header - sys/socket.h for the gory details. */</font> - - ssize_t retval; - switch (retval = this->cli_stream_.recv (buf, BUFSIZ)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>(%P|%t) %p bad read\n</font>", - "<font color=green>client logger</font>"), - -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>(%P|%t) closing log daemon (fd = %d)\n</font>", - this->get_handle ()), - -1); - default: - buf[retval] = '\0'; - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) from client: %s</font>", - buf)); - } - - return 0; - } - - <font color=red>/* When handle_input() returns -1, we'll end up here. There are a - few housekeeping chores to handle. */</font> - - int handle_close (ACE_HANDLE, - ACE_Reactor_Mask _mask) - { - <font color=red>/* Remove ourselves from the reactor. We have to include the - DONT_CALL in the mask so that it won't call handle_close() on us - again! */</font> - reactor_->remove_handler (this, - _mask | <font color=#008888>ACE_Event_Handler::DONT_CALL</font>); - - <font color=red>/* Close the socket that we're connected to the client with. */</font> - cli_stream_.close (); - - <font color=red>/* Since we know we were dynamically allocated by the acceptor, - now is a good time to get rid of ourselves. */</font> - delete this; - - return 0; - } - -protected: - - <font color=red>/* Our peer connection. */</font> - ACE_SOCK_Stream cli_stream_; - - <font color=red>/* Our reactor (and our acceptor's reactor). */</font> - ACE_Reactor *reactor_; -}; - -<font color=blue>#endif</font> <font color=red>/* _CLIENT_HANDLER_H */</font> - -</PRE> -<HR WIDTH="100%"> - -<P> -The comments really should tell the story. The really -interesting stuff is in <i>handle_input()</i>. Everything -else is just housekeeping. -In the future, we'll learn about ACE_Svc_Handler<> -which will take care of most of the housekeeping for us. -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> - |