सॉकेट प्रोग्रामिंग के लिए INADDR_ANY को समझना


84

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

printf("%d",htonl(INADDR_ANY));

मुझे रिटर्न वैल्यू के रूप में 0 मिलता है। क्या कोई कुछ स्पष्टीकरण ला सकता है?


9
" ... मैं उपयोग करता हूं htonl(INADDR_ANY)। डॉक्टर का कहना है कि यह फ़ंक्शन एक यादृच्छिक आईपी उत्पन्न करता है ... " यह सही नहीं है। कौन सा डॉक्स आपको ऐसा बताता है?
'15:06

1
@alk, वास्तव में मैं गुमराह करता हूं: मैं कुछ पीडीएफ पढ़ रहा था मैंने सोचा कि कुछ आधिकारिक दस्तावेज हैं। मैं अपनी पोस्ट को अब संपादित करता हूं
epsilones

जवाबों:


132
  1. bind()की INADDR_ANYकरता है नहीं "एक यादृच्छिक आईपी उत्पन्न"। यह सॉकेट को सभी उपलब्ध इंटरफेस से बांधता है

  2. एक सर्वर के लिए, आप आम तौर पर सभी इंटरफेस से जुड़ना चाहते हैं - न कि केवल "लोकलहोस्ट"।

  3. यदि आप अपने सॉकेट को केवल लोकलहोस्ट से बांधना चाहते हैं my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1");, तो सिंटैक्स होगा , फिर कॉल करें bind(my_socket, (SOCKADDR *) &my_sockaddr, ...)

  4. जैसा कि होता है, INADDR_ANYएक स्थिरांक है जो "शून्य" के बराबर होता है:

    http://www.castaglia.org/proftpd/doc/devel-guide/src/include/inet.h.html

    # define INADDR_ANY ((unsigned long int) 0x00000000)
    ...
    # define INADDR_NONE    0xffffffff
    ...
    # define INPORT_ANY 0
    ...
    
  5. यदि आप पहले से ही इससे परिचित नहीं हैं, तो मैं आपसे आग्रह करता हूं कि बीज़ गाइड टू सॉकेट्स प्रोग्रामिंग की जाँच करें:

    http://beej.us/guide/bgnet/

चूंकि लोग अभी भी इसे पढ़ रहे हैं, एक अतिरिक्त नोट:

आदमी (7) आईपी :

जब कोई प्रक्रिया नए इनकमिंग पैकेट या कनेक्शन प्राप्त करना चाहती है, तो उसे बाइंड (2) का उपयोग करके एक स्थानीय इंटरफ़ेस पते पर एक सॉकेट बांधना चाहिए

इस मामले में, केवल एक आईपी सॉकेट किसी भी स्थानीय (पता, पोर्ट) जोड़ी के लिए बाध्य हो सकता है। जब INADDR_ANY को बाइंड कॉल में निर्दिष्ट किया जाता है, तो सॉकेट सभी स्थानीय इंटरफेस के लिए बाध्य होगा।

जब सुनो (2) को एक अनबाउंड सॉकेट पर कहा जाता है, तो सॉकेट स्वचालित रूप से एक बेतरतीब मुक्त पोर्ट से बंध जाता है, जिसमें INADDR_ANY सेट किया गया है।

जब कनेक्ट (2) को एक अनबाउंड सॉकेट पर कॉल किया जाता है, तो सॉकेट स्वचालित रूप से एक यादृच्छिक मुक्त पोर्ट या INADDR_ANY के लिए स्थानीय पते के साथ एक प्रयोग करने योग्य साझा पोर्ट से जुड़ा होता है ...

कई विशेष पते हैं: INADDR_LOOPBACK (127.0.0.1) हमेशा लूपबैक डिवाइस के माध्यम से स्थानीय होस्ट को संदर्भित करता है; INADDR_ANY (0.0.0.0) का अर्थ है बाध्यकारी के लिए कोई भी पता ...

इसके अलावा:

बाइंड () - एक नाम को एक सॉकेट से बांधें :

यदि sin_addr.s_addr) फ़ील्ड निरंतर INADDR_ANY पर सेट है, जैसा कि netinet / in.h में परिभाषित किया गया है, तो कॉल करने वाला अनुरोध कर रहा है कि सॉकेट होस्ट पर सभी नेटवर्क इंटरफेस के लिए बाध्य है। इसके बाद, सभी इंटरफेस (जो बाउंड नाम से मेल खाते हैं) से यूडीपी पैकेट और टीसीपी कनेक्शन को आवेदन में भेज दिया जाता है। यह तब महत्वपूर्ण हो जाता है जब एक सर्वर कई नेटवर्क को सेवा प्रदान करता है। पते को अनिर्दिष्ट छोड़कर, सर्वर नेटवर्क इंटरफ़ेस की परवाह किए बिना सभी UDP पैकेट और टीसीपी कनेक्शन अनुरोधों को स्वीकार कर सकता है, जिस पर अनुरोध आया था।


4
इसका मतलब यह नहीं है कि 'सभी इंटरफेस को बांधें'। यदि ऐसा किया जाता है, तो नेटस्टैट आउटपुट अलग होगा। इसका मतलब है ' किसी भी इंटरफेस पर सुनो '।
लोर्ने का मार्कीस

6
उपरोक्त लिंक को उद्धृत करने के लिए: "जब INADDR_ANY को बाइंड कॉल में निर्दिष्ट किया जाता है, तो सॉकेट सभी स्थानीय इंटरफेस के लिए बाध्य होगा।" एक अन्य लिंक से: मूल्य "INADDR_ANY" का अर्थ है कि हम वर्तमान में स्थानीय कंप्यूटर के किसी भी / सभी आईपी पते से बंध जाएंगे । लेकिन हां - कई कार्यान्वयन पहले इंटरफ़ेस से बंधेंगे, ("सभी" नहीं)। लेकिन एक एनआईसी के साथ एक पीसी के लिए, अंतर शैक्षणिक है। INADDR_ANY के साथ, क्लाइंट किसी भी / सभी IP से कनेक्ट कर सकता है (जैसे 192.168.1.2 और 127.0.0.0 दोनों)।
paulsm4

5
क्षमा करें यदि यह एक मूर्खतापूर्ण प्रश्न है, लेकिन क्या इंटरफ़ेस का अर्थ वायरलेस, ईथरनेट, आदि है?
mrQWERTY

3
@ laike9m आप 127.0.0.1 पर बाइंड करेंगे जब आप लोकल मशीन से केवल सॉकेट से कनेक्ट होना चाहते हैं। इसके लिए उपयोग के मामले हैं जब सॉकेट द्वारा दी जाने वाली सेवा केवल एक अन्य प्रक्रिया द्वारा उपयोग की जाने वाली है जो मशीन के लिए स्थानीय है।
dgnuff

2
@ paulsm4 3 में, क्या आप INADDR_LOOPBACKइसके बजाय उपयोग नहीं कर सकते inet_addr("127.0.0.1")?
जॉन स्ट्रॉड

62

INADDR_ANYका उपयोग तब किया जाता है जब आपको किसी विशिष्ट IP पर सॉकेट को बांधने की आवश्यकता नहीं होती है। जब आप कॉल करते समय पते के रूप में इस मान का उपयोग करते हैं bind(), तो सॉकेट मशीन के सभी आईपी से कनेक्शन स्वीकार करता है।


8

लोकलहोस्ट के साथ सॉकेट को बांधने के लिए, बाइंड फ़ंक्शन को शुरू करने से पहले , sockaddr_in संरचना के sin_addr.s_addr फ़ील्ड को ठीक से सेट किया जाना चाहिए। उचित मूल्य या तो द्वारा प्राप्त किया जा सकता है

my_sockaddress.sin_addr.s_addr = inet_addr("127.0.0.1")

या द्वारा

my_sockaddress.sin_addr.s_addr=htonl(INADDR_LOOPBACK);

4

INADDR_ANYसभी उपलब्ध इंटरफेस को बांधने के लिए सॉकेट सुनने का निर्देश देता है। इसे बांधने की कोशिश के समान ही है inet_addr("0.0.0.0")। पूर्णता के लिए, मैं यह भी उल्लेख करूंगा कि IPv6 के लिए IN6ADDR_ANY_INIT भी है और यह ::IPv6 सॉकेट के लिए पता करने के लिए बाध्य करने की कोशिश के समान है ।

#include <netinet/in.h>

struct in6_addr addr = IN6ADDR_ANY_INIT;

यह भी ध्यान दें कि जब आप IPv6 सॉकेट को IN6ADDR_ANY_INITअपने सॉकेट से बाँधते हैं, तो सभी IPv6 इंटरफेस को बाँध देगा, और IPv4 क्लाइंट से कनेक्शन स्वीकार करने में सक्षम होना चाहिए (हालाँकि IPv6- मैप्ड पते)।


2

INADDR_ANY एक स्थिर है, जिसमें 0 मान शामिल हैं। इसका उपयोग केवल तभी किया जाएगा जब आप उन सभी सक्रिय पोर्टों से कनेक्ट करना चाहते हैं जिन्हें आप आईपी-ऐड के बारे में परवाह नहीं करते हैं। इसलिए यदि आप कोई विशेष आईपी कनेक्ट करना चाहते हैं तो आपको my_sockaddress.sin_addr.s_addr = inet_addr ("192.168.78.2") के रूप में उल्लेख करना चाहिए

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.