• ACE Tutorial [翻译] 08-page04

    2004-11-29

    Tag:ACE_TAO

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://jnn.blogbus.com/logs/520213.html

    broadcast_client.cpp中,我们将展示如何向子网内的所有的主机发送一个单一的数据报。这这里我们说子网是因为广播报文是不能够通过路由器转发过去的。所以,如果你的网络管理员已经将你的网络划分成为子网,你所发送的广播报文只能在你所在的子网中传送。

    这里我只注释和directed_client不同的部分。


    // page04.html,v 1.13 2000/11/27 17:56:43 othman Exp
     
    #include "ace/Log_Msg.h"
    #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_UNUSED_ARG(argc);
      ACE_UNUSED_ARG(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不同,我们创建了一个ACE_SOCK_Dgram_Bcast.
    Bcast”的意思是"Broadcast 广播"。这个ACE的对象是非常机灵,它将会通过OS
    遍历所以的网络接口。当你通过调用Dgram_Bcast的send()方法,它将会向所以的
    网络接口发送数据报。如果你是在一个起路由功能的多地址主机这么做将非常有效。
    */
      ACE_SOCK_Dgram_Bcast dgram;
     
      if (dgram.open (local) == -1)
        ACE_ERROR_RETURN ((LM_ERROR,
                           "%p\n",
                           "datagram open"),
                          -1);
     
      char buf[BUFSIZ];
     
      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.
    这和直接连接的客户端的最大的阿不同是,我们不需要指定接收数据报的主机。
    这样我们使用了一个魔数“INADDR_BROADCAST”.和用主机地址直接发送一样,
    这些主机都必须对接收的到的数据报进行响应。
     
        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.  
    需要提醒的是Dgram_Bcast将会通过主机的所有接口向外发送数据。即使这个
    地址指定的是一个特定的主机(并且主机地址是对这个接口有效的)。使用
    INADDR_BROADCAST地址的主要目的是需要防止这样的情况出现。
    */
     
      ACE_INET_Addr remote (PORT,
                            INADDR_BROADCAST);
     
      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t) Sending (%s) to the server.\n",
                  buf));
     
      if (dgram.send (buf,
                      ACE_OS::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.  
    使用“remote”对象实例,来获得服务器的地址。接下来我们可以将这个地址保存,
      然后通过数据报直接和服务器进行对话。
    */
      ACE_DEBUG ((LM_DEBUG,
                  "(%P|%t) The server can be found at:  (%s:%d)\n",
                  remote.get_host_name(),
                  PORT));
     
      return 0;
    }

     About that subnet thing:

    有关子网的内容:

    如果你的客户端运行的机器有好几个网络接口,那么广播报将向这些接口的所有子网进行发送。如果你需要将数据包通过路由器转发,所需要做的是什么?我的建议是写一个服务程序运行在你的路由器两端。当在路由器一端的服务程序接收到了广播包,它可以将这毅数据包通过路由器直接转发到对等一段的服务器。对等端的服务器可以在将原有的数据报在原有的子网内广播。 这是一个比较经济有效的做法。

     

    需要提醒的内容:

    当你创建广播报文的时候,你可能会看到这样的错误信息: ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not enable for this interface.: Unknown error. 是因为一些接口如(pppslip)都不支持广播报文。

     

    再次需要注意的地方

    如果当你调用客户端是,你的网络里面这时有多个服务器在运行,那回应可以是从任何一个机器返回的。


     


    收藏到:Del.icio.us




    评论

  • 请问,你知道如何让机器知道自己是连在哪个交换机的哪个口上吗?谢谢!