2012-10-06 28 views
34

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

बाइंड() के बाद, हम सुनते हैं()। बाइंड सुनने से संबंधित कैसे है()? क्या सुनो() को पता चलेगा कि बांध() को निष्पादित किया गया है? यदि हां, तो कौन से परिवर्तन बाध्य() करते हैं ताकि यह ज्ञात हो? मेरा मतलब है, सफल निष्पादन सहायता के लिए शून्य कैसे लौटा रहा है?

मैं कई परिभाषाओं से गुज़र चुका हूं, लेकिन जहां मैं इसे विस्तार से नहीं प्राप्त कर सकता हूं। तो अगर कोई मुझे यह समझा सकता है, तो मैं आभारी रहूंगा।

उत्तर

14

यह "स्थानीय" अंत का पोर्ट नंबर असाइन करता है।

सर्वर सॉकेट के लिए, यह जाने का सबसे अच्छा तरीका है - यह वही है जो आवश्यक है: उदाहरण के लिए, आपकी सॉकेट वेब सर्वर के लिए पोर्ट 80 से बंधी हो।

क्लाइंट सॉकेट के लिए, हालांकि, स्थानीय पता और बंदरगाह सामान्य रूप से महत्व का नहीं है। तो आप bind() नहीं हैं। यदि सर्वर अपने ग्राहकों को किसी निश्चित पोर्ट नंबर या किसी दिए गए श्रेणी से पोर्ट नंबर पर प्रतिबंधित करता है, तो आप क्लाइंट साइड पर bind() का भी उपयोग कर सकते हैं।

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

एक उदाहरण:

import socket 
s = socket.socket() # create your socket 
s.listen(10) # call listen without bind 
s.getsockname() Which random port number did we get? 
# here results in ('0.0.0.0', 61372) 

s2 = socket.socket() # create client socket 
s2.connect(('localhost', 61372)) # connect to the one above 
s3, x = s.accept() # Python specific use; s3 is our connected socket on the server side 
s2.getpeername() 
# gives ('127.0.0.1', 61372) 
s2.getsockname() 
# gives ('127.0.0.1', 54663) 
s3.getsockname() 
# gives ('127.0.0.1', 61372), the same as s2.getpeername(), for symmetry 
s3.getpeername() 
#gives ('127.0.0.1', 54663), the same as s2.getsockname(), for symmetry 
#test the connection 
s2.send('hello') 
print s3.recv(10) 
+1

यह उत्तर अधूरा है क्योंकि यह भी जिम्मेदार है जिसके लिए नेटवर्क इंटरफेस को आईपी पते के माध्यम से सुनना है। '0.0.0.0' – user3338098

7

यह एक पते पर एक सॉकेट "बांधता है", अन्यथा यह नहीं पता कि पता (आईपी-पता/पोर्ट जोड़ी) को यह सुनना चाहिए।

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

बाध्यकारी न केवल टीसीपी सॉकेट के लिए उपयोग किया जाता है, बल्कि यूडीपी सॉकेट के लिए भी, और अन्य प्रोटोकॉल भी।

8

bind() कनेक्शन के लिए स्थानीय बंदरगाह और इंटरफ़ेस का पता परिभाषित करता है। connect() एक अंतर्निहित bind("0.0.0.0", 0) करता है यदि कोई पहले नहीं किया गया है (शून्य को "किसी भी" के रूप में लिया जा रहा है)।

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

आने वाले कनेक्शनों के लिए, आपको एक ज्ञात बंदरगाह से बांधना होगा ताकि ग्राहकों को पता चले कि आपसे संपर्क करना है।एक बार ऐसा करने के बाद, उन्होंने सर्वर को अपना स्थानीय पता/बंदरगाह दिया है ताकि संचार दोनों दिशाओं में प्रवाह कर सके। listen() केवल bind() कॉल के बाद काम करेगा।

सभी सॉकेट को बाध्य होना चाहिए, चाहे वे यूडीपी, टीसीपी, या अन्य हों। यह हमेशा स्पष्ट रूप से नहीं किया जाता है।

+1

" 'सुनो()' केवल 'बाध्य()' कॉल के बाद काम करेगा। " नहीं, जैसा कि आप [मेरे उदाहरण] में देख सकते हैं (http://stackoverflow.com/a/12763313/296974)। – glglgl

+1

यदि यह काम करता है, तो 'बाइंड() 'अंतर्निहित है और सभी इंटरफेस के लिए अर्द्ध-यादृच्छिक पोर्ट नंबर चुनता है। यह आम तौर पर उपयोगी नहीं होता है (हालांकि दुर्लभ अपवाद हैं)। –

+0

यह सही है, यद्यपि। – glglgl

0

मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन मैं एक नया उत्तर :)

आप एक सर्वर है जो केवल आईपी प्रति इनकमिंग कनेक्शन की एक सीमित संख्या की अनुमति देता है से कनेक्ट करने के लिए चाहते हो सकता है।

यदि आपके पास कई नेटवर्क इंटरफ़ेस कार्ड हैं (और इस प्रकार से कनेक्ट करने के लिए कई संभावित आउटगोइंग ips) हैं, तो आप अपने कनेक्शन को संतुलित करने के लिए अपने प्रत्येक आईपीएस के माध्यम से साइक्लिंग मैन्युअल रूप से बाध्य() का उपयोग कर सकते हैं, और इस प्रकार कई बार अन्य कनेक्शन के रूप में अन्य कनेक्शन की अनुमति होगी।

अपने इंटरफेस और ips की एक सूची प्राप्त करने के लिए, this उत्तर देखें।

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

  • कोई संबंधित समस्या नहीं^_^