2015-10-02 2 views
10

पर काम करता है ऐप्पल को अब आईओएस 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 पर मल्टीकास्ट करने के लिए "वहाँ किसी को भी है?") समारोह कॉल मैं बना रहा हूं है विचार स्वागत है!

टिम

+2

इस बारे में सोचने की एक बात यह है कि आईपीवी 6 मल्टीकास्ट झंडे, स्कोप्स और श्रेणियों का उपयोग करता है जिन्हें आपको वास्तव में सही होने की आवश्यकता होती है। उदाहरण के लिए, 'एफएफ 01 ::/112' रेंज एक नोड-लोकल स्कोप है, लेकिन मुझे लगता है कि आप वास्तव में एक लिंक-स्थानीय दायरे जैसे' एफएफ 022 ::/112' की तलाश में हैं। –

+0

मैंने एफएफ 022 :: 1 और एफएफ 022: 1111 की कोशिश की। वही परिणाम: sendto() रिटर्न -1, त्रुटि सेट 22 (EBROKENPIPE)। हम दोनों यहाँ अनुमान लगा रहे हैं। आईओएस 9 पर मल्टीकास्ट लागू करने वाले किसी और ने क्या किया है? –

+0

मैं बस इतना कह रहा था कि आपको चुनने वाले मल्टीकास्ट पते के बारे में सावधान रहना होगा। मुझे नहीं पता कि लिंक-लोकल स्कोप आप जो करने की कोशिश कर रहे हैं उसके लिए सही है (वह दायरा लिंक नहीं छोड़ेगा, जैसे कि नोड-स्थानीय स्कोप नोड को नहीं छोड़ेगा)। यदि आप देखते हैं, तो FF02 :: 1 ऑल नोड्स पता है। आपको मेजबान और नेटवर्क पर आईपीवी 6 कॉन्फ़िगर करने की आवश्यकता है जहां आप इसका परीक्षण करने की कोशिश कर रहे हैं (आईपीवी 6 यूनिकास्ट पते के माध्यम से पिंग करने में सक्षम हो)।फिर आपको आईपीवी 6 मल्टीकास्ट आरएफसी का अध्ययन करने की आवश्यकता है, जो आपको लगता है कि हिट-या-मिस की बजाय एक बुद्धिमान समूह चयन करने के लिए। –

उत्तर

6

कुछ एप्पल के साथ और कुछ अतिरिक्त संदर्भ पीछे और आगे, के बाद, हम एक जवाब है। लेकिन यह मेरे मूल प्रश्न का उत्तर नहीं है। - एक स्थानीय WI-पर एक विरासत एम्बेडेड उपकरण खोजने अर्थात्,

https://forums.developer.apple.com/message/71107

ऐसा लगता है कि आईपीवी 6 बहुस्त्र्पीय क्या हम हाथ में असली समस्या को हल करने के लिए आवश्यक वास्तव में नहीं था: सबसे पहले, यहाँ संदर्भ के लिए एप्पल धागा है फाई नेटवर्क हमें वास्तव में ऐसा करने के लिए आईपीवी 4 यूडीपी प्रसारण का उपयोग करना पड़ा। हमारे एम्बेडेड डिवाइस आईपीवी 6 मल्टीकास्ट पैकेट को अनदेखा करते हैं जैसे पृथ्वी न्यूट्रिनो इसके माध्यम से उड़ती है।

ऐप्पल ने हमें एक सेटॉकॉप्ट() कॉल दिया जो आईपीवी 4 यूडीपी को आईएसओ 9 में एक इंफ्रास्ट्रक्चर वाई-फाई नेटवर्क पर काम करने में सक्षम बनाता है। इस सुविधा के लिए यह इच्छित उपयोग केस है। और ऐप्पल ने हमें असफलता का संभावित कारण भी दिया जब वह प्रसारण विज्ञापन हॉक वाई-फाई नेटवर्क में काम करने में असफल रहा (जो एक ज्ञात आईओएस 9 मुद्दा है)।

तो, हालांकि मेरे मूल प्रश्न का उत्तर यहां दिया नहीं गया है, अंतर्निहित मुद्दा हल हो गया है।

संबंधित मुद्दे