linux 内核 怎么支持多播

linux 内核 怎么支持多播,第1张

应用程序通过命令字IP_ADD_MEMBERSHIP把一个socket加入到一个多播组,IP_ADD_MEMBERSHIP是一个IP层的命令字,其调用使用的参数是结构体struct ip_mreq,其定义如下: struct ip_mreq { struct in_addr imr_multiaddrstruct in_addr imr_interf...

这就要有PIM(Protocol Independent Multicast,协议无关组播组)协议的支持,就必须在Linux环境下安装Pimd软件协议包。 安装补丁文件 安装Pimd软件协议包需要两个补丁文件:pimkern-freebsd-4.6.patch和netstat-freebsd-4.6.patch。安装步骤如下: 首先将两个补丁文件拷贝到/usr/src/目录下,并执行以下命令:#patch -p2 <netstat-freebsd-4.6.patch #patch -p2 <pimkern-freebsd-4.6.patch 执行以下命令,编译并安装netstat:#cd /usr/src/usr.bin/netstat #make #make install 重新编译内核 执行以下命令,修改multi配置文件:#cd /usr/src/sys/i386/conf/ #cp GENRIC multi #vi multi 在multi配置文件中,加入下列两行代码:options MROUTING options PIM 保存并退出vi编辑器。 在当前multi配置文件所在的目录执行以下命令:#config multi #cd /usr/src/sys/compile/multi/ #make depend #make #make install 至此,新内核编译完毕。 备份Kernel文件 新内核编译完毕后,在重新启动前,要先将根目录下原有的Kernel文件进行备份。#cd / #mv kernel kernel.old 若提示“operation not permitted”,则需要先执行以下命令:#chflags noschg /kernel 备份Kernel文件后执行以下命令:#cp /usr/src/sys/compile/multi/kernel /kernel 在系统重新启动后,默认选择的便是新编译的内核。 安装Pimd软件协议包 Linux下Pimd软件协议包代码的起源有两个地方,一个是日本的KAME项目组,另一个是南加州大学信息科学学院。到这两个组织的主页上都可以下载所需要的pimd-current.tar.gz 协议包和上面提到的两个补丁。 用以下命令解压缩 pimd-current.tar.gz 软件包,并安装:#tar zxf pimd-current.tar.gz #cd pimd-2.1.0-alpha29.16 #make #make install 以上命令执行过程中可能会出现错误,需要手工将其完成,拷贝当前目录下的pimd文件:#cp pimd /usr/local/bin/ #chmod 755 pimd #cp pimd.conf /etc/ 至此,Pimd软件协议包安装完毕。还需要打开Linux系统的路由转发功能,才能实现组播包的转发,即在配置文件rc.conf中增加以下代码,重启后生效。作者:龙宇翔 苑庆国

socket创建UDP通信描述符后,setsockopt加入多播组,再bind绑定到该网卡上

//在指定的IP和端口上接收多播组的报文

int  recv_msg(char  *ip   , unsigned  short  port , char  *mult_ip )

{

//建立通讯套接字

int  fd = socket( PF_INET , SOCK_DGRAM , 0 )

if( -1 == fd )

{

perror("socket failed")

return  -1

}

//设置地址重用和接收多播

{

int  reuse = 1 

struct  ip_mreqn  mult_addr = {0}

mult_addr.imr_multiaddr.s_addr = inet_addr( mult_ip )

mult_addr.imr_address.s_addr = inet_addr( ip )

if( -1 == setsockopt( fd , IPPROTO_IP , IP_ADD_MEMBERSHIP ,

&mult_addr , sizeof(mult_addr)))

{

perror("setsockopt add failed")

goto  _out

}

if( -1 == setsockopt( fd , SOL_SOCKET, SO_REUSEADDR,

&reuse , sizeof(reuse) ) )

{

perror("setsockopt reuse failed")

}

}

//绑定地址和端口

{

struct  sockaddr_in  addr = {0}

addr.sin_family = PF_INET

addr.sin_port = htons( port )

addr.sin_addr.s_addr = INADDR_ANY

if( -1 == bind( fd , (struct sockaddr*)&addr ,

sizeof(addr) ) )

{

perror("bind failed")

goto  _out

}

}

//接收信息

while(1)

{

char  buf[128] = {0}

int   ret  = 0 

struct sockaddr_in  client_addr = {0}

int  len = sizeof(client_addr) 

ret = recvfrom( fd , buf , sizeof(buf), 0 , 

(struct sockaddr*)&client_addr ,

&len )

//被信号中断则重启

if( (-1 == ret)&&(EINTR ==errno ))

{

continue

}

else if( -1 ==ret )

{

perror("recvfrom failed")

goto  _out

}

else if( ret >0 )

{

printf("%s\n" , buf )

}

usleep( 100*1000 )

}

_out:

if( fd >= 0)

{

close( fd )

}

return  0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/5927903.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-08
下一篇 2023-03-08

发表评论

登录后才能评论

评论列表(0条)

保存