सी

2012-03-25 5 views
7

में एंडियननेस और सॉकेट प्रोग्रामिंग मैं एक प्रोग्राम बना रहा हूं जो सी सॉकेट का उपयोग करके कुछ रोगी मॉनिटर के साथ संवाद करता है। मैं डिवाइस के साथ संवाद करने के लिए कनेक्शन-कम सॉकेट (यूडीपी) का उपयोग कर रहा हूं। लेकिन वहाँ है अपने कंप्यूटर और डिवाइस और अब तक मैं यह कर रहा था रोगी की निगरानी से पार्स प्रतिक्रिया प्राप्त करने के लिए के बीच endianness गलत मैच:सी

recvfrom(int socket, char *buffer, size_t length, int flags, 
      struct sockaddr *address, socklen_t *address_len); 

तो मैं बफर कास्टिंग था सीधे संरचना करने और ntohs और ntohl का उपयोग कर , बाइट क्रम बदलने के लिए उदाहरण के लिए: इंटरनेट पर कुछ उदाहरण को पढ़ने के बाद

struct A * a = (struct A *)buffer; 
Struct A b; 
b.v1 = ntohs(a->v1); 
b.v2 = ntohl(a->v2); 

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

मैं प्रेषक को नियंत्रित नहीं करता हूं। प्रेषक नेटवर्क बाइट ऑर्डर में है। मेरा सवाल केवल यही है: - एक संरचना में बफर डालने के लिए सुरक्षित है और फिर इस संरचना की मेजबान-बाइट ऑर्डर प्रतिकृति बनाने के लिए इस जाली संरचना पर ntohs और ntohl का उपयोग करें? क्या यह सबसे तेज़ दृष्टिकोण है? यदि नहीं, तो सबसे तेज़ दृष्टिकोण क्या हो सकता है?

+0

आप नियंत्रित करना प्रेषक भी? क्या वे नेटवर्क बाइट ऑर्डर में पैकेट भेजते हैं? – hroptatyr

+0

मुझे लगता है कि आपका समाधान पहले से ही सही है, आप यह सुनिश्चित करने के लिए '__attribute __ ((पैक))' या 'गठबंधन (x)' का उपयोग कर सकते हैं कि संकलक आपकी संरचना को पैड नहीं करता है। – hroptatyr

+0

वायर पर डेटा डालने और तार को बंद करते समय होस्ट ऑर्डर में कनवर्ट करते समय नेटवर्क बाइट ऑर्डर में कनवर्ट करें। –

उत्तर

3

सबसे पहले, a के बाद से apointer है, अपने कोड को कम से कम करना चाहिए ...

b.v1 = ntohs(a->v1); 
b.v2 = ntohl(a->v2); 

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

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

तो कुछ ऐसा है;

void unpack(struct *b, unsigned char *buffer) 
{ 
    b->v1 = (buffer[0] <<8)|(buffer[1]); 
   b->v2 = (buffer[2] <<24)|(buffer[3] <<16)|(buffer[4] <<8)|(buffer[5]); 
    etc.... 
}    

या इस तरह यदि आप आप ntohX पसंद करते हैं;

void unpack(struct *b, unsigned char *buffer) 
{ 
    b->v1 = ntohs(buffer+0); 
   b->v2 = ntohl(buffer+2); 
    etc.... 
}    

हालांकि आप, नियंत्रण की निगरानी कोड कर तो का उपयोग कर protocol buffers जैसे किसी उपकरण का सा हेरफेर कर के सभी जटिलता से छुटकारा और बाइट के आदेश के बारे में चिंता जायेगा ....

+0

हां, उत्तर के लिए धन्यवाद। उदाहरण के लिए मैंने कोड को थोड़ा गलती की थी। :) समझा सकता है कि आप किस तरह के विनिर्देशों के बारे में बात कर रहे हैं? – Shivam

+0

रोगी मॉनीटर से डेटा के लेआउट के लिए विनिर्देश .... – Soren

+0

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