diff options
Diffstat (limited to 'docs/tutorials/001/page04.html')
-rw-r--r-- | docs/tutorials/001/page04.html | 210 |
1 files changed, 0 insertions, 210 deletions
diff --git a/docs/tutorials/001/page04.html b/docs/tutorials/001/page04.html deleted file mode 100644 index 079947a3b3a..00000000000 --- a/docs/tutorials/001/page04.html +++ /dev/null @@ -1,210 +0,0 @@ -<!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> "<font color=green>ace/Event_Handler.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>ace/INET_Addr.h</font>" - -<font color=red>/* - Since we're doing TCP/IP, we'll need a SOCK_Stream for the connection. - */</font> -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" - -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. - */</font> - char buf[128]; - memset(buf,0,sizeof(buf)); - - <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> - switch( this->cli_stream_.recv(buf,sizeof buf) ) - { - 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: - 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> |