पर काम करता है ऐप्पल को अब आईओएस 9 ऐप्स को आईपीवी 6 अनुपालन की आवश्यकता है। हम यूडीपी प्रसारण भेजते हुए थोड़ा सा कोड छोड़कर अधिकतर ठीक हैं - यह अब आईओएस 9 में विफल रहता है।आईपीवी 6 मल्टीकास्ट सी कोड की आवश्यकता है जो आईओएस 9
जो कुछ भी मैंने पढ़ा है, वह मुझे बताता है कि यूपीपी मल्टीकास्ट आईपीवी 6 में ऐसा करने का सही तरीका है। मुझे कुछ उदाहरण कोड मिला है, लेकिन यह आईओएस या मैक ओएस एक्स के किसी भी संस्करण पर काम नहीं करता है मैंने कोशिश की है।
इस कोड को हमारे प्रोग्राम के अंदर सी/सी ++ lib से कहा जा रहा है - स्विफ्ट, ओब्जे-सी, जावा इत्यादि में कॉलबैक करना मुश्किल है और यह कोड मैक ओएस एक्स और एंड्रॉइड संस्करण द्वारा साझा किया जाएगा हमारा ऐप कोई सोचता है कि किसी भी पॉज़िक्स पर्यावरण में सी में आईपीवी 6 मल्टीकास्ट करना संभव है!
नीचे दिए गए नमूने में, निष्पादन अंतिम प्रेषण() कॉल तक सफल होता है, जो वास्तव में यूडीपी संदेश भेजता है। वह sendto() असफल होने के बाद इरनो सेट EBROKENPIPE (22) के साथ विफल रहता है।
मेरा सबसे अच्छा अनुमान यह है कि मुझे कुछ आवश्यक सेटॉकॉप() कॉल याद आ रही है, या गलत मल्टीकास्ट पते का उपयोग कर रहा हूं। अभी, मैं फंस गया हूँ।
// 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, 0, 8, &addr) == 0)
if (bind (sockfd, res->ai_addr, res->ai_addrlen) == 0)
if (sendto (sockfd, msg, msgsize, 0, (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, IPPROTO_IP, IP_MULTICAST_TTL,
&mcastTTL, sizeof(mcastTTL));
if (r2<0)
perror("joinGroup:: IP_MULTICAST_TTL:: ");
r3= setsockopt(sockfd, IPPROTO_IP, 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,
&loopBack, sizeof(loopBack));
if (r1<0)
perror("joinGroup:: IPV6_MULTICAST_LOOP:: ");
r2= setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&mcastTTL, sizeof(mcastTTL));
if (r2<0)
perror("joinGroup:: IPV6_MULTICAST_HOPS:: ");
r3= setsockopt(sockfd, IPPROTO_IPV6,
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;
}
:
char *msg = "Is anybody out there?";
err = multicast_udp_msg ("FF01::1111", 4031, msg, strlen(msg));
यहाँ कोड है कि बुलाया जा रहा है:
यहाँ (UDP पोर्ट 4031 पर मल्टीकास्ट करने के लिए "वहाँ किसी को भी है?") समारोह कॉल मैं बना रहा हूं है विचार स्वागत है!
टिम
इस बारे में सोचने की एक बात यह है कि आईपीवी 6 मल्टीकास्ट झंडे, स्कोप्स और श्रेणियों का उपयोग करता है जिन्हें आपको वास्तव में सही होने की आवश्यकता होती है। उदाहरण के लिए, 'एफएफ 01 ::/112' रेंज एक नोड-लोकल स्कोप है, लेकिन मुझे लगता है कि आप वास्तव में एक लिंक-स्थानीय दायरे जैसे' एफएफ 022 ::/112' की तलाश में हैं। –
मैंने एफएफ 022 :: 1 और एफएफ 022: 1111 की कोशिश की। वही परिणाम: sendto() रिटर्न -1, त्रुटि सेट 22 (EBROKENPIPE)। हम दोनों यहाँ अनुमान लगा रहे हैं। आईओएस 9 पर मल्टीकास्ट लागू करने वाले किसी और ने क्या किया है? –
मैं बस इतना कह रहा था कि आपको चुनने वाले मल्टीकास्ट पते के बारे में सावधान रहना होगा। मुझे नहीं पता कि लिंक-लोकल स्कोप आप जो करने की कोशिश कर रहे हैं उसके लिए सही है (वह दायरा लिंक नहीं छोड़ेगा, जैसे कि नोड-स्थानीय स्कोप नोड को नहीं छोड़ेगा)। यदि आप देखते हैं, तो FF02 :: 1 ऑल नोड्स पता है। आपको मेजबान और नेटवर्क पर आईपीवी 6 कॉन्फ़िगर करने की आवश्यकता है जहां आप इसका परीक्षण करने की कोशिश कर रहे हैं (आईपीवी 6 यूनिकास्ट पते के माध्यम से पिंग करने में सक्षम हो)।फिर आपको आईपीवी 6 मल्टीकास्ट आरएफसी का अध्ययन करने की आवश्यकता है, जो आपको लगता है कि हिट-या-मिस की बजाय एक बुद्धिमान समूह चयन करने के लिए। –