UDP组播支持
在https://github.com/ithewei/libhv/issues/251 中看到有UDP组播需求,我这里也正好有这个需求。
仿udp_broadcast()接口实现了一个。名称参考Qt的joinMulticastGroup()、leaveMulticastGroup()接口,但区分IPv4和IPv6两个版本。总共4个接口
HV_INLINE int udp_joinmulticastgroupv4(int sockfd, const char* group, const char* local_host);
HV_INLINE int udp_leavemulticastgroupv4(int sockfd, const char* group, const char* local_host);
HV_INLINE int udp_joinmulticastgroupv6(int sockfd, const char* group, ULONG interface);
HV_INLINE int udp_leavemulticastgroupv6(int sockfd, const char* group, ULONG interface);
能否提个PR过来,添加到哪个分支,放在hsocket.h中作为HV_INLINE是合适?
请您给个指示。
实现如下
HV_INLNE int udp_joinmulticastgroupv4(int sockfd, const char* group, const char* local_host) {
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group);
mreq.imr_interface.s_addr = inet_addr(local_host);
return setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
}
HV_INLNE int udp_leavemulticastgroupv4(int sockfd, const char* group, const char* local_host) {
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group);
mreq.imr_interface.s_addr = inet_addr(local_host);
return setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
}
HV_INLNE int udp_joinmulticastgroupv6(int sockfd, const char* group, ULONG interface) {
struct ipv6_mreq mreq;
mreq.ipv6mr_interface = interface;
inet_pton(AF_INET6, group, &mreq.ipv6mr_multiaddr);
return setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
}
HV_INLNE int udp_leavemulticastgroupv6(int sockfd, const char* group, ULONG interface) {
struct ipv6_mreq mreq;
mreq.ipv6mr_interface = interface;
inet_pton(AF_INET6, group, &mreq.ipv6mr_multiaddr);
return setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
}
欢迎提PR,可以提到master分支
大佬快提pr啊,我也有这个需求
我这里名字还没想好,这个名字太长了。
还有测试还没怎么做,只有IPV4的组播加入和离开试了一下。
如果你着急用,下边这些代码可以加入你程序里,自行编译顶着先。
添加一个头文件或实现文件,或放到UdpClinet.h里
int udp_joinmulticastgroupv4(int sockfd, const char* group, const char* local_host) {
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group);
mreq.imr_interface.s_addr = inet_addr(local_host);
return setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
}
int udp_leavemulticastgroupv4(int sockfd, const char* group, const char* local_host) {
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group);
mreq.imr_interface.s_addr = inet_addr(local_host);
return setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
}
int udp_joinmulticastgroupv6(int sockfd, const char* group, ULONG interface) {
struct ipv6_mreq mreq;
mreq.ipv6mr_interface = interface;
inet_pton(AF_INET6, group, &mreq.ipv6mr_multiaddr);
return setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
}
int udp_leavemulticastgroupv6(int sockfd, const char* group, ULONG interface) {
struct ipv6_mreq mreq;
mreq.ipv6mr_interface = interface;
inet_pton(AF_INET6, group, &mreq.ipv6mr_multiaddr);
return setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq));
}
在UdpClient.h文件class UdpClientEventLoopTmpl中添加
//multicast group
int joinmulticastgroupv4(const char* group, const char* local_host = "0.0.0.0"){
return udp_joinmulticastgroupv4(channel->fd(), group, local_host);
}
然后在主程序文件UdpClient_test.cpp中添加
int gport = atoi(argv[2]);
cli.bind(gport, "0.0.0.0");
std::cout <<"bind local port:" <<gport <<std::endl;
cli.joinmulticastgroupv4("230.1.1.25", "0.0.0.0");
基本就可以了。
这是我测试组播发送的一个截图
好的,谢谢大佬
我已经添加了UDP组播的加入和离开方法,并进行了测试。 PR在 https://github.com/ithewei/libhv/pull/480
我已经添加了UDP组播的加入和离开方法,并进行了测试。 PR在 #480
interface 为啥有的是 ULONG 有的是 char* ?
IPV4是描述绑定本机IP的地址,是char*。
IPV6是描述绑定本机接口,是ULONG。
这是根据 ip_mreq、ipv6_mreq的不同结构体定义给出的,这样更直接,没有转换。
网上搜到是这个结构体,我就用上了。