摘要:
mc_svcttl;mc_clittl;mcjoin;smcrouted;omping
测试OK:(前提k8s-node07和k8s-node08运行smcrouted)
---> k8s-node07 smcroute.conf
mgroup from enp4s0f0 group 232.0.0.100
mroute from enp4s0f0 group 232.0.0.100 to cali1806a26ae62
mroute from cali1806a26ae62 group 232.0.0.100 to enp4s0f0
---> k8s-node08 smcroute.conf
mgroup from enp4s0f0 group 232.0.0.100
mroute from enp4s0f0 group 232.0.0.100 to califc3399243d8
mroute from califc3399243d8 group 232.0.0.100 to enp4s0f0
---
omping-a 172.27.29.185 k8s-node07
omping-b 172.19.199.175 k8s-node08
root@omping-a:/# mc_svcttl (!!!编译的代码组播地址改成了232.0.0.100)
[root@k8s-node07 home]# mcjoin -j 234.0.0.100 -p 8888
[root@k8s-node08 ~]# mcjoin -j 234.0.0.100 -p 8888
root@omping-b:/# mcjoin -j 234.0.0.100 -p 8888
root@omping-b:/# mc_clittl (!!!编译的代码组播地址改成了232.0.0.100)
(SO_REUSEADDR)Recv 0st message from server:BROADCAST TEST DATA 232.0.0.100:8888 TTL=64
- 但是,使用omping工具不太好用,显示是单播unicast,但实际组播也通。
root@omping-a:/# omping -m 232.0.0.100 -p 8888 172.27.29.185 172.19.199.175
172.19.199.175 : waiting for response msg
172.19.199.175 : joined (S,G) = (*, 232.0.0.100), pinging
172.19.199.175 : unicast, seq=1, size=69 bytes, dist=2, time=0.842ms
root@omping-b:/# omping -m 232.0.0.100 -p 8888 172.27.29.185 172.19.199.175
172.27.29.185 : joined (S,G) = (*, 232.0.0.100), pinging
172.27.29.185 : unicast, seq=1, size=69 bytes, dist=2, time=0.633ms
root@omping-b:/# mc_clittl
(SO_REUSEADDR)Recv 0st message from server:I
root@omping-b:/# mcjoin -j 232.0.0.100 -p 8888 //能收到字母:I
1、多播服务程序:MCAST_ADDR "234.0.0.100" MCAST_PORT 8888
/*
* *broadcast_server.c - 多播服务程序
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MCAST_PORT 8888
#define MCAST_ADDR "234.0.0.100" /*一个局部连接多播地址,路由器不进行转发*/
#define MCAST_DATA "BROADCAST TEST DATA 234.0.0.100:8888" /*多播发送的数据*/
#define MCAST_INTERVAL 5 /*发送间隔时间*/
int main(int argc, char*argv)
{
int s;
struct sockaddr_in mcast_addr;
s = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字*/
if (s == -1)
{
perror("socket()");
return -1;
}
memset(&mcast_addr, 0, sizeof(mcast_addr));/*初始化IP多播地址为0*/
mcast_addr.sin_family = AF_INET; /*设置协议族类行为AF*/
mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);/*设置多播IP地址*/
mcast_addr.sin_port = htons(MCAST_PORT); /*设置多播端口*/
/*向多播地址发送数据*/
while(1) {
int n = sendto(s, /*套接字描述符*/
MCAST_DATA, /*数据*/
sizeof(MCAST_DATA), /*长度*/
0,
(struct sockaddr*)&mcast_addr,
sizeof(mcast_addr)) ;
if( n < 0)
{
perror("sendto()");
return -2;
}
sleep(MCAST_INTERVAL); /*等待一段时间*/
}
return 0;
}
2、多播的客户端:MCAST_ADDR "234.0.0.100" MCAST_PORT 8888
/*
* *broadcast_client.c - 多播的客户端
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define MCAST_PORT 8888
#define MCAST_ADDR "234.0.0.100" /*234组播地址全局有效,路由器进行转发*/
#define MCAST_INTERVAL 5 /*发送间隔时间*/
#define BUFF_SIZE 256 /*接收缓冲区大小*/
int main(int argc, char*argv[])
{
int s; /*套接字文件描述符*/
struct sockaddr_in local_addr; /*本地地址*/
int err = -1;
s = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字*/
if (s == -1)
{
perror("socket()");
return -1;
}
/*设定 SO_REUSEADDR,允许多个应用绑定同一个本地端口接收数据包*/
int reuse = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
{
perror("Setting SO_REUSEADDR error");
close(s);
exit(1);
}
/*初始化地址*/
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(MCAST_PORT);
/*bind绑定本地端口,IP为INADDR_ANY,从而能接收组播数据包。*/
err = bind(s,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;
if(err < 0)
{
perror("bind()");
return -2;
}
/*设置回环许可*/
int loop = 1;
err = setsockopt(s,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));
if(err < 0)
{
perror("setsockopt():IP_MULTICAST_LOOP");
return -3;
}
struct ip_mreq mreq; /*加入多播组*/
mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*多播地址*/
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*网络接口为默认*/
/*将本机加入多播组*/
err = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof
(mreq));
if (err < 0)
{
perror("setsockopt():IP_ADD_MEMBERSHIP");
return -4;
}
int times = 0;
int addr_len = 0;
char buff[BUFF_SIZE];
int n = 0;
/*循环接收多播组的消息,5次后退出*/
for(times = 0;times<15;times++)
{
addr_len = sizeof(local_addr);
memset(buff, 0, BUFF_SIZE); /*清空接收缓冲区*/
/*接收数据*/
n = recvfrom(s, buff, BUFF_SIZE, 0,(struct sockaddr*)&local_addr,
&addr_len);
if( n== -1)
{
perror("recvfrom()");
}
/*打印信息*/
printf("(SO_REUSEADDR)Recv %dst message from server:%s\n", times, buff);
sleep(MCAST_INTERVAL);
}
/*退出多播组*/
err = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof
(mreq));
close(s);
return 0;
}