diff options
Diffstat (limited to 'docs/tutorials/008')
-rw-r--r-- | docs/tutorials/008/Makefile | 59 | ||||
-rw-r--r-- | docs/tutorials/008/broadcast_client.cpp | 72 | ||||
-rw-r--r-- | docs/tutorials/008/directed_client.cpp | 112 | ||||
-rw-r--r-- | docs/tutorials/008/page01.html | 60 | ||||
-rw-r--r-- | docs/tutorials/008/page02.html | 237 | ||||
-rw-r--r-- | docs/tutorials/008/page03.html | 187 | ||||
-rw-r--r-- | docs/tutorials/008/page04.html | 156 | ||||
-rw-r--r-- | docs/tutorials/008/page05.html | 43 | ||||
-rw-r--r-- | docs/tutorials/008/server.cpp | 128 |
9 files changed, 0 insertions, 1054 deletions
diff --git a/docs/tutorials/008/Makefile b/docs/tutorials/008/Makefile deleted file mode 100644 index 356d7f32f5f..00000000000 --- a/docs/tutorials/008/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = server directed_client broadcast_client - -FILES = - -BUILD = $(VBIN) - -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - - # Don't put anything below here. Between the "depend" target and fix.Makefile - # it's guaranteed to be lost! - - # This is inserted by the fix.Makefile script -include .depend diff --git a/docs/tutorials/008/broadcast_client.cpp b/docs/tutorials/008/broadcast_client.cpp deleted file mode 100644 index 2f754806d03..00000000000 --- a/docs/tutorials/008/broadcast_client.cpp +++ /dev/null @@ -1,72 +0,0 @@ - -// $Id$ - -#include "ace/SOCK_Dgram_Bcast.h" -#include "ace/INET_Addr.h" - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main(int argc,char *argv[] ) -{ - ACE_INET_Addr local((u_short)0); - - /* - Instead of creating the ACE_SOCK_Dgram we created last time, - we'll create an ACE_SOCK_Dgram_Bcast. "Bcast" means, of course, - "Broadcast". This ACE object is clever enough to go out to the - OS and find all of the network interfaces. When you send() - on a Dgram_Bcast, it will send the datagram out on all of those - interfaces. This is quiet handy if you do it on a multi-homed - host that plays router... - */ - ACE_SOCK_Dgram_Bcast dgram; - - if( dgram.open(local) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "datagram open"),-1); - } - - char buf[512]; - - sprintf(buf, "Hello World!"); - - /* - The only other difference between us and the directed client - is that we don't specify a host to receive the datagram. - Instead, we use the magic value "INADDR_BROADCAST". All hosts - are obliged to respond to datagrams directed to this address - the same as they would to datagrams sent to their hostname. - - Remember, the Dgram_Bcast will send a datagram to all interfaces - on the host. That's true even if the address is for a specific - host (and the host address makes sense for the interface). - The real power is in using an INADDR_BROADCAST addressed datagram - against all interfaces. - */ - - ACE_INET_Addr remote(PORT,INADDR_BROADCAST); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Sending (%s) to the server.\n",buf)); - - if( dgram.send(buf,strlen(buf)+1,remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1); - } - - if( dgram.recv(buf,sizeof(buf),remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"),-1); - } - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server said: %s\n",buf)); - - /* - Using the "remote" object instance, find out where the server lives. - We could then save this address and use directed datagrams to chat - with the server for a while. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server can be found at: (%s:%d)\n", - remote.get_host_name(), PORT )); - - return(0); -} diff --git a/docs/tutorials/008/directed_client.cpp b/docs/tutorials/008/directed_client.cpp deleted file mode 100644 index 7fac216dbc3..00000000000 --- a/docs/tutorials/008/directed_client.cpp +++ /dev/null @@ -1,112 +0,0 @@ - -// $Id$ - -#include "ace/SOCK_Dgram.h" -#include "ace/INET_Addr.h" - -/* - Once again, we use the default server port. In a "real" system, - the server's port (or ports) would be published in some way so - that clients would know where to "look". We could even add entries - to the operating system's services file and use a service name - instead of a number. We'll come back to that in some other tutorial - though. For now, let's stay simple. - */ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -/* - Our goal here is to develop a client that can send a datagram to - a server running on a known host. We'll use a command-line argument - to specify the hostname instead of hard-coding it. - */ -int main(int argc,char *argv[] ) -{ - /* - All datagrams have to have a point of origin. Since we intend to - transmit instead of receive, we initialize an address with zero - and let the OS choose a port for us. We could have chosen our - own value between 1025 and 65535 as long as it isn't already in use. - */ - ACE_INET_Addr local((u_short)0); - - /* - And here is our datagram object. - */ - ACE_SOCK_Dgram dgram; - - /* - Notice that this looks a lot like the server application. There's - no difference in creating server datagrams an client datagrams. - You can even use a zero-constructed address for your server datagram - as long as you tell the client where you're listening (eg -- by writting - into a file or some such). - */ - if( dgram.open(local) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "datagram open"),-1); - } - - /* - Yep. We've seen this before too... - */ - char buf[512]; - - /* - Ok, now we're doing something different. - */ - sprintf(buf, "Hello World!"); - - /* - Just like sending a telegram, we have to address our datagram. - Here, we create an address object at the desired port on the - chosen host. To keep us from crashing, we'll provide a default - host name if we aren't given one. - */ - ACE_INET_Addr remote(PORT, argc > 1 ? argv[1] : "localhost" ); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Sending (%s) to the server.\n",buf)); - /* - Now we send our buffer of stuff to the remote address. This is - just exactly what the server did after receiving a client message. - Datagrams are rather orthogonal that way: they don't generally make - much of a fuss about being either client or server. - */ - if( dgram.send(buf,strlen(buf)+1,remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1); - } - - /* - Now we've turned around and put ourselves into "server mode" by - invoking the recv() method. We now our server is going to send - us something, so we hang out here and wait for it. Because we - know datagrams are unreliable, there is a chance that the server - will respond but we won't hear. You might consider providing a - timeout on the recv() in that case. If recv() fails due to timeout - it will return -1 and you can then resend your query and attempt - the recv() again. - - Like the server application, we have to give the recv() an - uninitialized addr object so that we can find out who is talking - back to us. - */ - if( dgram.recv(buf,sizeof(buf),remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"),-1); - } - - /* - Find out what the server had to say. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server said: %s\n",buf)); - - /* - Using the "remote" object instance, find out where the server lives. - We could then save this address and use directed datagrams to chat - with the server for a while. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server can be found at: (%s:%d)\n", - remote.get_host_name(), PORT )); - - return(0); -} diff --git a/docs/tutorials/008/page01.html b/docs/tutorials/008/page01.html deleted file mode 100644 index ebe24e9ecc8..00000000000 --- a/docs/tutorials/008/page01.html +++ /dev/null @@ -1,60 +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"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In a lot of IPC programming, the clients know where the servers -are. A mail client, for instance, has a configuration file that says -where the mail host is. Your web browser has a "location" field that -you type into to give it a destination. - -<P>What if you have written a server application and then you execute it -on several systems in your network? All of the instances are probably -more or less equal to the client's point of view, so you don't want to -"configure" the clients to a single server each. Likewise, you -want the ability to add and remove servers at any time so you can't just -give the clients a list to choose from. - -<P>So... how do the clients know where the servers are? - -<P>Let 'em ask! - -<P>Datagrams are great for this. You can toss a datagram out onto -the network and any servers listening at the correct port will* hear it. -Like ACE_SOCK_Stream that we've seen before, you can get the peer address -from a datagram. With that, the server can send a response -back to the client. The client, in turn, can pull the peer address -out and know exactly where the server lives. - -<P>In this tutorial we'll develop three applications: a server listening -for datagrams, a client that can send to a known host and a client that -can send to the entire (sub)network. In the next tutorial, we'll -expand on this to make the server a bit more prudish. -<BR> - -<P><FONT SIZE=-1>* Actually, the servers <I>might</I> hear the datagram. -Datagrams are rather unreliable. (Sort of like some operating systems -I know.) Still, if the network traffic isn't too bad, they generally -get through. Your clients can always send out more queries if there -aren't any responses in a timely fashion.</FONT> - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/page02.html b/docs/tutorials/008/page02.html deleted file mode 100644 index 85b8c083d88..00000000000 --- a/docs/tutorials/008/page02.html +++ /dev/null @@ -1,237 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>The first thing we want to look at is <A HREF="server.cpp">server.cpp</A>. -This is a pretty simple application that listens for datagrams at a known -port and sends back a response. In order to implement a true "discovery" -mechanism, the server will have to be a little bit more picky about who -it responds to. We'll tackle that issue in the next tutorial though... - -<P> -<HR WIDTH="100%"> - -<P><TT>/*</TT> -<BR><TT> Our datagram server will, of course, need to create -a datagram.</TT> -<BR><TT> We'll also need an address object so that we know -where to listen.</TT> -<BR><TT> */</TT> -<BR><TT>#include "ace/SOCK_Dgram.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT> - -<P><TT>/*</TT> -<BR><TT> Use the typical TCP/IP port address for receiving -datagrams.</TT> -<BR><TT> */</TT> -<BR><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT> - -<P><TT>int main(int,char**)</TT> -<BR><TT>{</TT> -<BR><TT> /*</TT> -<BR><TT> This is where we'll listen -for datagrams coming from the</TT> -<BR><TT> clients. We'll give -this address to the open() method</TT> -<BR><TT> below to enable the listener.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr local(PORT);</TT> - -<P><TT> /*</TT> -<BR><TT> A simply constructed datagram -that we'll listen with.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_SOCK_Dgram dgram;</TT> - -<P><TT> /*</TT> -<BR><TT> Like most ACE objects, the -datagram has to be opened before</TT> -<BR><TT> it can be uses. Of course, --1 on failure.</TT> - -<P><TT> A datagram will fail to open -if there is already a datagram</TT> -<BR><TT> listening at the port we've -chosen. It *is* OK to open</TT> -<BR><TT> a datagram at a port where -there is an ACE_SOCK_Stream</TT> -<BR><TT> though. This is because -datagrams are UDP and SOCK_Stream</TT> -<BR><TT> is TCP and the two don't cross -paths.</TT> -<BR><TT> */</TT> -<BR><TT> if( dgram.open(local) == -1 )</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, -"%p\n", "open"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Create a simple buffer to -receive the data. You generally need</TT> -<BR><TT> to provide a buffer big enough -for the largest datagram you</TT> -<BR><TT> expect to receive. Some -platforms will let you read a little</TT> -<BR><TT> and then some more later but -other platforms will throw out</TT> -<BR><TT> whatever part of the datagram -you don't get with the first</TT> -<BR><TT> read. (This is on a -per-datagram basis BTW.) The theoretical</TT> -<BR><TT> limit on a datagram is about -64k. The realistic limit (because</TT> -<BR><TT> of routers & such) is -much smaller. Choose your buffer size</TT> -<BR><TT> based on your application's -needs.</TT> -<BR><TT> */</TT> -<BR><TT> char buf[512];</TT> - -<P><TT> /*</TT> -<BR><TT> Unlike ACE_SOCK_Stream, datagrams -are unconnected. That is,</TT> -<BR><TT> there is no "virtual circuit" -between server and client.</TT> -<BR><TT> Because of this, the server -has to provide a placeholder</TT> -<BR><TT> for the OS to fill in the -source (client) address information</TT> -<BR><TT> on the recv. You can -initialize this INET_Addr to anything,</TT> -<BR><TT> it will be overwritten when -the data arrives.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr remote;</TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server -daemon\n"));</TT> - -<P><TT> /*</TT> -<BR><TT> Receive datagrams as long -as we're able.</TT> -<BR><TT> */</TT> -<BR><TT> while( dgram.recv(buf,sizeof(buf),remote) != --1 )</TT> -<BR><TT> {</TT> -<BR><TT> /*</TT> -<BR><TT> Display -a brief message about our progress. Notice how we</TT> -<BR><TT> use -the 'remote' object to display the address of the client.</TT> -<BR><TT> With -an ACE_SOCK_Stream we used get_remote_addr() to get the</TT> -<BR><TT> address -the socket is connected to. Because datagrams are</TT> -<BR><TT> unconnected, -we use the addr object provided to recv().</TT> -<BR><TT> */</TT> -<BR><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) Data (%s) from client (%s)\n", buf, remote.get_host_name()));</TT> - -<P><TT> /*</TT> -<BR><TT> To -respond to the client's query, we have to become a client</TT> -<BR><TT> ourselves. -To do so, we need an anonymous local address from</TT> -<BR><TT> which -we'll send the response and a datagram in which to send</TT> -<BR><TT> it. -(An anonymous address is simply one where we let the OS</TT> -<BR><TT> choose -a port for us. We really don't care what it is.O</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr -local((u_short)0);</TT> -<BR><TT> ACE_SOCK_Dgram client;</TT> - -<P><TT> /*</TT> -<BR><TT> Open -up our response datagram as always.</TT> -<BR><TT> */</TT> -<BR><TT> if( client.open(local) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "client open"),-1);</TT> -<BR><TT> -return(0);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Build -a witty response...</TT> -<BR><TT> */</TT> -<BR><TT> sprintf(buf,"I am here");</TT> - -<P><TT> /*</TT> -<BR><TT> and -send it to the client. Notice the symetry with the recv()</TT> -<BR><TT> method. -Again, the unconnected nature of datagrams forces</TT> -<BR><TT> us -to specify an address object with each read/write operation.</TT> -<BR><TT> In -the case of read (recv()) that's where the OS stuffs the</TT> -<BR><TT> address -of the datagram sender. In the case of write (send())</TT> -<BR><TT> that -we're doing here, the address is where we want the network</TT> -<BR><TT> to -deliver the data.</TT> - -<P><TT> Of -course, we're assuming that the client will be listening</TT> -<BR><TT> for -our reply...</TT> -<BR><TT> */</TT> -<BR><TT> if( client.send(buf,strlen(buf)+1,remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1);</TT> -<BR><TT> -return(0);</TT> -<BR><TT> }</TT> -<BR><TT> }</TT> - -<P><TT> return(0);</TT> -<BR><TT>}</TT> - -<P> -<HR WIDTH="100%"> - -<P>And that's really all there is to it. Obviously there is some -room for improvement. The most blatant is the somewhat small buffer -size for receiving the datagram. I've never been able to get a solid -answer on datagram sizes. The theoretical limit is just under 64k -but you have to deal with fragmentation. Some readings indicate that -8k is a reasonable size, others go much smaller. My general rule -of thumb is to keep datagrams relatively small (eg -- under 8k or so) and -test a lot. If you find that your routers are fragmenting your larger -datagrams, back off to something smaller. Of course, if you must -send 100k and can only do so 1k at a time, you'll have to worry about retransmissions -& reordering. At that point, you might consider going to TCP. -Remember: datagrams are unreliable! Don't try to make 'em do -something they werent' designed for! - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial Index</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/page03.html b/docs/tutorials/008/page03.html deleted file mode 100644 index b1faf3b7287..00000000000 --- a/docs/tutorials/008/page03.html +++ /dev/null @@ -1,187 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In <A HREF="directed_client.cpp">directed_client.cpp</A> we create a -client that knows how to send a datagram to a server on a known host. -This is a good thing if you know where the server lives and want to have -a conversation. The Unix <I>talk</I> utilitiy, for instance, -could be written this way. - -<P> -<HR WIDTH="100%"> - -<P><TT>#include "ace/SOCK_Dgram.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT> - -<P><TT>/*</TT> -<BR><TT> Once again, we use the default server port. -In a "real" system,</TT> -<BR><TT> the server's port (or ports) would be published in -some way so</TT> -<BR><TT> that clients would know where to "look". We -could even add entries</TT> -<BR><TT> to the operating system's services file and use a -service name</TT> -<BR><TT> instead of a number. We'll come back to that -in some other tutorial</TT> -<BR><TT> though. For now, let's stay simple.</TT> -<BR><TT> */</TT> -<BR><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT> - -<P><TT>/*</TT> -<BR><TT> Our goal here is to develop a client that can send -a datagram to</TT> -<BR><TT> a server running on a known host. We'll use -a command-line argument</TT> -<BR><TT> to specify the hostname instead of hard-coding it.</TT> -<BR><TT> */</TT> -<BR><TT>int main(int argc,char *argv[] )</TT> -<BR><TT>{</TT> -<BR><TT> /*</TT> -<BR><TT> All -datagrams have to have a point of origin. Since we intend to</TT> -<BR><TT> transmit -instead of receive, we initialize an address with zero</TT> -<BR><TT> and -let the OS choose a port for us. We could have chosen our</TT> -<BR><TT> own -value between 1025 and 65535 as long as it isn't already in use.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr -local((u_short)0);</TT> - -<P><TT> /*</TT> -<BR><TT> And -here is our datagram object.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_SOCK_Dgram dgram;</TT> -<BR><TT> </TT> -<BR><TT> /*</TT> -<BR><TT> Notice -that this looks a lot like the server application. There's</TT> -<BR><TT> no -difference in creating server datagrams an client datagrams.</TT> -<BR><TT> You -can even use a zero-constructed address for your server datagram</TT> -<BR><TT> as -long as you tell the client where you're listening (eg -- by writting</TT> -<BR><TT> into -a file or some such).</TT> -<BR><TT> */</TT> -<BR><TT> if( dgram.open(local) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "datagram open"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Yep. -We've seen this before too...</TT> -<BR><TT> */</TT> -<BR><TT> char buf[512];</TT> - -<P><TT> /*</TT> -<BR><TT> Ok, -now we're doing something different.</TT> -<BR><TT> */</TT> -<BR><TT> sprintf(buf, "Hello -World!");</TT> - -<P><TT> /*</TT> -<BR><TT> Just -like sending a telegram, we have to address our datagram.</TT> -<BR><TT> Here, -we create an address object at the desired port on the</TT> -<BR><TT> chosen -host. To keep us from crashing, we'll provide a default</TT> -<BR><TT> host -name if we aren't given one.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr -remote(PORT, argc > 1 ? argv[1] : "localhost" );</TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) Sending (%s) to the server.\n",buf));</TT> -<BR><TT> /*</TT> -<BR><TT> -Now we send our buffer of stuff to the remote address. This is</TT> -<BR><TT> -just exactly what the server did after receiving a client message.</TT> -<BR><TT> -Datagrams are rather orthogonal that way: they don't generally make</TT> -<BR><TT> -much of a fuss about being either client or server.</TT> -<BR><TT> */</TT> -<BR><TT> if( dgram.send(buf,strlen(buf)+1,remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Now -we've turned around and put ourselves into "server mode" by</TT> -<BR><TT> invoking -the recv() method. We now our server is going to send</TT> -<BR><TT> us -something, so we hang out here and wait for it. Because we</TT> -<BR><TT> know -datagrams are unreliable, there is a chance that the server</TT> -<BR><TT> will -respond but we won't hear. You might consider providing a</TT> -<BR><TT> timeout -on the recv() in that case. If recv() fails due to timeout</TT> -<BR><TT> it -will return -1 and you can then resend your query and attempt</TT> -<BR><TT> the -recv() again.</TT> -<BR><TT> */</TT> -<BR><TT> if( dgram.recv(buf,sizeof(buf),remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Find -out what the server had to say.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) The server said: %s\n",buf));</TT> - -<P><TT> return(0);</TT> -<BR><TT>}</TT> - -<P> -<HR WIDTH="100%"> - -<P>That's all neat and good but the point of what we're doing here is not -to talk to a server we know about but to discover servers we don't know -about. Now, you could send a directed datagram to every possible -host address on your network but that's not a very nice thing to do. -On the next page, we'll find out the right approach... - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial Index</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/page04.html b/docs/tutorials/008/page04.html deleted file mode 100644 index 4a634b56a4b..00000000000 --- a/docs/tutorials/008/page04.html +++ /dev/null @@ -1,156 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<BR> -<BR> In <A HREF="broadcast_client.cpp">broadcast_client.cpp</A> we -find out how to send a single datagram to every host on our (sub)network. -I have to say <I>(sub)network</I> because broadcast datagrams typically -are not passed through routers. So, if your network admin has divided -up your network into subnets, your broadcasts will likey only stay on the -subnet you're a part of. - -<P>I've only commented the parts that are different from the directed_client. - -<P> -<HR WIDTH="100%"> - -<P><TT>#include "ace/SOCK_Dgram_Bcast.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT> - -<P><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT> - -<P><TT>int main(int argc,char *argv[] )</TT> -<BR><TT>{</TT> -<BR><TT> ACE_INET_Addr -local((u_short)0);</TT> - -<P><TT> /*</TT> -<BR><TT> Instead -of creating the ACE_SOCK_Dgram we created last time,</TT> -<BR><TT> we'll -create an ACE_SOCK_Dgram_Bcast. "Bcast" means, of course,</TT> -<BR><TT> "Broadcast". -This ACE object is clever enough to go out to the</TT> -<BR><TT> OS -and find all of the network interfaces. When you send()</TT> -<BR><TT> on -a Dgram_Bcast, it will send the datagram out on all of those</TT> -<BR><TT> interfaces. -This is quiet handy if you do it on a multi-homed</TT> -<BR><TT> host -that plays router...</TT> -<BR><TT> */</TT> -<BR><TT> ACE_SOCK_Dgram_Bcast -dgram;</TT> - -<P><TT> if( dgram.open(local) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "datagram open"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> char buf[512];</TT> - -<P><TT> sprintf(buf, "Hello World!");</TT> - -<P><TT> /*</TT> -<BR><TT> The -only other difference between us and the directed client</TT> -<BR><TT> is -that we don't specify a host to receive the datagram.</TT> -<BR><TT> Instead, -we use the magic value "INADDR_BROADCAST". All hosts</TT> -<BR><TT> are -obliged to respond to datagrams directed to this address</TT> -<BR><TT> the -same as they would to datagrams sent to their hostname.</TT> - -<P><TT> Remember, -the Dgram_Bcast will send a datagram to all interfaces</TT> -<BR><TT> on -the host. That's true even if the address is for a specific</TT> -<BR><TT> host -(and the host address makes sense for the interface).</TT> -<BR><TT> The -real power is in using an INADDR_BROADCAST addressed datagram</TT> -<BR><TT> against -all interfaces.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr -remote(PORT,INADDR_BROADCAST);</TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) Sending (%s) to the server.\n",buf));</TT> -<BR><TT> </TT> -<BR><TT> if( dgram.send(buf,strlen(buf)+1,remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> if( dgram.recv(buf,sizeof(buf),remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) The server said: %s\n",buf));</TT> - -<P><TT> /*</TT> -<BR><TT> Using -the <I>remote</I> object instance, find out where the server lives.</TT> -<BR><TT> We -could then save this address and use directed datagrams to chat</TT> -<BR><TT> with -the server for a while.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) The server can be found at: (%s:%d)\n",</TT> -<BR><TT> -remote.get_host_addr(), PORT ));</TT> -<BR><TT> </TT> -<BR><TT> return(0);</TT> -<BR><TT>}</TT> - -<P> -<HR WIDTH="100%"> - -<P> About that subnet thing: -<BLOCKQUOTE>If you run this client on a host that has multiple network -interfaces, the broadcast will go to all of those (sub)networks. -What do you do, though, if you need to get past a router? My advice -is to write a server that will run on hosts on both sides of your router. -When a server on one side of the router receives a broadcast, it would -send a directed datagram to it's counterpart on the other side of the router. -The counterpart would then re-broadcast the original datagram on that sub-net. -Cheap, simple and effective.</BLOCKQUOTE> -One final word of warning: -<BLOCKQUOTE>When creating your broadcast datagrams you may see something -like this: <I>ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not -enable for this interface.: Unknown error</I>. There are some interfaces -(ppp, slip) that don't support broadcast datagrams. That's what you're -seeing here.</BLOCKQUOTE> - -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial Index</A>] [<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/page05.html b/docs/tutorials/008/page05.html deleted file mode 100644 index f8c4603668a..00000000000 --- a/docs/tutorials/008/page05.html +++ /dev/null @@ -1,43 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<BR> -<BR>That's it for this tutorial. In the next one we'll add some intelligence -to the data put into the datagrams. By doing so, we'll be able to -classify our clients and servers into groups. By combining the data -content and the server's port we can get fairly fine-grained control over -who talks to who. - -<P>For you convenience: -<UL> -<LI> -<A HREF="server.cpp">server.cpp</A></LI> - -<LI> -<A HREF="directed_client.cpp">directed_client.cpp</A></LI> - -<LI> -<A HREF="broadcast_client.cpp">broadcast_client.cpp</A></LI> - -<LI> -<A HREF="Makefile">Makefile</A></LI> -</UL> - -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/server.cpp b/docs/tutorials/008/server.cpp deleted file mode 100644 index e702b1b93bb..00000000000 --- a/docs/tutorials/008/server.cpp +++ /dev/null @@ -1,128 +0,0 @@ - -// $Id$ - -/* - Our datagram server will, of course, need to create a datagram. - We'll also need an address object so that we know where to listen. - */ -#include "ace/SOCK_Dgram.h" -#include "ace/INET_Addr.h" - -/* - Use the typical TCP/IP port address for receiving datagrams. - */ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main(int,char**) -{ - /* - This is where we'll listen for datagrams coming from the - clients. We'll give this address to the open() method - below to enable the listener. - */ - ACE_INET_Addr local(PORT); - - /* - A simply constructed datagram that we'll listen with. - */ - ACE_SOCK_Dgram dgram; - - /* - Like most ACE objects, the datagram has to be opened before - it can be uses. Of course, -1 on failure. - - A datagram will fail to open if there is already a datagram - listening at the port we've chosen. It *is* OK to open - a datagram at a port where there is an ACE_SOCK_Stream - though. This is because datagrams are UDP and SOCK_Stream - is TCP and the two don't cross paths. - */ - if( dgram.open(local) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"),-1); - } - - /* - Create a simple buffer to receive the data. You generally need - to provide a buffer big enough for the largest datagram you - expect to receive. Some platforms will let you read a little - and then some more later but other platforms will throw out - whatever part of the datagram you don't get with the first - read. (This is on a per-datagram basis BTW.) The theoretical - limit on a datagram is about 64k. The realistic limit (because - of routers & such) is much smaller. Choose your buffer size - based on your application's needs. - */ - char buf[512]; - - /* - Unlike ACE_SOCK_Stream, datagrams are unconnected. That is, - there is no "virtual circuit" between server and client. - Because of this, the server has to provide a placeholder - for the OS to fill in the source (client) address information - on the recv. You can initialize this INET_Addr to anything, - it will be overwritten when the data arrives. - */ - ACE_INET_Addr remote; - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server daemon\n")); - - /* - Receive datagrams as long as we're able. - */ - while( dgram.recv(buf,sizeof(buf),remote) != -1 ) - { - /* - Display a brief message about our progress. Notice how we - use the 'remote' object to display the address of the client. - With an ACE_SOCK_Stream we used get_remote_addr() to get the - address the socket is connected to. Because datagrams are - unconnected, we use the addr object provided to recv(). - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Data (%s) from client (%s)\n", buf, remote.get_host_name())); - - /* - To respond to the client's query, we have to become a client - ourselves. To do so, we need an anonymous local address from - which we'll send the response and a datagram in which to send - it. (An anonymous address is simply one where we let the OS - choose a port for us. We really don't care what it is.O - */ - ACE_INET_Addr local((u_short)0); - ACE_SOCK_Dgram client; - - /* - Open up our response datagram as always. - */ - if( client.open(local) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "client open"),-1); - return(0); - } - - /* - Build a witty response... - */ - sprintf(buf,"I am here"); - - /* - and send it to the client. Notice the symetry with the recv() - method. Again, the unconnected nature of datagrams forces - us to specify an address object with each read/write operation. - In the case of read (recv()) that's where the OS stuffs the - address of the datagram sender. In the case of write (send()) - that we're doing here, the address is where we want the network - to deliver the data. - - Of course, we're assuming that the client will be listening - for our reply... - */ - if( client.send(buf,strlen(buf)+1,remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1); - return(0); - } - } - - return(0); -} |