vcudp通信socketsetsockopt组播广播多播是有个多播地址,是在224.0.0.0到239.255.255.255之间的IP地址,但是有一些特殊(保留)的不能用包括:224.0.0.0基本地址224.0.0.1子网上的所有系统224.0.0.2子网上的所有路由器224.0.0.5子网上所有OSPF路由器224.0.0.6子网上所有指定的OSPF路由器224.0.0.9RIP第2版本组地址224.0.1.1网络时间协议224.0.1.24WINS服务器组地址可以说组播是广播的改进.下面是用socket1.1,用setsockopt()函数来加入一个多播组,其包括内容:1.IP_ADD_MEMBERSHIP:加入一个多播组2.IP_DROP_MEMBERSHIP:离开一个多播组3.IP_MULTICAST_IF:指定外出多播数据报的外出接口4.IP_MULTICAST_TTL:TTL数5.IP_MULTICAST_LOOP:是否禁止回馈,我的理解是一台机器是否可以接收到自己发送的多播数据报在接收段只需要加入一个多播组,其余的和正常UDP一样处理组播IPIPIPIP地址是在224.0.0.0224.0.0.0224.0.0.0224.0.0.0到239.255.255.255239.255.255.255239.255.255.255239.255.255.255之间,接收端socketsocketsocketsocket绑定的端口号应该与发送端目的地址的端口号一致接收端:#includeWINSOCK2.H#includestdio.h#includeWs2tcpip.h#defineMCASTADDR225.0.0.10#pragmacomment(lib,ws2_32)intmain(void){WSADATAws;intret;SOCKETsock;SOCKADDR_INlocalAddr,remoteAddr;intlen=sizeofSOCKADDR;charrecvBuf[100];ip_mreqmcast;//设置多播(组播)ret=WSAStartup(MAKEWORD(2,2),&ws);if(0!=ret){printf(WSAStartup失败\n);}sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);if(INVALID_SOCKET==sock){WSACleanup();printf(socket创建失败\n);}localAddr.sin_family=AF_INET;localAddr.sin_port=htons(9999);//注意端口号应该与发送端目的地址的端口号一致localAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);ret=bind(sock,(SOCKADDR*)&localAddr,len);if(SOCKET_ERROR==ret){closesocket(sock);printf(bind失败\n);}//用于接收多播所设置,把套接字加入一个多播组memset(&mcast,0x00,sizeof(mcast));mcast.imr_multiaddr.S_un.S_addr=inet_addr(MCASTADDR);mcast.imr_interface.S_un.S_addr=htonl(INADDR_ANY);ret=setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));if(SOCKET_ERROR==ret){printf(IP_ADD_MEMBERSHIPERROR!CODEIS:%d\n,WSAGetLastError());}memset(&remoteAddr,0x00,len);memset(recvBuf,0x00,sizeof(recvBuf));while(TRUE){ret=recvfrom(sock,recvBuf,sizeof(recvBuf),0,(SOCKADDR*)&remoteAddr,&len);if(ret0){printf(收到数据:%s\n,recvBuf);printf(分析发送端的ip地址为:%s\n,inet_ntoa(remoteAddr.sin_addr));break;}}shutdown(sock,SD_BOTH);closesocket(sock);chars;scanf(%c,&s);return0;}发送端:#includeWINSOCK2.H#includestdio.h#includeWs2tcpip.h//组播要用到的头文件#define_ADD_GROUP//可以不加入组也可以向组内发信息#defineMCASTADDR225.0.0.10#pragmacomment(lib,ws2_32)intmain(void){WSADATAws;intret;SOCKETsock;SOCKADDR_INlocalAddr,remoteAddr;intlen=sizeofSOCKADDR;ip_mreqmcast;//设置多播(组播)ret=WSAStartup(MAKEWORD(2,2),&ws);if(0!=ret){return1;}sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);if(INVALID_SOCKET==sock){WSACleanup();return1;}localAddr.sin_family=AF_INET;localAddr.sin_port=htons(3000);localAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);ret=bind(sock,(SOCKADDR*)&localAddr,len);if(SOCKET_ERROR==ret){return1;}//设置多播(组播)发送remoteAddr.sin_family=AF_INET;remoteAddr.sin_port=htons(9999);remoteAddr.sin_addr.S_un.S_addr=inet_addr(MCASTADDR);intbMLoop=1;ret=setsockopt(sock,IPPROTO_IP,IP_MULTICAST_LOOP,(char*)&bMLoop,sizeof(bMLoop));if(SOCKET_ERROR==ret){printf(IP_MULTICAST_LOOPerror!CODEis:%d\n,WSAGetLastError());return1;}intdwRoute=6;ret=setsockopt(sock,IPPROTO_IP,IP_MULTICAST_TTL,(char*)&dwRoute,sizeof(dwRoute));if(SOCKET_ERROR==ret){printf(IP_MULTICAST_TTLerror!CODEis:%d\n,WSAGetLastError());return1;}memset(&mcast,0x00,sizeof(mcast));mcast.imr_multiaddr.S_un.S_addr=inet_addr(MCASTADDR);mcast.imr_interface.S_un.S_addr=htonl(INADDR_ANY);#ifdef_ADD_GROUPret=setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast));if(SOCKET_ERROR==ret){printf(IP_ADD_MEMBERSHIPERROR!CODEIS:%d\n,WSAGetLastError());return1;}#endifsendto(sock,hello,6,0,(SOCKADDR*)&remoteAddr,len);#ifdef_ADD_GROUP//离开一个多播组ret=setsockopt(sock,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char*)&mcast,sizeof(mcast));if(SOCKET_ERROR==ret){printf(IP_DROP_MEMBERSHIPERROR!CODEIS:%d\n,WSAGetLastError());return1;}#endifshutdown(sock,2);//这里的2在win32中可以写为SD_BOTHclosesocket(sock);WSACleanup();chars;printf(数据已发送\n);scanf(%c,&s);return0;}