2012-07-10 23 views
11

पर htonl() और ntohl() के लिए समान आउटपुट मैंने छोटे-अंत [LE] मशीन [लिनक्स, इंटेल प्रोसेसर] पर निम्न प्रोग्राम चलाया। मैं नीचे कोड स्निपेट में 3 आउटपुट की व्याख्या करने में असमर्थ हूं। चूंकि मशीन ली है, a का मान 0x78563412 के रूप में संग्रहीत किया जाता है। प्रिंट करते समय, यह अपना वास्तविक मूल्य प्रदर्शित कर रहा है। इसकी एक ली मशीन के बाद से, मैं ntohl() को नो-ऑप होने और 0x78563412 प्रदर्शित करने की अपेक्षा करता हूं, जो यह कर रहा है। हालांकि, मुझे htonl() युक्त दूसरे प्रिंट स्टेटमेंट के लिए 0x12345678 की उम्मीद है। क्या कोई मुझे समझने में मदद कर सकता है कि वे समान क्यों हैं?एक पूर्णांक

int main() 
{ 
    int a = 0x12345678; 

    printf("Original - 0x%x\n", (a)); 
    printf("Network - 0x%x\n", htonl(a)); 
    printf("Host - 0x%x\n", ntohl(a)); 

    return 0; 
} 

आउटपुट:

Original - 0x12345678 
Network - 0x78563412 
Host - 0x78563412 

उत्तर

23

आदेश दिया इसकी एक ले मशीन के बाद से गुजर रहा हो सकता है, मैं ntohl() उम्मीद नो-सेशन

गलती है कि किया जाना है। नेटवर्क बाइट ऑर्डर बिग-एंडियन है, होस्ट बाइट ऑर्डर थोड़ा-अंत है। इसलिए, ntohl और htonl दोनों उनके इनपुट का एक बाइट-स्वैप संस्करण लौटाते हैं।

याद रखें, htonl का मुद्दा यह है कि आप मेजबान पर एक पूर्णांक ले सकता है, तो लिखें:

int i = htonl(a); 

और परिणाम है कि i की स्मृति, जब नेटवर्क बाइट क्रम का उपयोग कर व्याख्या की, एक ही मूल्य है कि a करता है। इसलिए, यदि आप सॉकेट में i का ऑब्जेक्ट प्रस्तुति लिखते हैं और दूसरी तरफ पाठक नेटवर्क बाइट ऑर्डर में 4-बाइट पूर्णांक की अपेक्षा करता है, तो यह a के मान को पढ़ेगा।

और प्रदर्शन 0x78563412

यह है कि क्या आप लिखने के लिए इरादा है? यदि ntohl नो-ऑप (या बल्कि, एक पहचान फ़ंक्शन) थे, तो आपकी तीसरी पंक्ति आवश्यक रूप से आपकी पहली पंक्ति के रूप में एक ही चीज़ मुद्रित करेगी, क्योंकि आपके पास ntohl(a) == a होगा।

Original - 0x12345678 
Network - 0x12345678 
Host - 0x12345678 
+0

जैसा कि नीचे उल्लिखित @Alok के रूप में, मैं उम्मीद कर रहा था कि निम्नलिखित व्यवहार हमेशा सत्य रहेगा: 'x == htonl (ntohl (x))'। लेकिन यह नहीं हो रहा है और आपकी व्याख्या बहुत उपयोगी थी। – Bhaskar

+2

@ भास्कर: ब्रायन रोच का बिंदु भी महत्वपूर्ण है, फिर: आपने कभी भी 'एचटनएल (एनओटीएचएल (ए)) की गणना नहीं की। आपने 'htonl (ए) 'और' ntohl (ए) 'की गणना की। –

+0

बहुत बहुत धन्यवाद! ग्रेट स्पष्टीकरण – Skully

5

क्योंकि आप मूल्य से a गुजर रहे हैं और इसलिए यह उन कार्यों में से किसी से नहीं बदला है।

आप प्रिंट कर रहे हैं htonl() और ntohl() लौट रहे हैं।

जोड़ने के लिए संपादित करें: मुझे याद आया जहां आपने सोचा था कि कोई नो-ऑप होगा। यह। दोनों एक एलई मशीन पर एक ही चीज़ करने जा रहे हैं; बाइट ऑर्डरिंग को उलट दें। ntohl() उम्मीद कर रही है कि आप इसे एक नेटवर्क बाइट int

9

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

+5

एक काल्पनिक "बेवकूफ-एंडियन" सी कार्यान्वयन पर जहां बाइट न तो बड़े-एंडियन (आदेश दिया गया '4321') और न ही थोड़ा-अंत (आदेश दिया गया' 1234') है, लेकिन उदाहरण के लिए '3214' का आदेश दिया गया है, तो आपके पास अभी भी होगा 'htonl (ntohl (x))', लेकिन 'htonl' और' ntohl' वही काम नहीं करेगा, वे विपरीत दिशाओं में 8-बिट रोटेशन होंगे। मुझे उम्मीद है कि ऐसा कोई वास्तुकला मौजूद नहीं है, लेकिन यह सॉकेट एपीआई को इस तथ्य के लिए धन्यवाद दे सकता है कि 'htonl' और 'ntohl' अलग-अलग फ़ंक्शन हैं। –

+0

@SteveJessop आप बिल्कुल सही हैं। यह शायद * वास्तविक * कारण है कि हमारे पास दो अलग-अलग कार्य हैं। http://en.wikipedia.org/wiki/Endianness#Middle-endian –

+0

@SteveJessop हाँ, मैंने बस यह पता लगाया और मेरी टिप्पणी हटाने की कोशिश कर रहा था, लेकिन आप तेज़ हैं! :-)। –

0

अपने कार्यक्रम में आप लिखना जब int a;क्या आप जानते हैं कि a एक मेजबान पूर्णांक का आदेश दिया है, प्रोग्राम है जो नहीं जानता है। आप नेटवर्क ऑर्डर में पहले से ही एक मान युक्त एक int प्रदान कर सकते हैं। बेशक यदि आप किसी भी अंकगणितीय ऑपरेटर का उपयोग उस मान पर करते हैं जो होस्ट ऑर्डर में नहीं है, तो नेटवर्क ऑर्डर दृश्य से गलत होगा यदि नेटवर्क ऑर्डर होस्ट ऑर्डर के समान नहीं है।

लेकिन यह अब तक नहीं पहुंचाया गया है, नेटवर्क आदेशों को अक्सर कम स्तर की संरचनाओं में भेजा जाता है, भेजने से पहले या प्राप्त होने के बाद।

क्या अपने कार्यक्रम के साथ गलत है कि जब आप ntohl() फोन अपने ntohl() समारोह है कि int प्रदान कर रहे हैं का वादा कर रहे हैं कुछ नेटवर्क क्रम में स्मृति में संग्रहीत मूल्य है। वह अनुबंध है। यदि यह सत्य नहीं है, तो फ़ंक्शन आपके द्वारा अपेक्षित कार्य नहीं करेगा, और यही वह है जिसे आप बैठ रहे हैं।

जैसा कि अधिकांश प्रणालियों (बड़े या छोटे लेकिन बेवकूफ-एंडियन) पर समझाया गया है, दोनों कार्य आमतौर पर समान होते हैं, या तो बाइट रिवर्स या नो-ऑप।