2010-11-18 8 views
5

में एक क्रॉस प्लेटफॉर्म स्ट्रक्चर का निर्माण और उपयोग करना मैं नेटवर्किंग क्षमताओं (एसएफएमएल और RakNet का उपयोग करके) के साथ एक क्रॉस प्लेटफॉर्म गेम लिख रहा हूं और मैं उस बिंदु पर आया हूं जहां मैंने सर्वर को अपने उबंटू सर्वर पर संकलित किया है और एक क्लाइंट जा रहा है मेरे मैक पर मेरे विकास पर सभी विकास किए गए हैं, इसलिए मैंने शुरुआत में सर्वर का परीक्षण किया है, और यह ठीक काम करता है।सी ++

मैं नेटवर्क पर struct एस भेज रहा हूं और फिर उन्हें char * से (उदाहरण के लिए) inet::PlayerAdded पर वापस कास्टिंग कर रहा हूं। अब यह ठीक काम कर रहा है (अधिकांश भाग के लिए), लेकिन मेरा सवाल है: क्या यह हमेशा काम करेगा? यह एक बहुत नाजुक दृष्टिकोण की तरह लगता है। उदाहरण के लिए, क्या अन्य प्लेटफॉर्म, विंडोज़ पर भी संरचना को हमेशा रखा जाएगा? आप क्या सुझाव देंगे?

#pragma pack(push, 1) 
struct Player 
{ 
    int dir[2]; 
    int left; 
    float depth; 
    float elevation; 
    float velocity[2]; 
    char character[50]; 
    char username[50]; 
}; 

// I have been added to the game and my ID is back 
struct PlayerAdded: Packet 
{ 
    id_type id; 
    Player player; 
}; 
#pragma pack(pop) 
+2

धारावाहिक डाउनवॉटर के लिए, कोई विशेष कारण? (स्टीव का डाउनवोट विशेष रूप से गंभीर लगता है) – KevinDTimm

+0

अंक इस तरह की जगह में व्यर्थ हैं। मैं इसके बारे में चिंता नहीं करता। –

+1

मुझे अंक के बारे में परवाह नहीं है, मैं जानना चाहता हूं कि क्यों हर उत्तर (एक को छोड़कर, सबसे कम से कम उपयोगी) को डाउनवोट मिला। विशेष रूप से जब (डाउनवॉटेड) उत्तरों में से एक स्पष्ट रूप से सबसे अच्छा था। – KevinDTimm

उत्तर

5
अन्य उत्तर मैं अगर यह बचा जा सकता है कच्चे बाइनरी डेटा भेजने के खिलाफ सलाह देंगे के कई तरह

। बूस्ट सीरियल या Google प्रोटोबफ जैसे कुछ बहुत अधिक ओवरहेड के बिना ठीक काम करेंगे।

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

आपको डेटा आकारों की भी देखभाल करने की आवश्यकता है। सरल में stdint.h शामिल है और निश्चित आकार प्रकारों का उपयोग करें जैसे uint32_t। फ्लोटिंग पॉइंट मानों से सावधान रहें क्योंकि सभी आर्किटेक्चर समान मूल्य साझा नहीं करेंगे, 32-बिट फ्लोट के लिए वे संभवतः करते हैं। इसके अलावा अंतहीनता के लिए अधिकांश आर्किटेक्चर इसका उपयोग करेंगे, और यदि वे नहीं करते हैं तो आप इसे क्लाइंट पर आसानी से फ़्लिप कर सकते हैं जो अलग है।

+0

हालांकि अधिकांश उत्तर वास्तव में महान थे, मुझे लगता है कि यह वह है जिसने मुझे सबसे ज्यादा मदद की। मुझे लगता है कि मैं इसे एक शॉट दूंगा, और अगर मैंने कभी इस विधि के साथ बाधा डाली तो मुझे पता चलेगा कि क्या उपयोग करना है। – ErikPerik

9

यह अगर (अन्य बातों के अलावा) आप इसे थोड़ा-endian मशीन से बड़े endian मशीन के लिए क्या करने के रूप में सही int प्रतिनिधित्व दोनों के बीच उलट हो जाएगा प्रयास काम नहीं करेगा।

यह भी विफल हो सकता है यदि संरेखण या मशीन के लिए मशीन से अपने संरचना में परिवर्तन की पैकिंग। क्या होगा यदि आपके पास कुछ 64-बिट मशीनें हैं और कुछ 32-बिट हैं?

आप Boost.Serialization या Google Protocol Buffers की तरह एक उचित पोर्टेबल क्रमबद्धता पुस्तकालय का उपयोग करने के लिए सुनिश्चित करें कि आप एक तार प्रोटोकॉल (उर्फ संक्रामक डेटा स्वरूप) है कि हार्डवेयर की सफलतापूर्वक स्वतंत्र डीकोड किया जा सकता है की जरूरत है।

प्रोटोकॉल बफ़र के बारे में एक बार अच्छी बात यह है कि आप पारदर्शी रूप से एक zlib संगत धारा भी Protobuf धाराओं के साथ संगत है कि का उपयोग कर डेटा सेक कर सकते हैं। मैंने वास्तव में यह किया है, यह अच्छी तरह से काम करता है। मुझे लगता है कि अन्य सजावटी धाराओं को आपके मूल तार प्रोटोकॉल को आवश्यकतानुसार बढ़ाने या अनुकूलित करने के समान तरीके से उपयोग किया जा सकता है।

2

का जवाब "... यहां तक ​​कि अन्य प्लेटफार्मों पर एक ही बाहर रखी ..." आम तौर पर नहीं है। यह तब भी है जब विभिन्न CPUs और/या विभिन्न endianness के रूप में ऐसे मुद्दों को संबोधित किया जाता है।

विभिन्न ऑपरेटिंग सिस्टम (यहां तक ​​कि एक ही हार्डवेयर प्लेटफॉर्म पर) विभिन्न डेटा प्रस्तुतियों का उपयोग कर सकते हैं; इसे आम तौर पर "मंच एबीआई" कहा जाता है और यह उदाहरण के बीच अलग है। 32 बिट/64 बिट विंडोज, 32 बिट/64 बिट लिनक्स, मैकोज़क्स।

'#pragma पैक' केवल आधा रास्ता क्योंकि संरेखण प्रतिबंध परे वहाँ डेटा प्रकार आकार अंतर हो सकता है। उदाहरण के लिए, 64 बिट विंडोज़ पर "लंबा" 32 बिट है जबकि यह लिनक्स और मैकॉक्स पर 64 बिट है।

यह कहा गया कि समस्या स्पष्ट रूप से नई नहीं है और पहले से ही संबोधित किया गया है - रिमोट प्रोसेस कॉल मानक (आरपीसी) में प्लेटफ़ॉर्म-स्वतंत्र तरीके से डेटा संरचनाओं को परिभाषित करने और कैसे एन्कोड/इन structs का प्रतिनिधित्व "बफर" decode। इसे "एक्सडीआर" (शासक डेटा प्रतिनिधित्व) कहा जाता है। आरएफसी 1832 देखें। प्रोग्रामिंग के रूप में, इस पहिया को कई बार पुनर्निर्मित किया गया है; चाहे आप एक्सएमएल में कनवर्ट करें, एक्सडीआर के साथ निम्न स्तर का काम करें, google :: protobuf, boost या Qt :: Variant का उपयोग करें, वहां से चुनने के लिए बहुत कुछ है।

एक विशुद्ध रूप से कार्यान्वयन तरफ: simpliclty के लिए, बस लगता है कि "अहस्ताक्षरित int" हर जगह एक 32bit सीमा पर गठबंधन 32 बिट है, यदि आप अपने सभी डेटा को 32 बिट मानों के सरणी के रूप में एन्कोड कर सकते हैं तो एकमात्र बाहरीकरण समस्या जिसे आप सौदा करना चाहते हैं वह अंतहीनता है।