//服务器端
///////////////////////////////////////////////////////////////////////////////////////////////////////////#define DEFAULT_MULTICAST_ADDR "224.0.0.1" //所有支持多播的主机,服务器在这个地址上监听所有的客户端上线消息//多播接收器
class CReceiver_Multicast
{
public:
CReceiver_Multicast(int port):
mcast_addr_(port,DEFAULT_MULTICAST_ADDR)
{
// 预定多播
if (mcast_dgram_.subscribe (mcast_addr_) == -1)
{
OutputDebugString("Error in subscribing to Multicast address \n");
}
}
~CReceiver_Multicast()
{
//取消预定
if(mcast_dgram_.unsubscribe()==-1)
OutputDebugString("Error in unsubscribing from Mcast group\n");
}//接收多播消息
int recv(char* buf, size_t bufSize, DWORD dwTimeout_msec, ACE_INET_Addr& remote)
{
ACE_Time_Value tm(dwTimeout_msec/1000, (dwTimeout_msec%1000)*1000);
return mcast_dgram_.recv (buf, bufSize, remote, 0, &tm);
}private:
ACE_INET_Addr mcast_addr_;
ACE_SOCK_Dgram_Mcast mcast_dgram_;
};void CServer::Go()
{
char buf[1024]={0};
CReceiver_Multicast receiver(2000);//监视多播端口m_EventStop = 0;
ACE_INET_Addr remote;
while(!m_EventStop)
{
//接收多播数据
int nRecv = receiver.recv(buf, sizeof(buf), 300, remote);
if(nRecv>0)
{
//do something
}
}
}//客户端
/////////////////////////////////////////////////////////////////////////////////////////////////////void CClient::Go()
{
ACE_INET_Addr local((u_short)0);
ACE_SOCK_Dgram data_gram(local);data_gram.get_local_addr(local);
m_LsitenPort = local.get_port_number();ACE_INET_Addr remote;
ACE_Time_Value timeout( Millisec2ACETime(60) );static const char DEFAULT_MULTICAST_ADDR[] = "224.0.0.1";  
ACE_INET_Addr server(2000, DEFAULT_MULTICAST_ADDR);//周知的服务器监听的多播地址及端口
char buf[128]; //128足够
int size = MakeQSLCmd(buf, m_LsitenPort);//按自己的格式定义查询服务器位置的消息
data_gram.send(buf, size, server, 0);//发送查询服务器位置消息m_bExit = false;
char buf[1024];
while(!m_bExit)
{
int nRecv = data_gram.recv(buf, sizeof(buf), remote, 0, &timeout);
if(nRecv>0)
{
//do something
}
}}我是在家里的电脑(通过ADSL上网的)测试时为何服务器压根儿就没收到客户端发的查询服务器位置的消息?是与发送地址有关吗?
但是在公司的局域网却能成功收到消息,这是为什么呢?先在此跪谢各位兄台了!

解决方案 »

  1.   

       首先你组播地址就不对,224.0.0.1属于保留地址,用这个地址会带来很多问题,你应该使用224.1.1.1以后的。但这不是最重要的,组播(多播)是由路由器完成的,必须得到路由器的支持才能成功。局域网中机器一般在一个子网中,经过一个路由器或很少的交换机,一般默认开启了组播协议,因此没有问题。广域网上一个消息包要经过多个路由器,一般在10个路由器以上。位于广域网的两个客户端,无法加入到同一个路由器的组播段中,而且为了防止占用带宽,电信服务商一般都关闭了路由器的组播协议,因此无法通信。如果经过了交换机的话,情况则更为复杂。组播一般只用在局域网应用,不要在广域网使用。
       组播地址不是一个远端的固定的地址,并非有一台机器等着终端去连接。离你最近的路由器如果支持组播协议,当你使用组播时,它会把你加入到它的组播组之中。要通信的两台的机器必须加入到同一个路由器的组播组之中。广域网中的机器能加入到同一路由器的概率几乎为0。就算你和另一个人住同一个小区,住隔壁,你们两个还必须直接拨号上网,同一个电信服务商,有可能连在同一个路由器上,但都不能保证通信。因为电信服务商一般不会开启路由器的组播协议。
      

  2.   

    谢谢楼上的虾哥,那应该用怎样的方式查找服务器地址呢?QQ是怎么解决的呢?
      

  3.   

    那我是否可以这样改进?我就不用多播去查找服务器了,而是指定一个域名,将此域名作为服务器地址去连接?