用c语言ipv6组播,需要适用于iOS 9的IPv6组播C代码

苹果现在要求iOS 9应用符合IPv6.我们几乎可以,除了一些发送UDP广播的代码 – 现在在iOS 9中失败了.

我看到的一切告诉我,UDP组播是在IPv6中这样做的正确方法.我已经找到一些示例代码,但是在我尝试过的任何版本的iOS或Mac OS X上都无效.

这个代码是从我们程序中的C/C++ lib调用的 – 很难回调到Swift,Obj-C,Java等.这段代码将由我们的应用程序的Mac OS X和Android版本共享.有人会认为可以在任何POSIX环境中的C中进行IPv6组播!

在下面的示例中,执行成功到最终的sendto()调用,实际发送UDP消息.失败后sendto()失败,errno设置为EBROKENPIPE(22).

我最好的猜测是我缺少一些需要的setsockopt()调用,或者使用错误的多播地址.现在,我被困了

这是我正在做的函数调用(在UDP端口4031上多播“有人在吗?”):

char *msg = "Is anybody out there?";

err = multicast_udp_msg ( "FF01::1111",4031,msg,strlen(msg) );

这是正在调用的代码:

// Multicasts a message on a specific UDP port.

// myhost - IPv6 address on which to multicast the message (i.e.,ourself)

// port - UDP port on which to broadcast the mssage

// msg - message contents to broadcast

// msgsize - length of message in bytes

// Return value is zero if successful,or nonzero on error.

int multicast_udp_msg ( char *myhost,short port,char *msg,size_t msgsize )

{

int sockfd,n;

char service[16] = { 0 };

int err = 0;

struct addrinfo hints = { 0 },*res,*ressave;

struct sockaddr_storage addr = { 0 };

hints.ai_family = AF_INET6;

hints.ai_socktype = SOCK_DGRAM;

sprintf ( service,"%hd",port );

n = getaddrinfo ( myhost,service,&hints,&res );

if ( n < 0 )

{

fprintf(stderr,"getaddrinfo error:: [%s]\n",gai_strerror(n));

return -1;

}

ressave = res;

sockfd = socket ( res->ai_family,res->ai_socktype,res->ai_protocol );

if ( sockfd >= 0 )

{

memcpy ( &addr,res->ai_addr,sizeof ( addr ) );

if ( joinGroup ( sockfd,8,&addr ) == 0 )

if ( bind ( sockfd,res->ai_addrlen ) == 0 )

if ( sendto ( sockfd,msgsize,(struct sockaddr *) &addr,sizeof ( addr ) ) < 0 )

err = errno;

close ( sockfd );

res = res->ai_next;

}

freeaddrinfo ( ressave );

return err;

}

int

joinGroup(int sockfd,int loopBack,int mcastTTL,struct sockaddr_storage *addr)

{

int r1,r2,r3,retval;

retval=-1;

switch (addr->ss_family) {

case AF_INET: {

struct ip_mreq mreq;

mreq.imr_multiaddr.s_addr=

((struct sockaddr_in *)addr)->sin_addr.s_addr;

mreq.imr_interface.s_addr= INADDR_ANY;

r1= setsockopt(sockfd,IPPROTO_IP,IP_MULTICAST_LOOP,&loopBack,sizeof(loopBack));

if (r1<0)

perror("joinGroup:: IP_MULTICAST_LOOP:: ");

r2= setsockopt(sockfd,IP_MULTICAST_TTL,&mcastTTL,sizeof(mcastTTL));

if (r2<0)

perror("joinGroup:: IP_MULTICAST_TTL:: ");

r3= setsockopt(sockfd,IP_ADD_MEMBERSHIP,(const void *)&mreq,sizeof(mreq));

if (r3<0)

perror("joinGroup:: IP_ADD_MEMBERSHIP:: ");

} break;

case AF_INET6: {

struct ipv6_mreq mreq6;

memcpy(&mreq6.ipv6mr_multiaddr,&(((struct sockaddr_in6 *)addr)->sin6_addr),sizeof(struct in6_addr));

mreq6.ipv6mr_interface= 0; // cualquier interfaz

r1= setsockopt(sockfd,IPPROTO_IPV6,IPV6_MULTICAST_LOOP,sizeof(loopBack));

if (r1<0)

perror("joinGroup:: IPV6_MULTICAST_LOOP:: ");

r2= setsockopt(sockfd,IPV6_MULTICAST_HOPS,sizeof(mcastTTL));

if (r2<0)

perror("joinGroup:: IPV6_MULTICAST_HOPS:: ");

r3= setsockopt(sockfd,IPV6_JOIN_GROUP,&mreq6,sizeof(mreq6));

if (r3<0)

perror("joinGroup:: IPV6_ADD_MEMBERSHIP:: ");

} break;

default:

r1=r2=r3=-1;

}

if ((r1>=0) && (r2>=0) && (r3>=0))

retval=0;

return retval;

}

想念欢迎!

-Tim

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值