سؤال

حسنًا ، أنا في حيرة هنا تمامًا. يبدو أن نسبة مئوية صغيرة من المستخدمين لديهم أخطاء سيئة في ترجمة اسم المضيف الخاص بي.

الحادث الكامل أدناه:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: 0x000000000000000d, 0x0000000000000000
Crashed Thread:  21

Thread 21 Crashed:
0   libSystem.B.dylib               0x00007fff8406a446 _mdns_query_callback + 275
1   libSystem.B.dylib               0x00007fff84057fc8 handle_query_response + 296
2   libSystem.B.dylib               0x00007fff84057433 DNSServiceProcessResult + 717
3   libSystem.B.dylib               0x00007fff84069cf3 _mdns_query_mDNSResponder + 1180
4   libSystem.B.dylib               0x00007fff84069090 _mdns_search + 1458
5   libSystem.B.dylib               0x00007fff840682f1 _mdns_addrinfo + 716
6   libSystem.B.dylib               0x00007fff84067373 search_addrinfo + 146
7   libSystem.B.dylib               0x00007fff84066d9c si_addrinfo + 1352
8   libSystem.B.dylib               0x00007fff840667ad getaddrinfo + 159
9   com.NZBVortex.NZBVortex         0x000000010002a4d7 -[CFNetworkStream getHostAddress:sockAddressIn:] + 152
10  com.NZBVortex.NZBVortex         0x000000010002a622 -[CFNetworkStream openBSDSocket::] + 252

فيما يلي الرمز الذي أستخدمه لحل DNS (الأجزاء المهمة). نسيت شيئا ما هنا؛ هل يمكنني إضافة المزيد من الشيكات؟ إنه مجرد عدد منخفض جدًا من المستخدمين ، لذلك ليس لدى الآلاف أي مشاكل.

جزء من رمز حل اسم المضيف الخاص بي: طريقة [cfnetWorkstream OpenBsdSocket ::

-(bool)openBSDSocket:(NSString*)hostName:(int)port {
    struct sockaddr_in remoteAddr;

    remoteAddr.sin_family = AF_INET;
    remoteAddr.sin_port = htons(port);

    if ([self getHostAddress:hostName sockAddressIn:&remoteAddr]) {
        //some non-related code
    }
}

والتي بدورها تستدعي طريقة [Gethostaddress: xxxx] أدناه الطريقة الكاملة:

-(bool)getHostAddress:(NSString*)hostname sockAddressIn:(struct sockaddr_in*)result {
    struct addrinfo hints, *res, *iterateRes;
    int retval;

    memset (&hints, 0, sizeof (struct addrinfo));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags |= AI_CANONNAME;

    int maxLength = [hostname length]+1;
    const char hostNameC[maxLength];
    struct in_addr *inAddr;
    bool foundAddress = NO;

    if (hostNameC!=NULL) {
        [hostname getCString:(void*)&hostNameC maxLength:maxLength encoding:NSASCIIStringEncoding];

        retval = getaddrinfo (hostNameC, NULL, &hints, &res);
        if (retval == 0) {

            iterateRes = res;
            while (iterateRes && !foundAddress) {
                switch (iterateRes->ai_family)
                {
                    case AF_INET:
                        inAddr = &((struct sockaddr_in *) iterateRes->ai_addr)->sin_addr;
                        memcpy(&(result->sin_addr), inAddr, sizeof(inAddr));
                        foundAddress = YES;
                }
                iterateRes = iterateRes->ai_next;
            }
        }

        freeaddrinfo (res);
    }

    return foundAddress;
}

هل يمكن أن تعطيني استشارة؟ يبدو أنني عالق حقًا هنا ، مصل اللبن هل يرى هؤلاء (منخفض) من المستخدمين المشكلات في هذا الرمز؟ هل أحتاج إلى شيكات إضافية؟

يمكنني حقًا استخدام نصائحك/استشارة.

هام: يقول المستخدمون المتأثرون إنه يحدث فقط إذا تم إسقاط الشبكة. لكن لا يمكنني قبول أن اتصال شبكة إسقاط يمكن أن ينشئ المشكلات المذكورة أعلاه؟

تحرير: لقد أجريت اختبار تسرب. لفترة طويلة عن طريق مزيف أي نتيجة DNS (إذا (Retval! = 0)) ، ولكن لا تتسرب الذاكرة على جهاز Mac الخاص بي.

هل كانت مفيدة؟

المحلول 2

حسنًا ، لقد قمت بإصلاحها من خلال التأكد من أن getaddrinfo لا يتم استدعاؤه في كثير من الأحيان من قبل العديد من المواضيع في نفس الوقت. وأضاف أيضا ذاكرة التخزين المؤقت المحلية للنتائج (A في App DNS Cache).

أعتقد أن المشكلة الحقيقية هي أنه عندما يواجه المستخدمون مشاكل في الاتصال ، قد تكون العديد من مؤشرات ترابط الاتصال أكثر من اللازم Getaddrinfo كثيرًا حتى تنكسر.

نصائح أخرى

حسنًا ، لشيء واحد الاختبار if (hostNameC!=NULL) لا ينجز أي شيء: hostnameC هي صفيف (وليس مؤشر) ، ولن يكون أبدًا == فارغ. لذا ، هل تتعامل مع الحالة التي يكون فيها اسم المضيف == null ، أو اسم المضيف هو طوله صفري؟

أنت لا تتحقق من قيمة الإرجاع -getCString: maxLength: encoding:; ؛ إذا فشلت تلك المكالمة ، فستمرر القمامة غير المعدلة إلى getaddrinfo.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top