diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1998-08-30 23:53:37 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1998-08-30 23:53:37 +0000 |
commit | 4d8c4ec1bac03da1426aea54e6c9e56ce95683a6 (patch) | |
tree | 8214f09a9b730000f2fdf5a68bda8c6f384c01a5 /docs | |
parent | 890e81acbee4c4a7f2b0102b8ecf755de473831c (diff) | |
download | ATCD-4d8c4ec1bac03da1426aea54e6c9e56ce95683a6.tar.gz |
*** empty log message ***
Diffstat (limited to 'docs')
-rw-r--r-- | docs/tutorials/index.html | 20 | ||||
-rw-r--r-- | docs/tutorials/page03.html | 285 |
2 files changed, 10 insertions, 295 deletions
diff --git a/docs/tutorials/index.html b/docs/tutorials/index.html index 8b623c201db..03c32c3d4cc 100644 --- a/docs/tutorials/index.html +++ b/docs/tutorials/index.html @@ -8,15 +8,15 @@ <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> <HR> -<H3> -ACE Tutorials</H3> +<H3>ACE Tutorials</H3><P> -<HR WIDTH="100%">The original audience for these tutorials was the <A HREF="http://www.lads.com">Automated -Design Systems</A> (ADS) IPC team, lead by <A HREF="mailto:jcej@lads.com">James -Johnson</A>. Since then, the scope has been changed to include anyone who -wants to learn about the ACE framework. Hopefully, even experienced ACE -programmers will find something new here. With a framework as encompassing -as ACE, it is easy to become an expert in one area and know little or nothing +<HR WIDTH="100%">The original audience for these tutorials was the <A +HREF="http://www.lads.com">Automated Design Systems</A> (ADS) IPC +team, lead by <A HREF="mailto:jcej@lads.com">James Johnson</A>. Since +then, the scope has been changed to include anyone who wants to learn +about the ACE framework. Hopefully, even experienced ACE programmers +will find something new here. With a framework as encompassing as ACE, +it is easy to become an expert in one area and know little or nothing about others. <P> @@ -58,10 +58,10 @@ In the early stages, these tutorials won't address The ACE ORB (<A HREF="http:// However, if you want to request a tutorial on some aspect of TAO or even create one yourself, I'll be glad to integrate those into these tutorials. It's rare when folks want to write documentation, so nothing will be refused! -<BR> +<P> <HR WIDTH="100%"> <H3> -The Tutorials</H3> +The Tutorials</H3><P> <UL> <H4> diff --git a/docs/tutorials/page03.html b/docs/tutorials/page03.html deleted file mode 100644 index 836ba7c1ea8..00000000000 --- a/docs/tutorials/page03.html +++ /dev/null @@ -1,285 +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> - -<P> -<HR WIDTH="100%"></P> - -<P>Now we begin to look at the acceptor object.</P> - -<P>I will present the entire object header file first and then disect it -as with <I>main()</I>.</P> - -<UL> -<PRE>1. #include <stdio.h> - -2. #include "ace/Reactor.h" -3. #include "ace/Event_Handler.h" -4. #include "ace/SOCK_Acceptor.h" -5. #include "ace/SOCK_Stream.h" -6. #include "ace/INET_Addr.h" - -7. #include "logger.h" - - -8. extern ACE_Reactor g_reactor; - -9. class Client_Acceptor : public ACE_Event_Handler - { - -10. public : - -11. Client_Acceptor( const ACE_INET_Addr &addr) : acceptor_(addr) { -12. if( ! (fp = fopen("acceptor","w+")) ) -13. fp = stderr; - -14. fprintf(fp,"Constructed\n"); - } - -15. virtual int handle_exception(ACE_HANDLE handle) - { -16. fprintf(fp,"Exception\n"); -17. return(-1); - } - -18. virtual int handle_input(ACE_HANDLE handle) - { -19. ACE_SOCK_Stream new_connection; - -20. this->acceptor_.accept(new_connection); - -21. Logging_Handler *cli_handler = new Logging_Handler(new_connection); - -22. fprintf(fp,"Got New Connection\n"); - -23. int foo = g_reactor.register_handler(cli_handler,ACE_Event_Handler::RWE_MASK); -24. return( foo ); - } - -25. virtual ACE_HANDLE get_handle(void) const - { -26. fprintf(fp,"Providing Handle\n"); -27. return this->acceptor_.get_handle(); - } - -28. virtual void handle_close(void) - { -29. this->acceptor_.close(); -30. fprintf(fp,"Closing\n"); - } - -31. private : -32. ACE_SOCK_Acceptor acceptor_; -33. FILE * fp; -34. }; - -</PRE> -</UL> - -<P>Here's a blow-by-blow account of what's being done:</P> - -<OL START=1> -<LI>Include the standard I/O system header file. I only need this -so that I can use <I>fprintf</I> stuff for the logging function. In -reality we would probably talk to a database or something.</LI> - -<LI>Bring in the ACE headers. Don't worry about the details here.</LI> -</OL> - -<OL START=7> -<LI>Bring in the definition of the <I>logger</I> object. The logger will -handle connections after our acceptor has accepted the connection. We'll -look at that on the next page.</LI> - -<LI>Provide quick access to the reactor object. Later tutorials will be -more clever than this...</LI> - -<LI>Derive our new acceptor object from the ACE_Event_Handler base-class. -The event handler object is designed to work with the reactor. When an -event handler is registered with a reactor, the reactor uses member functions -of the event handler object to gain access to the underlying connection -<I>handle.</I> We saw this registration process in the previous example -when the acceptor object was registered with the reactor in the <I>main()</I> -function. On Unix-type systems, the reactor will then use the <I>select</I> -system call to wait for activity on the handle (on Win32, <I>WaitForMultipleObjects</I> -is used instead). Once activity is detected on the handle by the reactor, -different member functions of the event handler are invoked to process -the activity. We'll see these in the lines below.</LI> - -<LI>Most of the object is going to be public. When we get a little better -at what we're doing, we can try to make it safer by declaring some of these -protected. Most of them can never be private however. Notice at this point -how each of the functions is declared to be a virtual. This MUST be done -so that if we later derive a class from here the runtime environment will -get the member function of the derived class instead of that of the baseclass.</LI> - -<LI>The object constructor is the only non-virtual function. We may find -out later that it should have been virtual! Anyway, we take the single -parameter, a reference to an address object, and use it to initialize our -<I>acceptor_</I> object. This is the object which will actually listen -for client connections. There is a discussion below about why the Acceptor -is a member of our object rather than it's base class.</LI> - -<LI>Remove the gag from the object by giving it somewhere to write debug -information to. We'll use this file pointer throughout the object to keep -track of it's internal activities.</LI> - -<LI>Fall back to <I>stderr</I> if we failed to open our output file.</LI> - -<LI>Status message (duh).</LI> - -<LI>The <I>handle_exception</I> member function will be called by the reactor -if an exception is noticed on the handle associated with this object. In -the case of a connected socket, an exception is generally caused when the -remote side closes the connection. In the case of a listening socket, it -could indicate som rare and strange network failure. See the <I>man</I> -pages for <I>accept</I> and <I>listen</I> if you really care. For our purposes, -if we get an exception on our acceptor then we return <I>-1</I> to the -reactor which tells it we're out of commission. At that point the reactor -will invoke our <I>close</I> funtion and shut us down.</LI> - -<LI>Display notification of the error.</LI> - -<LI>Return -1 to tell the reactor that we should be shut down.</LI> - -<LI>The <I>handle_input</I> method is called by the reactor whenever our -handle has some data available for us to process. The actual handle is -passed into the function but we won't be using it because we know it MUST -be the <I>acceptor_</I> member object. We could compare the two as a safety -check though.</LI> - -<LI>Now we are creating a new connection. It will be this connection which -we use to communicate with the client. This will free up the acceptor to -listen for more connection requests. Because the acceptor as a <I>SOCK -</I>type object we need to create the connection as a <I>SOCK</I> also. -An <I>ACE_SOCK_Stream</I> will provide us with an end-to-end connection -similar to a pipe. This gives us the guarantee that any data we send or -receive will be complete and in the correct order. An <I>ACE_SOCK_Dgram</I> -could be used if we don't mind missing some packets or receiving them out -of order.</LI> - -<LI>The <I>acceptor_</I> member object is now told to accept the client -connection and attach it to the new <I>ACE_SOCK_Stream</I> object we just -created. This is what frees up the acceptor to listen for more new connections. -If you don't <I>accept</I> the connection, you cannot read the client's -data and new clients cannot connect. In fact, after a timeout, the client -which caused this <I>handle_input</I> callback will give up and assume -the connection failed.</LI> - -<LI>Up to this point, we haven't done anything very specific with regards -to our application. Here, however, we finally create a <I>logger</I> object -to handle the connection. The logger object is something we defined in -<I>logger.h</I>. It is given an <I>ACE_SOCK_Stream</I> object on which -it will communicate. This is the <B>only</B> application-specific code -you will find in the <I>Client_Acceptor</I> object we are developing here.</LI> - -<LI>Announce the new connection. We could use member functions of <I>new_connection</I> -to report either of the local and remote systems' addresses and names.</LI> - -<LI>Finally, we register our <I>Logging_Handler</I> with our reactor. This -tells the reactor about our new connection and tells it who to inform when -there is activity on the connection. Note that we use the <I>RWE</I> mask -so that we get notification when the connection has data for us to read, -is available for us to write upon* and when it takes an error. (* Because -of network buffers and such, you can't necessarily write on a connection -anytime you want. At times, a <I>write</I> operation on a connection will -fail or partially fail due to full buffers or some other network issue. -When that happens, you must cache the remaining data to be written and -wait for the write-notification event.)</LI> - -<LI>Return the result of registering the new connection. If the registration -failed for some reason, this will cause the <I>handle_input</I> to fail -and, ultimately, shut down the server. There is probably a much better -way to handle this but it serves our purposes at the moment.</LI> - -<LI><I>get_handle</I> provides an interface layer between the reactor with -which we're registered and the connection we wish the reactor to operate -on. The reactor does it's job by monitoring one or more <I>handles</I>. -In the Unix world, these are simply file descriptors. The <I>get_handle</I> -method of a communcations object such as our <I>acceptor_</I> returns the -underlying socket file descriptor associated with the connection. Because -other OSes work differently, however, the <I>get_handle</I> method provides -insulation for the programmer. By doing this, the programmer has the option -of registering many types of objects with a reactor: disk-based file, serial -port, intra-process pipes, etc...</LI> - -<LI>Progress notification.</LI> - -<LI>Return the handle of the actual communcation's object.</LI> - -<LI>Similar to <I>get_handle</I>, the <I>handle_close</I> is a wrapper -that allows the reactor to close a connection object. Again, this does -not have to be an IPC object, it could be anything that supports basic -open/read/write/close functionality. What we're doing here is shutting -down the acceptor. You would do this when you want to bring down or pause -the server.</LI> - -<LI>Perform the actual close operation.</LI> - -<LI>Another notification</LI> - -<LI>Now we begin our brief section of private data. In a real application -this might be <I>protected</I> instead so that a derived object would have -direct access to the data members. On the other hand, we may not want that...</LI> - -<LI>The <I>acceptor_</I> member object is where all of the action centers. -It is this object which abstracts all of the socket-level mess necessary -to listen for client connection requests.</LI> - -<LI>The file pointer is our simple way of reporting progress throught the -program and logging activity from the client.</LI> - -<LI>All Done.</LI> -</OL> - -<P>It is important to notice here that we have done very little application-specifc -code in developing this object. In fact, if we take out the progress information, -the only app-specific code is when we create the new <I>Logging_Handler</I> -object to give to the <I>accept</I> function. You may begin to wonder why -there isn't a C++ template that does all of this coding for you. Actually, -the ACE toolkit happens to have one handy:</P> - -<UL> -<P>typedef ACE_Acceptor <<I>YourHandlerClass</I>, ACE_SOCK_ACCEPTOR> -<I>YourAcceptorClass</I>;</P> -</UL> - -<P>We would have used it like this:</P> - -<UL> -<P>typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor;</P> -</UL> - -<P>This will create a piece of code similar to what I've shown above. The -primary difference is that the <I>handle_input </I>function created by -the template does NOT register the handler with the reactor. In the long-run, -that is good for us because we can then move that logic into the <I>open</I> -function of the <I>Logging_Handler</I> and use a completely-generic acceptor.</P> - -<P>Now that we know how to accept a connection request, let's move on to -the next page where we learn how to handle the actual connection. Even -though we just learned about this cool template thing, we will continue -to use the "hand-written" acceptor developed above. As I mentioned, -the only difference will be in the <I>open</I> function of the connection -handler anyway.</P> - -<P> -<HR WIDTH="100%"></P> - -<CENTER><P>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page02.html">Previous -Page</A>] [<A HREF="page04.html">Continue -This Tutorial</A>] </P></CENTER> - -</BODY> -</HTML> |