#pragma comment(lib,"ws2_32.lib")
#include<winsock2.h>
#include<stdio.h>
#include<WS2tcpip.h>
#ifndef _MCASTLIB_H_
#define _MCASTLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
int mc_join(SOCKET s, struct in_addr *mcaddr, struct in_addr *local_if);
int mc_setIF(SOCKET s, const DWORD local_out_if);
int mc_getIF(SOCKET s, DWORD *local_out_if);
int mc_setTTL(SOCKET s, const DWORD ttl);
int mc_getTTL(SOCKET s, DWORD *ttl);
int mc_setLoop(SOCKET s, const BOOL flag);
int mc_getLoop(SOCKET s, BOOL *flag);
int mc_leave(SOCKET s, struct in_addr *mcaddr, struct in_addr *local_if);
#ifdef __cplusplus
}
#endif
#endif
// 本地接口local_if加入多播组mcaddr
int mc_join(SOCKET s,struct in_addr *mcaddr, struct in_addr *local_if)
{
struct ip_mreq mreq;
memcpy(&(mreq.imr_interface), local_if, sizeof(struct in_addr)); // local if
memcpy(&(mreq.imr_multiaddr), mcaddr, sizeof(struct in_addr)); // mutilcast group address
return (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)));
}
// 为多播报文设置外出接口
int mc_setIF(SOCKET s, const DWORD local_out_if)
{
return (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&local_out_if,
sizeof(local_out_if)));
}
// 获取多播报文的外出接口
int mc_getIF(SOCKET s, DWORD *local_out_if)
{
int len = sizeof(DWORD);
return (getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&local_out_if, &len));
}
// 设置外出多播报文的ttl值,默认为1
int mc_setTTL(SOCKET s, const DWORD ttl)
{
return (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)));
}
// 获取外出多播报文的ttl值
int mc_getTTL(SOCKET s, DWORD *ttl)
{
int len = sizeof(DWORD);
return (getsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,(char *)ttl,&len));
}
int mc_setLoop(SOCKET s,const BOOL flag)
{
return (setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,(char *)flag,sizeof(flag)));
}
int mc_getLoop(SOCKET s,BOOL *flag)
{
int len = sizeof(BOOL);
return(getsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,(char *)flag,&len));
}
int mc_leave(SOCKET s,struct in_addr *mcaddr,struct in_addr *local_if)
{
struct ip_mreq mreq;
memcpy(&(mreq.imr_interface),local_if,sizeof(struct in_addr));
memcpy(&(mreq.imr_multiaddr),mcaddr,sizeof(struct in_addr));
return(setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char *)&mreq,sizeof(mreq)));
}
void main(int argc,char* argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
SOCKET sock = socket(AF_INET,SOCK_DGRAM,0);
char name[255];
char *ip; //定义IP地址变量
PHOSTENT hostinfo;
gethostname ( name, sizeof(name)) ;
//如果成功地将本地主机名存放入由name参数指定的缓冲区中
hostinfo = gethostbyname(name);
//这是获取主机名,如果获得主机名成功的话,将返回一个指针,指向hostinfo,hostinfo
//为PHOSTENT型的变量,下面即将用到这个结构体
ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
//调用inet_ntoa()函数,将hostinfo结构变量中的h_addr_list转化为标准的点分表示的IP
//地址(如192.168.0.1)
printf("本机ip: %s\n",ip);//输出IP地址
struct sockaddr_in to;
memset(&to,0,sizeof(to));
to.sin_family=AF_INET;
to.sin_port=htons(9999);
to.sin_addr.S_un.S_addr=inet_addr(ip);
bind(sock,(struct sockaddr *)&to,sizeof(to));
struct in_addr mcaddr;
mcaddr.s_addr =inet_addr("226.1.2.3");
mc_join(sock,&mcaddr,&(to.sin_addr));
char buf[65] ;
while(1){
memset(buf,0,65);
recvfrom(sock,buf,64,0,NULL,NULL);
printf("recvd: %s\n",buf);
}
}