2009-02-25 15 views
6

यह मेरी other question की शाखा है। अगर आपको पसंद है तो इसे पढ़ें, लेकिन यह आवश्यक नहीं है।प्रोटोकॉल बफर संदेश पूरी तरह से प्राप्त होने पर कैसे पता लगाया जाए?

असल में, मुझे एहसास हुआ कि बड़े संदेशों पर सी # के शुरुआती रिसीविव() का प्रभावी ढंग से उपयोग करने के लिए, मुझे या तो (ए) पैकेट की लंबाई पहले पढ़ने की ज़रूरत है, फिर ठीक से पढ़ें कि कई बाइट्स या (बी) अंत का उपयोग करें -पैकेट डेलीमीटर। मेरा सवाल है, इनमें से कोई भी प्रोटोकॉल बफर में मौजूद है? मैंने अभी तक उनका उपयोग नहीं किया है, लेकिन प्रलेखन पर जाकर ऐसा लगता है कि एक लम्बा हेडर या डिलीमीटर नहीं है।

यदि नहीं, तो मुझे क्या करना चाहिए? क्या मुझे बस संदेश बनाना चाहिए, फिर लम्बा हेडर/ईओपी डिलीमीटर के साथ उपसर्ग/प्रत्यय करना चाहिए?

उत्तर

14

आपको अपने प्रोटोकॉल में आकार या अंत मार्कर शामिल करने की आवश्यकता है। अलग-अलग पैकेट में मनमाने ढंग से टूटने वाले ऑक्टेट्स की अनिश्चित धारा का समर्थन करने के अलावा धारा आधारित सॉकेट (टीसीपी/आईपी) में कुछ भी नहीं बनाया गया है (और पैकेट को पारगमन में भी ठंडा किया जा सकता है)।

प्रत्येक "संदेश" के लिए एक निश्चित आकार शीर्षलेख होने के लिए एक सरल दृष्टिकोण होगा, जिसमें प्रोटोकॉल संस्करण और एक पेलोड आकार और कोई अन्य निश्चित डेटा शामिल होगा। फिर संदेश सामग्री (पेलोड)।

वैकल्पिक रूप से एक संदेश फ़ूटर (निश्चित आकार) चेकसम या यहां तक ​​कि एक क्रिप्टोग्राफिक हस्ताक्षर (आपकी विश्वसनीयता/सुरक्षा आवश्यकताओं के आधार पर) के साथ जोड़ा जा सकता है।

पेलोड आकार को जानना आपको कई बाइट्स पढ़ने के लिए अनुमति देता है जो शेष संदेश के लिए पर्याप्त होगा (और यदि एक पठन कम से कम पूरा हो जाता है, तब तक शेष बाइट्स के लिए एक और पढ़ा जाता है जब तक कि पूरा संदेश प्राप्त नहीं हो जाता)।

रखना एक अंत संदेश सूचक भी काम करता है, लेकिन आप कैसे अपने संदेश है कि एक ही ओकटेट अनुक्रम ...

1

टीसीपी/आईपी, साथ ही यूडीपी को संभालने के लिए परिभाषित करने की जरूरत, पैकेट उनके आकार के लिए कुछ संदर्भ शामिल हैं । IP header में एक 16-बिट फ़ील्ड है जो बाइट्स में आईपी हेडर और डेटा की लंबाई निर्दिष्ट करता है। TCP header में एक 4-बिट फ़ील्ड है जो 32-बिट शब्दों में TCP शीर्षलेख का आकार निर्दिष्ट करता है। UDP header में एक 16-बिट फ़ील्ड है जो बाइट्स में यूडीपी हेडर और डेटा की लंबाई निर्दिष्ट करता है।

यह बात है।

विंडोज में मानक रन-ऑफ-द-मिल सॉकेट का उपयोग करना, चाहे आप System.Net.Sockets नामस्थान में C# या Win32 में मूल Winsock सामग्री का उपयोग कर रहे हों, आप कभी भी आईपी/टीसीपी/यूडीपी शीर्षलेख नहीं देखते । ये हेडर बंद हो जाते हैं ताकि जब आप सॉकेट पढ़ते हैं तो आपको वास्तविक पेलोड, यानी, भेजा गया डेटा है।

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

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

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

+0

यदि आपका मतलब प्रोटोबफ-नेट है, तो यह सिर्फ डब्ल्यूसीएफ के लिए नहीं है; परियोजना में सॉकेट उदाहरण हैं। –

3

मैं मैट से सहमत हूं कि प्रोटोकॉल बफर के लिए एक शीर्षलेख एक पाद लेख से बेहतर है, क्योंकि प्राथमिक कारण यह है कि पीबी एक बाइनरी प्रोटोकॉल है, यह एक पाद लेख के साथ आने में समस्याग्रस्त है जो वैध संदेश अनुक्रम भी नहीं होगा। बहुत सारे पाद लेख-आधारित प्रोटोकॉल (आमतौर पर ईओएल वाले) काम करते हैं क्योंकि संदेश सामग्री परिभाषित सीमा में होती है (आमतौर पर 0x20 - 0x7F ASCII)।

एक उपयोगी तरीका यह है कि आपका निम्नतम स्तर कोड सॉकेट से बस बफर को पढ़ता है और उन्हें एक फ्रेमिंग परत तक प्रस्तुत करता है जो पूर्ण संदेशों को इकट्ठा करता है और आंशिक लोगों को याद करता है (मैं इस के लिए एक एसिंक दृष्टिकोण प्रस्तुत करता हूं (सीसीआर का उपयोग करके) here, यद्यपि एक लाइन प्रोटोकॉल के लिए)।

स्थिरता के लिए, आप हमेशा अपने संदेश को तीन क्षेत्रों के साथ पीबी संदेश के रूप में परिभाषित कर सकते हैं: लंबाई के रूप में एक निश्चित-int, प्रकार के रूप में एक enum, और एक बाइट अनुक्रम जिसमें वास्तविक डेटा होता है। यह आपके पूरे नेटवर्क प्रोटोकॉल पारदर्शी रखता है।

6

पार्टी में देर से पहुंचने के लिए माफ़ी। मैं प्रोटोबफ-नेट का लेखक हूं, सी # कार्यान्वयन में से एक। नेटवर्क उपयोग के लिए, आपको "[डी] SerializeWithLengthPrefix" विधियों पर विचार करना चाहिए - इस तरह, यह स्वचालित रूप से आपके लिए लंबाई को संभालेगा। स्रोत में उदाहरण हैं।

मैं एक पुरानी पोस्ट पर भारी जानकारी नहीं लेगा, लेकिन यदि आप और जानना चाहते हैं, तो एक टिप्पणी जोड़ें और मैं आपसे वापस आऊंगा।

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