例
2-4//Client
#include "ace/OS.h"
#include "ace/SOCK_Dgram.h"
#include "ace/INET_Addr.h"
#define DATA_BUFFER_SIZE 1024
#define SIZE_DATA 28
class
Client{
public:
Client
(char * remote_host,int port):remote_addr_(remote_host),
local_addr_((u_short)0),local_(local_addr_)
{
data_buf = new char[DATA_BUFFER_SIZE];
remote_addr_.set_port_number(port);
}
//Receive data from the remote host using the datgram wrapper `local_’.
//The address of the remote machine is received in `remote_addr_’
//which is of type ACE_INET_Addr. Remember that there is no established
//connection.
int
accept_data(){
if(local_.recv(data_buf,SIZE_DATA,remote_addr_)!=-1)
{
ACE_DEBUG((LM_DEBUG, "Data received from remote server %s was: %s \n" ,
remote_addr_.get_host_name(), data_buf));
return 0;
}
else
return -1;
}
//Send data to the remote. Once data has been sent wait for a reply
//from the server.
int
send_data(){
ACE_DEBUG((LM_DEBUG,"Preparing to send data to server %s:%d\n",
remote_addr_.get_host_name(),remote_addr_.get_port_number()));
ACE_OS::sprintf(data_buf,"Client says hello");
while(local_.send(data_buf,ACE_OS::strlen(data_buf),remote_addr_)!=-1)
{
ACE_OS::sleep(1);
if(accept_data()==-1)
break;
}
return -1;
}
private:
char *data_buf;
ACE_INET_Addr remote_addr_;
ACE_INET_Addr local_addr_;
ACE_SOCK_Dgram local_;
};
int
main(int argc, char *argv[]){
if(argc<3)
{
ACE_OS::printf("Usage: %s
\n", argv[0]); ACE_OS::exit(1);
}
Client client(argv[1],ACE_OS::atoi(argv[2]));
client.send_data();
}
2.2.3 使用ACE的多点传送(Multicast)
你会发现,在许多场合,同样的消息必须被发送给你的分布式系统中的众多客户或服务器。例如,可能需要将时间调整更新或其他的周期性信息广播给特定的终端集。多点传送被用于处理这一问题。它允许对特定的终端子集或组、而不是所有终端进行广播。因此,你可以认为多点传送是一种受控的广播机制。大多数现代
OS都提供多点传送功能。ACE
提供ACE_SOCK_Dgram_Mcast包装,封装了不可*的多点传送。它允许程序员将数据报消息发送给被称为“多点传送组”的受控组。这样的组由唯一的多点传送地址标识。对在此地址上接收广播有兴趣的客户和服务器必须进行预订(也被称为“多点传送组预订”)。于是,所有预订到此多点传送组的进程将会接收到所有发送给该组的数据报消息。仅仅想要给多点传送组发送消息,而不需要收听它们的应用,无需进行预订。实际上,这样的发送者可以使用原有的简单
ACE_SOCK_Dgram包装给多点传送地址发送消息,整个多点传送组将随之收到发送出的消息。在
ACE中,多点传送功能被封装在ACE_SOCK_Dgram_Mcast中,其中包括在多点传送组上的预订、取消预订和接收功能。下面的例子演示在
ACE中是怎样使用多点传送的:
例
2-5#include "ace/SOCK_Dgram_Mcast.h"
#include "ace/OS.h"
#define DEFAULT_MULTICAST_ADDR "224.9.9.2"
#define TIMEOUT 5
//The following class is used to receive multicast messages from
//any sender.
class
Receiver_Multicast{
public:
Receiver_Multicast
(int port):mcast_addr_(port,DEFAULT_MULTICAST_ADDR),remote_addr_((u_short)0)
{
// Subscribe to multicast address.
if (mcast_dgram_.subscribe (mcast_addr_) == -1)
{
ACE_DEBUG((LM_DEBUG,"Error in subscribing to Multicast address \n"));
exit(-1);
}
}
~Receiver_Multicast
(){
if(mcast_dgram_.unsubscribe()==-1)
ACE_DEBUG((LM_ERROR,"Error in unsubscribing from Mcast group\n"));
}
//Receive data from someone who is sending data on the multicast group
//address. To do so it must use the multicast datagram component
//mcast_dgram_.
int
recv_multicast(){
//get ready to receive data from the sender.
if(mcast_dgram_.recv (&mcast_info,sizeof (mcast_info),remote_addr_)==-1)
return -1;
else
{
ACE_DEBUG ((LM_DEBUG, "(%P|%t) Received multicast from %s:%d.\n",
remote_addr_.get_host_name(), remote_addr_.get_port_number()));
ACE_DEBUG((LM_DEBUG,"Successfully received %d\n", mcast_info));
return 0;
}
}
private:
ACE_INET_Addr mcast_addr_;
ACE_INET_Addr remote_addr_;
ACE_SOCK_Dgram_Mcast mcast_dgram_;
int mcast_info;
};
int
main(int argc, char*argv[]){
Receiver_Multicast m(2000);
//Will run forever
while(m.recv_multicast()!=-1)
{
ACE_DEBUG((LM_DEBUG,"Multicaster successful \n"));
}
ACE_DEBUG((LM_ERROR,"Multicaster failed \n"));
exit(-1);
}
上面的例子说明应用怎样使用
ACE_SOCK_Dgram_Mcast预订多点传送组,以及从多点传送组接收消息。Receiver_Multicast
类的构造器将对象预订到多点传送组,析构器取消预订。一旦预订之后,应用无限期地等待任何发往此多点传送地址的数据。下一个例子说明应用怎样使用
ACE_SOCK_Dgram包装类将数据报消息发送到多点传送地址或组。
例
2-6#include "ace/SOCK_Dgram_Mcast.h"
#include "ace/OS.h"
#define DEFAULT_MULTICAST_ADDR "224.9.9.2"
#define TIMEOUT 5
class
Sender_Multicast{
public:
Sender_Multicast
(int port):local_addr_((u_short)0),dgram_(local_addr_),
multicast_addr_(port,DEFAULT_MULTICAST_ADDR)
{
}
//Method which uses a simple datagram component to send data to the //multicast group.
int
send_to_multicast_group(){
//Convert the information we wish to send into network byte order
mcast_info= htons (1000);
// Send multicast
if(dgram_.send (&mcast_info, sizeof (mcast_info), multicast_addr_)==-1)
return -1;
ACE_DEBUG ((LM_DEBUG,
"%s; Sent multicast to group. Number sent is %d.\n",
__FILE__,
mcast_info));
return 0;
}
private:
ACE_INET_Addr multicast_addr_;
ACE_INET_Addr local_addr_;
ACE_SOCK_Dgram dgram_;
int mcast_info;
};
int
main(int argc, char*argv[]){
Sender_Multicast m(2000);
if(m.send_to_multicast_group()==-1)
{
ACE_DEBUG((LM_ERROR,"Send to Multicast group failed \n"));
exit(-1);
}
else
ACE_DEBUG((LM_DEBUG,"Send to Multicast group successful \n"));
}
在此例中,客户使用数据报包装给多点传送组发送数据。
Sender_Multicast类含有一个简单的send_to_multicast_group()方法。该方法使用数据报包装组件dgram_发送单个消息给多点传送组,消息中仅包含一个整数。当接收者接收到此消息时,它把该整数打印到标准输出。