2009-10-24 23 views
5

के माध्यम से संचरण के लिए सी/सी ++ संरचना को एन्कोड करने के लिए डेल्टा कैसे करें, मुझे काफी उच्च अद्यतन दर पर तार पर एक सी संरचना (यूडीपी सॉकेट और संभवतः एक्सडीआर का उपयोग करके) भेजने की आवश्यकता है, जो संभावित रूप से बहुत सारे कारणों से होता है कई khz पर अनावश्यक और अनावश्यक यातायात।सॉकेट

ऐसा इसलिए है क्योंकि, संरचना में कुछ डेटा कभी-कभी नहीं बदला हो सकता है, इसलिए मैंने सोचा कि पिछले सी संरचना के खिलाफ मौजूदा सी संरचना डेल्टा-एन्कोडिंग एक अच्छा विचार प्रतीत होता है, जो कि " diff "।

लेकिन मुझे आश्चर्य है कि ऐसा कुछ करने का सबसे अच्छा तरीका क्या है, आदर्श रूप से पोर्टेबल तरीके से यह सुनिश्चित करता है कि डेटा अखंडता बनाए रखा जाए? क्या डेटा को एक्सओआर करना और इस तरह आगे बढ़ना संभव होगा?

इसी तरह, यह महत्वपूर्ण होगा कि दृष्टिकोण पर्याप्त रूप से पर्याप्त हो, ताकि नए फ़ील्ड को स्ट्रक्चर में जोड़ा जा सके या यदि आवश्यक हो तो रीडर्ड किया जा सके (पैडिंग), जो ऐसा लगता है जैसे इसे संस्करण की जानकारी की आवश्यकता होगी।

कोई विचार या पॉइंटर्स (क्या मौजूदा पुस्तकालय हैं?) की अत्यधिक सराहना की जाएगी!

धन्यवाद

संपादित करें: हर कोई एक जिन्होंने उत्तर प्रदान के लिए धन्यवाद, विस्तार के स्तर वास्तव में सराहना की है, मुझे लगता है कि मैं शायद हालांकि यूडीपी उल्लेख किया है नहीं करना चाहिए, क्योंकि वह मुख्य समस्या यह है की नहीं है, क्योंकि यूडीपी के शीर्ष पर पहले से ही एक समान प्रोटोकॉल लागू किया गया है जो उल्लिखित कठिनाइयों के लिए जिम्मेदार है, इसलिए प्रश्न वास्तव में एक संरचना के डेल्टा एन्कोडिंग के व्यवहार्य साधनों के लिए विशिष्ट होना था, और विशेष रूप से परिवहन तंत्र के रूप में यूडीपी का उपयोग करने के बारे में इतना कुछ नहीं था ।

+0

मैं इसे निर्भर करता है कितना लगता है के साथ कोरबा या प्रोटोकॉल बफ़र्स की तरह एक RPC

उपयोग DTLS का प्रयोग करें डेटा बदलने जा रहा है (1%? 10%? 50%?) और परिवर्तन कितने नियमित हैं (क्या वे एक ही स्थान या हर जगह हैं?) –

+0

बस उत्सुक: क्यों एक सी संरचना को XMLRPC, SOAP जैसे कुछ का उपयोग करने का विरोध किया गया या अन्य कॉम डीबीयूएस जैसे यूनिकेशन तंत्र? संरचना के साथ दूसरी तरफ आने पर क्या होता है? – aneccodeal

उत्तर

4

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

क्या आपके ट्रांसमिशन को एक तरफा, प्रेषक को प्रेषक होने की आवश्यकता है? यदि ऐसा है (यानी, रिसीवर के लिए स्वीकृति या रीट्रांसमिट भेजने के लिए स्वीकार्य नहीं है) तो वास्तव में आप इन पंक्तियों के साथ बहुत कुछ नहीं कर सकते हैं। एक चीज जो दिमाग में आती है: अगर रिसीवर थोड़ी देर के लिए सिंक से बाहर निकलना ठीक है, तो प्रेषक दो प्रकार के पैकेट भेज सकता है - एक संरचना के वर्तमान मूल्य की एक पूरी तस्वीर के साथ, और एक पहचान अद्वितीय टैग, कम से कम प्रत्येक (कहें) 5 मिनट भेजा जा सकता है (इसलिए वास्तव में रिसीवर 15 मिनट तक सिंक से बाहर हो सकता है अगर यह इन "बड़े पैकेट" में से दो याद करता है); आखिरी "बड़े पैकेट" से केवल एक अपडेट (diff) के साथ, जिसमें बड़े पैकेट की पहचान अद्वितीय टैग और (उदा।) एक्सओआर का एक रन-लम्बाई-एन्कोडेड संस्करण शामिल है, जिसमें आप उल्लेख करते हैं।

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

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

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

कुछ विनिर्देशों के बिना, कम से कम बॉलपार्क संख्याओं के लिए कम से कम ballpark संख्याओं के बिना अधिक सहायता प्रदान करना मुश्किल है - पैकेट आकार, भेजने की आवृत्तियों, प्रेषक के साथ समन्वयित होने में कितना समय लगता है रिसीवर, नेटवर्क पैरामीटर का एक बंडल इत्यादि। लेकिन मुझे आशा है कि यह कुछ सामान्य विश्लेषण और सुझाव अभी भी मदद करेगा।

3
डेल्टा एन्कोड करने के लिए

:

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

2) पिछले पैकेट से डेल्टा की गणना करें और इसे कॉम्पैक्ट रूप में एन्कोड करें। आपके द्वारा भेजे जा रहे डेटा के प्रकार की जांच करके और जिस तरह से यह आम तौर पर बदलता है, आप एक सुंदर कॉम्पैक्ट डेल्टा तैयार करने में सक्षम होना चाहिए। हालांकि, आपको डेल्टा के आकार की जांच करने की आवश्यकता हो सकती है - कुछ मामलों में यह एक कुशल एन्कोडिंग नहीं हो सकता है - यदि यह एक महत्वपूर्ण फ्रेम से बड़ा है तो आप इसके बजाय एक और कुंजी फ्रेम भेज सकते हैं। आप इस बिंदु पर भी निर्णय ले सकते हैं कि क्या आपके डेल्टा हानिकारक या हानिकारक हैं।

3) पैकेट में सीआरसी चेक जोड़ें (सीआरसी 32 के लिए खोजें)। यह रिसीवर को यह सत्यापित करने की अनुमति देगा कि पैकेट को बरकरार रखा गया है, जिससे उन्हें अमान्य पैकेट छोड़ने की अनुमति मिलती है।

नोट:

  • UDP पर ऐसा करने के बारे में सावधान रहें - यह कोई गारंटी नहीं है कि आपके पैकेट उसी क्रम आप उन्हें भेजा में आ जाएगा देता है। स्पष्ट रूप से एक डेल्टा केवल तभी काम करेगा जब पैकेट क्रम में हों। इस मामले में, आपको प्रत्येक पैकेट में अनुक्रम आईडी का कुछ रूप जोड़ना होगा (पहला पैकेट "1" है, दूसरा पैकेट "2" आदि है) ताकि आप आउट ऑफ़ ऑर्डर प्राप्त कर सकें। आपको रिसीवर में "एन" पैकेट्स का बफर रखने की भी आवश्यकता हो सकती है ताकि जब आप उन्हें डीकोड करने के लिए आते हैं तो आप उन्हें सही क्रम में फिर से इकट्ठा कर सकते हैं (लेकिन बेशक, यह कुछ विलंबता पेश कर सकता है)। आप शायद यूडीपी पर कुछ पैकेट भी याद करेंगे, इस मामले में आपको अगली कीफ्रेम तक इंतजार करना होगा, इससे पहले कि आप "सिग्नल पुनः प्राप्त करें" करने में सक्षम होंगे - इसलिए महत्वपूर्ण फ्रेम अक्सर विनाशकारी आबादी से बचने के लिए पर्याप्त होना चाहिए अपने comms में।

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

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

+0

क्या आपका पहला नोट "संक्षिप्त टीसीपी" के रूप में अधिक संक्षेप में लिखा नहीं जाएगा? –

+0

बस जोड़ने के लिए, इस स्तर के विस्तार में जाने के लिए धन्यवाद, यह वास्तव में सराहना की है। – guest

+0

@guest - कोई चिंता नहीं। उम्मीद है कि यह प्रबुद्ध/रोचक था भले ही वह उस समाधान को प्रदान न करे जिसे आप ढूंढ रहे थे। –

1

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

0

एक संपीड़न विकल्प

उपयोग एक पैक प्रारूप

Repurposes एक मौजूदा शीर्ष लेख संकुचन लाइब्रेरी