Sophie

Sophie

distrib > Mandriva > 10.0 > i586 > media > contrib > by-pkgid > 21280410b6ea906d791d7a12afae2579 > files > 126

libace5-doc-5.4-2mdk.i586.rpm

<!-- page04.html,v 1.13 2000/11/27 17:56:43 othman Exp -->
<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%">

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.&nbsp;
I have to say <I>(sub)network</I> because broadcast datagrams typically
are not passed through routers.&nbsp; So, if your network admin has divided
up your network into subnets, your broadcasts will likey stay on the
subnet you're a part of.

<P>I've only commented the parts that are different from the directed_client.
<HR WIDTH="100%">
<PRE>
<font color=red>// page04.html,v 1.13 2000/11/27 17:56:43 othman Exp</font>

<font color=blue>#include</font> "<A HREF="../../../ace/Log_Msg.h">ace/Log_Msg.h</A>"
<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Dgram_Bcast.h">ace/SOCK_Dgram_Bcast.h</A>"
<font color=blue>#include</font> "<A HREF="../../../ace/INET_Addr.h">ace/INET_Addr.h</A>"

static const u_short PORT = ACE_DEFAULT_SERVER_PORT;

int
main (int argc,char *argv[])
{
  ACE_UNUSED_ARG(argc);
  ACE_UNUSED_ARG(argv);

  ACE_INET_Addr local ((u_short) 0);

  <font color=red>/* Instead of creating the ACE_SOCK_Dgram we created last time,
    we'll create an ACE_SOCK_Dgram_Bcast.  "<font color=green>Bcast</font>" means, of course,
    "<font color=green>Broadcast</font>".  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...  */</font>
  ACE_SOCK_Dgram_Bcast dgram;

  if (dgram.open (local) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "<font color=green>%p\n</font>",
                       "<font color=green>datagram open</font>"),
                      -1);

  char buf[BUFSIZ];

  sprintf (buf, "<font color=green>Hello World!</font>");

  <font color=red>/* 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 "<font color=green>INADDR_BROADCAST</font>".  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.  */</font>

  ACE_INET_Addr remote (PORT,
                        INADDR_BROADCAST);

  ACE_DEBUG ((LM_DEBUG,
              "<font color=green>(%P|%t) Sending (%s) to the server.\n</font>",
              buf));

  if (dgram.send (buf,
                  <font color=#008888>ACE_OS::strlen</font> (buf) + 1,
                  remote) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "<font color=green>%p\n</font>",
                       "<font color=green>send</font>"),
                      -1);

  if (dgram.recv (buf,
                  sizeof (buf),
                  remote) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "<font color=green>%p\n</font>",
                       "<font color=green>recv</font>"),
                      -1);

  ACE_DEBUG ((LM_DEBUG,
              "<font color=green>(%P|%t) The server said:  %s\n</font>",
              buf));

  <font color=red>/* Using the "<font color=green>remote</font>" 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.  */</font>
  ACE_DEBUG ((LM_DEBUG,
              "<font color=green>(%P|%t) The server can be found at:  (%s:%d)\n</font>",
              remote.get_host_name(),
              PORT));

  return 0;
}
</PRE>
<HR WIDTH="100%">

<P>&nbsp;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.&nbsp;
What do you do, though, if you need to get past a router?&nbsp; My advice
is to write a server that will run on hosts on both sides of your router.&nbsp;
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.&nbsp;
The counterpart would then re-broadcast the original datagram on that sub-net.&nbsp;
Cheap, simple and effective.</BLOCKQUOTE>
One final word of warning:
<BLOCKQUOTE>When creating your broadcast datagrams you may see something
like this:&nbsp; <I>ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not
enable for this interface.: Unknown error</I>.&nbsp; There are some interfaces
(ppp, slip) that don't support broadcast datagrams.&nbsp; That's what you're
seeing here.</BLOCKQUOTE>
Ok, one more warning:
<blockquote>If you happen to have multiple servers running on your
network when you invoke this client, the response could come from any
one of them.
</blockquote>

<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER>