以多播方式传送数据

以多播方式传送数据

转自http://hi.baidu.com/plovemxz/blog/item/7b5bd1cb2d458292c9176883.html
以多播方式传送数据
以下讨论针对WINDOWS系统:
一般情况下用Winsock 1实现,因为这样的自由度较高,它是自Berkeley衍生出来的。

多播地址:
224.0.0.0到239.255.255.255
特定地址:
224.0.0.0 基本地址
224.0.0.1 这个子网上的所有系统。
224.0.0.2 这个字网上的所有路由器。
224.0.1.1 网间时间协议
224.0.0.9 RIP第2版组地址
224.0.1.24 WINS服务器组地址

用Winsock1实现:
一、 创建广播套截字:

socket(AF_INET,            //协议族  IP
   SOCK_DGRAM,      //数据包方式
flag);                //标志位
    //异常处理

 

二、 绑定网络接口设备:

//先设置地址信息

sockaddr_in local,                       //地址结构
local.sin_family=AF_INET;               //协议IP
local.sin_port=htons(端口号);             //端口

//如果系统有多个网络接口设备(如:一般网卡,modem,B2C2卡),而需要指定那个设备工作时,其它的情况可用INADDR_ANY
local.sin_addr.s_addr = inet_addr(某个网络接口设备的ip地址);
//local.sin_addr.s_addr = htonl(INADDR_ANY);// INADDR_ANY  由路由表自动选择适合的网络接口设备。

//执行绑定:
bind(套接字,(LPSOCKADDR)&local,sizeof(local));

//异常处理:

 

 

三、 加入多播

//首先、设置多播地址信息:
struct ip_mreq  ipmr;//多播地址结构
ipmr.imr_multiaddr.s_addr = inet_addr(服务器地址);

//多播本地地址设置与bind是一样。
ipmr.imr_interface.s_addr = inet_addr(本地地址); //ipmr.imr_interface.s_addr = htonl(INADDR_ANY);

//然后加入多播组:
setsockopt(套接字,
        IPPROTO_IP,    //选项级别
        IP_ADD_MEMBERSHIP, //加入多播选项,如果要退出该多播组,用:IP_DROP_MEMBERSHIP选项。
        (char *)&ipmr,sizeof(ipmr))
//异常处理

 

其它选项
四、 设置多播数据存在时间(TTL),默认值1:

//IP头信息记录拉TTL,当多播数据经过一个路由器后,TTL减1,直到0,多播数据自动丢失。
int exist; 
exist = 2;
setsockopt(套接字,IPPROTO_IP,
     IP_MULTICAST_TTL,      //设置TTL选项
     (char *)& exist,sizeof(int))
//异常处理

 

五、 设置反射:

 

//以多播方式传送数据时有反射现象,当一个局与网时存在多个多播数据源时,反射将使网路瘫痪。所以有必要用这个选项。
//然而,目前这个选项只能在2000或以上,win OS设置。

int  enable= 0;  //不允许反射。设置多播反射,true 允许反射(默认),false 不反射
setsockopt(套接字,IPPROTO_IP,IP_MULTICAST_LOOP,  //设置反射选项
 (char *)& enable,sizeof(int))
//异常处理

 

 

发送和接收数据:

int sendto (
  SOCKET s,                        
  const char FAR * buf,            
  int len,                         
  int flags,                       
  const struct sockaddr FAR * to,  
  int tolen                        
);

    int recvfrom (
   SOCKET s,                   
   char FAR* buf,              
   int len,                    
    int flags,                  
   struct sockaddr FAR* from,  
   int FAR* fromlen            
);

 

 

用Winsock2实现 :
  Winsock2的广播设置过程基本与 Winsock1相同:

//  第一步:创建套截字:
//用:WSASocket。
WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,
WSA_FLAG_MULTIPOINT_C_LEAF|    //控制层作为多播组的叶。
WSA_FLAG_MULTIPOINT_D_LEAF);    //数局层作为多播组的叶。

//  第三步:加入多播用:
SOCKET WSAJoinLeaf (
SOCKET s,                         //winsock2套接字             
const struct sockaddr FAR * name,      //多播地址
int namelen,                         //多播地址长度
LPWSABUF lpCallerData,                //呼叫者数据,没实现
   LPWSABUF lpCalleeData,            //被叫者数据,没实现
   LPQOS lpSQOS,                    //质量服务     
   LPQOS lpGQOS,                    //忽略,目前没实现
   DWORD dwFlags                       //发送,接收,兼具
);
//具体实施:
sockaddr_in  multyaddr;
multyaddr.sin_family      = AF_INET;
multyaddr.sin_port        = htons(m_port);
multyaddr.sin_addr.s_addr   = inet_addr(多播ip地址);
//加入多播
WSAJoinLeaf(套截字,(SOCKADDR*)&multyaddr,sizeof(multyaddr),
NULL,NULL,NULL,NULL,JL_BOTH)
//异常处理

 

posted @ 2012-07-04 17:26  littlestone08  阅读(279)  评论(0)    收藏  举报