diff options
Diffstat (limited to 'docs/tutorials/004/page01.html')
-rw-r--r-- | docs/tutorials/004/page01.html | 401 |
1 files changed, 0 insertions, 401 deletions
diff --git a/docs/tutorials/004/page01.html b/docs/tutorials/004/page01.html deleted file mode 100644 index 00eab3dd08a..00000000000 --- a/docs/tutorials/004/page01.html +++ /dev/null @@ -1,401 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 004</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 004</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>A much more clever Client</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Ok, so the last time around, we learned how to create a simple client -that can send a chunk of data. A cooler thing to do is to overload -the C++ put operator (<<) to put some data for us. That's -what we're going to do this time. (This tutorial is actually where -ACE_IOStream was born.) - -<P> -<HR WIDTH="100%"> - -<P>The code: -<UL> -<PRE> -1. #include "ace/SOCK_Connector.h" -2. #include "ace/SString.h" - -3. class Client : public ACE_SOCK_Stream - { - - public: -4. Client(void); -5. Client( const char * server, u_short port ); - -6. int open( const char * server, u_short port ); - -7. inline int initialized(void) { return mInitialized; } -8. inline int error(void) { return mError; } - -9. Client & operator<<( ACE_SString & str ); -10. Client & operator<<( char * str ); -11. Client & operator<<( int n ); - - protected: - - private: -12. unsigned char mInitialized; -13. unsigned char mError; - - }; - -14. Client::Client(void) - { -15. mInitialized = 0; -16. mError = 0; - } - -17. Client::Client( const char * server, u_short port ) - { -18. mInitialized = 0; -19. mError = 0; -20. (void)open(server,port); - } - -21. int Client::open( const char * server, u_short port ) - { -22. ACE_SOCK_Connector connector; -23. ACE_INET_Addr addr (port, server); - -24. if (connector.connect (*this, addr) == -1) - { -25. ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - -26. mInitialized = 1; - -27. return(0); - } - -28. Client & Client::operator<<( ACE_SString & str ) - { -29. if( initialized() && ! error() ) - { -30. char * cp = str.rep(); - -31. mError = 0; - -32. if( this->send_n(cp,strlen(cp)) == -1 ) - { -33. mError = 1; - } - } -34. else - { -35. mError = 1; - } - -36. return *this ; - } - -37. Client & Client::operator<< ( char * str ) - { -38. ACE_SString newStr(str); - -39. *this << newStr; - -40. return *this ; - } - -41. Client & Client::operator<< ( int n ) - { - // ACE_SString newStr; - // newStr = n; - -42. char buf[1024]; -43. sprintf(buf,"(%d)\n",n); -44. ACE_SString newStr(buf); - -45. *this << newStr; - -46. return *this; - } - -47. int main (int argc, char *argv[]) - { -48. const char *server_host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; -49. u_short server_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; -50. int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : 4; - -51. Client server(server_host,server_port); - -52. if( ! server.initialized() ) - { -53. ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "intialization"), -1); - } - - -54. for (int i = 0; i < max_iterations; i++) - { -55. server << "message = " << i+1; - -56. if ( server.error() ) - { -57. ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); - } -58. else - { -59. ACE_OS::sleep (1); - } - } - -60. if (server.close () == -1) - { -61. ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); - } - -62. return 0; - }</PRE> -</UL> - -<HR WIDTH="100%"> - -<P>Now, the code description: -<BR> -<OL> -<LI> -Get the SOCK Connector header</LI> - -<LI> -and pickup a simple string class while we're at it.</LI> - -<LI> -Create a simple derivative of ACE_SOCK_Stream. This is where we'll -add our put methods for sending the data to our server. Another approach -would have been to simply have an ACE_SOCK_Stream as a member variable.</LI> - -<LI> -Boring constructor.</LI> - -<LI> -Construct and open() all at once.</LI> - -<LI> -Open the connection to the server.</LI> - -<LI> -Are we connected to the server?</LI> - -<LI> -Have we had an error?</LI> - -<LI> -Send a string object to the server</LI> - -<LI> -Send a "C" string to the server</LI> - -<LI> -Send an integer to the server</LI> - -<LI> -Intialization flag</LI> - -<LI> -Error flag</LI> - -<LI> -The boring constructor</LI> - -<LI> -sets the initialization flag</LI> - -<LI> -and the error flag to "false".</LI> - -<LI> -The more exciting constructor</LI> - -<LI> -sets the initialization flag</LI> - -<LI> -and the error flag to false.</LI> - -<LI> -But then it invokes open() to get us to the server.</LI> - -<LI> -The open() method will connect us across the wire.</LI> - -<LI> -First we need an ACE_SOCK_Connector (since we like sockets)</LI> - -<LI> -And then we need an address which we can connect to. I suppose I -should have made the args to open() match those of the ACE_INET_Addr -constructor...</LI> - -<LI> -Attempt to connect ourselves to the server. Since we're a derivative -of ACE_SOCK_Connector, it's legal to pass <I>this</I> to the connect() -method.</LI> - -<LI> -As usual, failure results in a message and a bad return code. Rememer -that <I>mInitialized</I> will still be set to false indicating that we're -not connected. We should proabably also set <I>mError</I> to true.</LI> - -<LI> -All is well, mark our selves as ready to go!</LI> - -<LI> -Return our typical success value. (Unix folks will recognize this -as fairly standard behavior: 0 indicates success, anything else is -an error code.)</LI> - -<LI> -Now we start to have some fun! Lets figure out how to "stream" a -string object.</LI> - -<LI> -First we have to make sure that we're connected and in good health.</LI> - -<LI> -Next, we get a character pointer to the string we want to send.</LI> - -<LI> -No errors so far...</LI> - -<LI> -Use our old friend <I>send_n()</I> to send the data at the pointer. -Use strlen() to figure out how many bytes to send.</LI> - -<LI> -Oops!</LI> - -<LI> -Ok, ok... if we're incapable of sending data</LI> - -<LI> -then this must be an error.</LI> - -<LI> -The put operator has to return a reference to itself so that we can string -them together: foobar << this << that</LI> - -<LI> -Now, how about sending a character pointer?</LI> - -<LI> -We're going to cheat and use the method we just wrote. The more sensible -thing would have been to write it in terms of <I>this</I> method.</LI> - -<LI> -Send the string we just created.</LI> - -<LI> -And again return ourselves.</LI> - -<LI> -Sending the <I>char *</I> was easy since it's really just a block of contiguous -data. But how do we send an integer? Part of the point in using -the put operator is to convert the stuff to text instead of binary.</LI> - -<LI> -So... create a temporary data buffer</LI> - -<LI> -stuff our number into it</LI> - -<LI> -and then create yet another string object.</LI> - -<LI> -Now, we already know how to send those.</LI> - -<LI> -And we're done!</LI> - -<LI> -Finally, we get to the program entry point.</LI> - -<LI> -Set the hostname we'll talk to</LI> - -<LI> -and then choose the port</LI> - -<LI> -and then decide how noisy to be.</LI> - -<LI> -Use the do-it-all constructor to go ahead and setup our connection.</LI> - -<LI> -Of course, it might have failed</LI> - -<LI> -and we have to complain and exit.</LI> - -<LI> -But if it worked, we start our <I>for</I> loop.</LI> - -<LI> -See how easy & intuitive it is to send stuff now? Just like -using <I>cerr</I> and <I>cout</I>!</LI> - -<LI> -Make sure everything is OK.</LI> - -<LI> -Sometimes it isn't.</LI> - -<LI> -But...</LI> - -<LI> -sometimes we can take a nap.</LI> - -<LI> -Shut it all down.</LI> - -<LI> -I guess it can fail too.</LI> - -<LI> -But now we're done.</LI> -</OL> - -<HR WIDTH="100%"> - -<P>Ok, now we're done with that. As you can see, it really isn't -so hard to create an object that makes sending data much more "natural" than -the typical send() invocation. You can even build up arbitrary objects -& do some neat tricks with C++ templates to stream their data -out as well. (We may go into that a little later.) Of course, -writting the full implementation such that these streams are interchangable -with the standard C++ ostreams is quite a bit more difficult. - -<P>As an exercise to the reader (don't you hate those!) I challenge -you to write the server side of this. You can take a look at -IOStream_Test in the ACE distribution if you get stuck... - -<P>If you want to compile it yourself, here's the <A HREF="client.cpp">source</A>, -the <A HREF="Makefile">Makefile</A>, and <A HREF="00SetEnv">Environment -settings</A>. - -<P> -<HR WIDTH="100%"> -<CENTER></CENTER> - -<CENTER>[<A HREF="../../tutorials">Tutorial Index</A>]</CENTER> - -</BODY> -</HTML> |