2009-07-31 31 views
5

के साथ बड़े डेटा भेजना मैं एक ऐप लिखने की कोशिश कर रहा हूं जो गेम किट फ्रेमवर्क के माध्यम से ऐप चलाने वाले अन्य iPhones के साथ डेटा का आदान-प्रदान करता है। IPhones एक दूसरे को खोजते हैं और जुर्माना कनेक्ट करते हैं, लेकिन जब मैं डेटा भेजता हूं तो समस्या होती है। मुझे पता है कि iPhones ठीक से जुड़े हुए हैं क्योंकि जब मैं एक एनएसएसटींग को क्रमबद्ध करता हूं और कनेक्शन के माध्यम से भेजता हूं तो यह दूसरे छोर पर आता है। लेकिन जब मैं एक बड़ी वस्तु को संग्रहित करने का प्रयास करता हूं (NSKeyedArchiver का उपयोग करके) मुझे त्रुटि संदेश मिलता है "AGPSessionBroadcast विफल (801c0001)"।आईफोन: गेम किट

मुझे लगता है कि ऐसा इसलिए है क्योंकि मैं जो डेटा भेज रहा हूं वह बहुत बड़ा है (मेरी फाइलें लगभग 500k आकार में हैं, ऐप्पल अधिकतम 95k की अनुशंसा करता है)। मैंने डेटा को कई स्थानान्तरण में विभाजित करने का प्रयास किया है, लेकिन मैं इसे दूसरे छोर पर ठीक से अनारक्षित नहीं कर सकता। मैं सोच रहा हूं कि अगर कोई और इस समस्या के खिलाफ आया है, और आपने इसे कैसे हल किया है।

उत्तर

4

मुझे 300K के आसपास एक ही समस्या w/फ़ाइलें थीं। परेशानी यह है कि प्रेषक को पता होना चाहिए कि रिसीवर ने अगले हिस्से को भेजने से पहले पाइप खाली कर दिया है।

मैं एक साधारण राज्य इंजन के साथ समाप्त हुआ जो दोनों तरफ दौड़ गया। प्रेषक एक हेडर ट्रांसमिट करता है कि कितने कुल बाइट भेजे जाएंगे और पैकेट आकार, फिर दूसरी तरफ से पावती के लिए इंतजार कर रहा है। एक बार यह हैंडशेक प्राप्त करने के बाद यह अनुक्रम संख्या के साथ मुद्रित तय आकार पैकेट भेजने के लिए आगे बढ़ता है।

रिसीवर प्रत्येक को प्राप्त करता है, इसे पढ़ता है और इसे एक बफर में जोड़ता है, फिर पाइप पर वापस लिखता है कि इसे अनुक्रम # के साथ पैकेट मिला है। प्रेषक पैकेट # पढ़ता है, एक और बफर के लायक को स्लाइस करता है, और इसी तरह से आगे। प्रत्येक पक्ष उस स्थिति का ट्रैक रखता है जिसमें वे हैं (निष्क्रिय, शीर्षलेख भेजना, शीर्षलेख प्राप्त करना, डेटा भेजना, डेटा प्राप्त करना, त्रुटि, किया आदि) दोनों पक्षों को अंतिम खंड को पढ़ने/लिखने का ट्रैक रखना है क्योंकि यह है पूर्ण बफर आकार से छोटा होने की संभावना है।

यह ठीक काम करता है (हालांकि थोड़ा धीमा) और यह किसी भी आकार में स्केल कर सकता है। मैंने 5 के पैकेट आकार के साथ शुरू किया लेकिन यह बहुत धीमी गति से चला। इसे 10K तक पहुंचा लेकिन इससे समस्याएं उत्पन्न हुईं, इसलिए मैंने बैक ऑफ किया और इसे 80 9 6 में रखा। यह बाइनरी और टेक्स्ट डेटा दोनों के लिए ठीक काम करता है।

+0

हाय रामिन, क्या आप सुझाए गए समाधान से संबंधित कुछ कोड स्निपेट साझा कर सकते हैं। – Anshul

3

ध्यान रखें कि GameKit एक सामान्य फ़ाइल-स्थानांतरण API नहीं है; यह खिलाड़ी कहां है, वर्तमान स्थान या अन्य ऑब्जेक्ट्स आदि के अपडेट के लिए अधिक मतलब है। इसलिए गेम के लिए 300k भेजना समझदार नहीं लगता है, हालांकि मैं सामान्य साझाकरण तंत्र के लिए एपीआई को अपहृत कर सकता हूं।

समस्या यह है कि यह एक टीसीपी कनेक्शन नहीं है; यह एक यूडीपी (डेटाग्राम) कनेक्शन है। इन मामलों में, डेटा एक धारा नहीं है (जो टीसीपी द्वारा पैकेट किया जाता है) बल्कि डेटा का एक बड़ा हिस्सा है। (तकनीकी रूप से, यूडीपी को कई आईपी पैकेट में विभाजित किया जा सकता है - लेकिन उनमें से एक खोना, और संपूर्ण यूडीपी खो गया है, टीसीपी के विपरीत, जो फिर कोशिश करेगा)।

अधिकांश वायर्ड नेटवर्क के लिए एमटीयू ~ 1.5k है; ब्लूटूथ के लिए, यह लगभग ~ 0.5k है। तो आपके द्वारा भेजा गया कोई भी यूडीपी पैकेट खो सकता है (ए) खो सकता है, (बी) कई एमटीयू आकार के आईपी पैकेट में विभाजित किया जा सकता है, और (सी) यदि उनमें से एक पैकेट खो गया है, तो आप स्वचालित रूप से पूरे सेट को खो देंगे।

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

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