以多播方式传送数据
以多播方式传送数据
转自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) //异常处理
浙公网安备 33010602011771号