组播
组播:(UDP)
发送方发送的组播数据包会传送到所有加入到组播组的主机上,主机上的接收方可以接收到该数据包。
加入组播地址的范围:
224.0.0.0----------------239.255.255.254的任意值一般不用结尾为0、1、255的IP
步骤:
发送端:socket—>指定发送地址为组播地址sendto
接收端:socket—>加入组播组—>bind—>recvfrom
案例:
组播发送:
#include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> int main(void) { int skt = socket(AF_INET, SOCK_DGRAM, 0); if(-1 == skt) { printf("socker error\n"); return -1; } //将IP和端口号存入结构体 struct sockaddr_in sddr; sddr.sin_family = AF_INET; sddr.sin_port = htons(7777); //设置为组播地址 sddr.sin_addr.s_addr = inet_addr("224.10.10.1"); int len = sizeof(struct sockaddr_in); char buf[100] = {'\0'}; while(1) { fgets(buf,100,stdin); sendto(skt, buf, sizeof(buf), 0, (struct sockaddr *)&sddr, len); puts(buf); memset(buf, 0,sizeof(buf)); } close(skt); return 0; }
组播接收:
#include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> int main(void) { int skt = socket(AF_INET, SOCK_DGRAM, 0); if(-1 == skt) { printf("socker error\n"); return -1; } //允许多次绑定 int on = 1; setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)); //加入组播组 struct ip_mreq mreq; bzero(&mreq,sizeof(mreq)); mreq.imr_multiaddr.s_addr = inet_addr("224.10.10.1"); mreq.imr_interface.s_addr = htonl(INADDR_ANY);//INADDR_ANY = 0x00000000 setsockopt(skt, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); //将IP和端口号存入结构体 struct sockaddr_in sddr; sddr.sin_family = AF_INET; sddr.sin_port = htons(7777); sddr.sin_addr.s_addr = inet_addr("0.0.0.0"); int len = sizeof(struct sockaddr_in); //将套接字和IP、端口号进行绑定 int ret = bind(skt, (struct sockaddr *)&sddr, sizeof(sddr)); if(-1 == ret) { printf("bind error\n"); return -1; } char buf[100] = {'\0'}; while(1) { recvfrom(skt, buf, sizeof(buf), 0, (struct sockaddr *)&sddr, &len);//0表示阻塞 puts(buf); } close(skt); return 0; }