2012-11-23 21 views
8

प्राप्त करना मैं पूल.एनटीपी.ऑर्ग से समय सिंक पर कनेक्ट करना चाहता हूं। तो एक सॉकेट बनाने रहाआईओएस डेटा टाइमआउट सीएफएसओकेट

sock=CFSocketCreate(NULL, PF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketDataCallBack|kCFSocketWriteCallBack|kCFSocketConnectCallBack, sockCallback, &sock_ctx); 

तो एक पाश

sockref=CFSocketCreateRunLoopSource(NULL, sock, 0); 
CFRunLoopAddSource(CFRunLoopGetMain(), sockref, kCFRunLoopCommonModes); 

की स्थापना कर रहा हूँ और पता

CFDataRef adrref=CFDataCreate(NULL, (const UInt8 *)&adr, sizeof(adr)); 
    CFSocketError err=CFSocketConnectToAddress(sock, adrref,-1); 

से कनेक्ट कर मैं आवश्यक डेटा भेजने अगर मैं कालबैक kCFSocketWriteCallBack है

 CFDataRef bufref=CFDataCreate(NULL, buffer, scl->NTP_PACKET_SIZE); 
    CFSocketError error = CFSocketSendData(scl->sock, NULL, bufref,3); 

यहां तक ​​कि सब कुछ सही काम करता है। मेरी वास्तविक समस्या

else if(callbackType==kCFSocketDataCallBack) 

9/10 बार ठीक काम कर रहा है। सर्वर प्रतिक्रिया भेज रहा है और मेरी प्रक्रिया जारी है। समस्या यह है कि मेरे ऐप तर्क को जारी रखने के लिए डेटा आने की प्रतीक्षा कर रहा हूं। यदि कोई डेटा kCFSocketDataCallBack नहीं आता है तो ट्रिगर नहीं किया गया है और ऐप हमेशा के लिए प्रतीक्षा कर रहा है। क्या डेटा प्राप्त करने के इंतजार में मुझे टाइमआउट डालने का कोई तरीका है? (पूल से पुनः कनेक्ट करने के लिए खुद को NSTimer के बिना)

+0

मुझे एक ही समस्या का सामना करना पड़ता है, क्या आपको कोई समाधान मिल रहा है? – xjdrew

उत्तर

1

मुझे लगता है कि यहां जानना महत्वपूर्ण बात यह है कि यूडीपी स्वाभाविक रूप से अविश्वसनीय है।

इसलिए यह बिल्कुल संभव और सामान्य व्यवहार है कि पैकेट खो जाते हैं और आपको कभी-कभी प्रतिक्रिया नहीं मिलती है। आप 10 बार में से 9 बार काम करते हैं, जो यूडीपी आधारित प्रोटोकॉल के लिए बहुत अच्छा लगता है।

तो मुझे लगता है कि आपको वास्तव में अपने कोड को थोड़ा अधिक स्मार्ट बनाने की आवश्यकता है। मुझे यह भी लगता है कि एक निश्चित राशि के भीतर वास्तव में प्रतिक्रिया प्राप्त करने के लिए टाइमर का उपयोग करने के आसपास कोई रास्ता नहीं है।

सौभाग्य से आपके लूप पर CFRunLoopTimer शेड्यूल करना बहुत आसान है।

  1. जब आप पहली बार के लिए CFSocketSendData फोन आप भी एक CFRunLoopTimer जोड़ें: क्या आप क्या करने की जरूरत है।
  2. आप एक kCFSocketDataCallBack कॉलबैक आप टाइमर
  3. रद्द प्राप्त आप एक प्रतिक्रिया कभी नहीं मिलता है, तो या प्रतिक्रिया वास्तव में देर में आता है, अपने टाइमर आग जाएगा। तो आप बस समय टाइमर कॉलबैक से फिर से पैकेट भेज और इसे फिर से अनुसूची CFRunLoopTimerSetNextFireDate

साथ आपको लगता है कि आप हर बार जब आप एक पैकेट भेज बढ़ाने के लिए एक काउंटर के आसपास रख सकते कर सकते हैं। फिर आप एक निश्चित राशि के बाद छोड़ सकते हैं।

यह थोड़ा और कोड है लेकिन यह आपके यूडीपी आधारित ऐप को और अधिक विश्वसनीय बनाएगा।