सर्वर को कैसे पता चलता है कि क्लाइंट पोर्ट किसको भेजना है?


26

जैसा कि मैंने समझा कि ऐसा तब होता है जब कोई ग्राहक कनेक्शन के लिए अनुरोध करता है:

  1. सर्वर एक विशेष पोर्ट नंबर के लिए बाध्य होगा। पोर्ट नंबर हमेशा एक सुनने की प्रक्रिया से जुड़ा होता है। चूंकि केवल सर्वर आने वाले कनेक्शनों के लिए सुन रहा है, हमें क्लाइंट की तरफ से बांधने की जरूरत नहीं है
  2. सर्वर उस पोर्ट नंबर पर सुरीनीग पर रखेगा।
  3. ग्राहक एक connect()अनुरोध भेजेगा ।
  4. सर्वर अनुरोध का उपयोग करके स्वीकार करेगा accept()। जैसे ही सर्वर क्लाइंट अनुरोध को स्वीकार करता है, कर्नेल आगे के लिए सर्वर के लिए एक यादृच्छिक पोर्ट नंबर आवंटित करता है send()और receive(), चूंकि सर्वर पर समान पोर्ट नंबर का उपयोग सुनने के साथ-साथ भेजने के लिए नहीं किया जा सकता है, और पिछला पोर्ट अभी भी है नए कनेक्शन के लिए सुन रहा है

यह सब देखते हुए, सर्वर को कैसे पता चलता है कि क्लाइंट किस पोर्ट पर प्राप्त कर रहा है? मुझे पता है कि क्लाइंट एक सोर्स पोर्ट और डेस्टिनेशन पोर्ट के साथ TCP सेगमेंट भेजेगा, इसलिए सर्वर उस सेगमेंट के सोर्स पोर्ट को अपने डेस्टिनेशन पोर्ट के रूप में इस्तेमाल करेगा, लेकिन उस पोर्ट के बारे में पता लगाने के लिए सर्वर किस फंक्शन को कॉल करता है? क्या यह है accept()?


जवाबों:


33

यह पैकेट में टीसीपी (या यूडीपी, आदि) हेडर का हिस्सा है। इसलिए सर्वर को पता चल जाता है क्योंकि क्लाइंट इसे बताता है। यह क्लाइंट के आईपी पते (जो आईपी हेडर का हिस्सा है) का पता लगाने के समान है।

उदाहरण के लिए, हर टीसीपी पैकेट में एक आईपी हेडर (स्रोत आईपी, गंतव्य आईपी और प्रोटोकॉल [टीसीपी], कम से कम) होता है। फिर एक टीसीपी हेडर है (स्रोत और गंतव्य पोर्ट के साथ, अधिक)।

जब कर्नेल को एक SYN पैकेट (एक टीसीपी कनेक्शन की शुरुआत) 10.11.12.13 के रिमोट आईपी (आईपी हेडर में) और 12345 का एक रिमोट पोर्ट (टीसीपी हेडर में) प्राप्त होता है, तो यह रिमोट आईपी और पोर्ट को जानता है। । यह एक SYN | ACK को वापस भेजता है। यदि उसे ACK वापस मिलता है, तो listenकॉल एक नया सॉकेट लौटाता है, जो उस कनेक्शन के लिए सेट किया गया है।

एक टीसीपी सॉकेट चार मूल्यों (दूरस्थ आईपी, स्थानीय आईपी, दूरस्थ बंदरगाह, स्थानीय बंदरगाह) द्वारा विशिष्ट रूप से पहचाना जाता है। आपके पास कई कनेक्शन / सॉकेट हो सकते हैं, जब तक कि उनमें से कम से कम एक अलग हो।

आमतौर पर, स्थानीय पोर्ट और लोकल आईपी एक सर्वर प्रक्रिया के सभी कनेक्शनों के लिए समान होंगे (उदाहरण के लिए sshd के सभी कनेक्शन स्थानीय-आईपी: 22 पर होंगे)। यदि एक रिमोट मशीन कई कनेक्शन बनाती है, तो प्रत्येक एक अलग रिमोट पोर्ट का उपयोग करेगा। इसलिए सब कुछ लेकिन रिमोट पोर्ट एक ही होगा, लेकिन यह ठीक है - चार में से केवल एक को अलग करना है।

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

Wireshark एक TCP SYN पैकेट दिखा रहा है


> स्पष्टीकरण के लिए धन्यवाद। यू कहने का मतलब था कि नए सर्वर सॉकेट डिस्क्रिप्टर (अर्थात टुल्ल) को स्वीकार करने के बाद प्राप्त किया जाएगा () क्लाइंट पोर्ट और क्लाइंट एड्रेस डिटेल्स होगा और उस नए सॉकेट डिस्क्रिप्टर सर्वर को डेटा भेजना और प्राप्त करना होगा। और client.New सॉकेट फ़ाइल डिस्क्रिप्टर से कर्नेल, सर्वर आईपी, क्लाइंट आईपी और क्लाइंट पोर्ट द्वारा निर्दिष्ट एक नया सर्वर पोर्ट नंबर होगा। क्या मैं सही हूं?
सुबी सुरेश

@SubiSuresh हाँ, टपल को कर्नेल के अंदर संग्रहीत किया जाता है, उस फ़ाइल डिस्क्रिप्टर से संबद्ध।
derobert

> धन्यवाद derobert.So मैं यह निष्कर्ष निकाल रहा हूं कि नए सर्वर सॉकेट डिस्क्रिप्टर में क्लाइंट पोर्ट और क्लाइंट एड्रेस होगा, जिसे सर्वर स्वीकार () से प्राप्त करता है। मेरी समझ ठीक है?
सूबी सुरेश '

@SubiSuresh हाँ, यह सही है। एप्लिकेशन के दृष्टिकोण से, आप आमतौर पर परवाह नहीं करते (लॉगिंग को छोड़कर)। कर्नेल यह सुनिश्चित करता है कि आपके write(आदि) डेटा सही जगह पर जाए।
derobert

> आपकी मदद के लिए धन्यवाद और मुझे लगता है कि मुझे बात मिल गई। ;-)
सुबी सुरेश

2

"कनेक्ट रिक्वेस्ट (क्लाइंट प्रोग्राम का connect()सिस्टम कॉल, आमतौर पर) तीन-तरफ़ा हैंडशेक का कारण बनता है । 3-तरह के हैंडशेक (क्लाइंट से सर्वर तक) के पहले पैकेट में SYN फ्लैग सेट होता है, और इसमें TCP पोर्ट नंबर क्लाइंट क्लाइंट प्रोग्राम शामिल होता है। कर्नेल इसे असाइन करता है।

आप इसे नैम्प बनाम प्राकृतिक SYN पैकेट पर एक लेख में देख सकते हैं । नैंप SYN पैकेट डिकोडिंग में "source.60058> dest.22" वाक्यांश है। "वैध SYN पैकेट" डिकोडिंग में वाक्यांश "source.35970> dest.80" है। दो SYN पैकेट रिमोट कर्नेल को बताते हैं कि पैकेट क्रमशः TCP पोर्ट 60058 और पोर्ट 35970 से हैं।


> लेकिन ब्रूस जो पीछे के अंत में हो रहा है। लेकिन कैसे मेरा सर्वर वास्तव में क्लाइंट सर्वर प्रोग्राम्स में पोर्ट नंबर becuase की तरह विवरण प्राप्त कर रहा है, मैंने कभी क्लाइंट पोर्ट और क्लाइंट एड्रेस प्राप्त करने के लिए कोई फ़ंक्शन नहीं देखा है
Subi Suresh

सिस्टम कॉल getpeername()आपको किसी भी खुले सॉकेट पर ऐसा करने देना चाहिए। accept()सिस्टम कॉल सर्वर कोड ग्राहक को वापस संवाद करने के लिए एक सॉकेट फ़ाइल वर्णनकर्ता प्राप्त करने के लिए उपयोग करने के लिए है कि एक पैरामीटर ( "sockaddr" मेरे आदमी पन्नों में) है कि संभावित ग्राहक के IP पते और टीसीपी पोर्ट नंबर शामिल है।
ब्रूस एडिगर

> कृपया मुझे कोई आपत्ति नहीं है। यदि मुझे मिले सभी इनपुट से मैं समझ गया कि स्वीकार () क्लाइंट विवरण से भरा संरचना sockaddr_in है और नए सर्वर सॉकेट डिस्क्रिप्टर को स्वीकार करने के बाद वापस आ गया है () ग्राहक पोर्ट और पते पर स्वचालित रूप से होगा। Thats क्यों हम भेज (नए सर्वर सॉकेट डिस्क्रिप्टर) का उपयोग करके भेजने में सक्षम हैं। मुझे आशा है, इस बिंदु तक हूं? यह सिर्फ यह सुनिश्चित करने के लिए है कि जो मैंने समझा है वह सही है। सही है?
सुबी सुरेश

@SubiSuresh - मेरा मानना ​​है कि आपने सच लिखा है।
ब्रूस एडिगर

1

टीसीपी सॉकेट एक स्ट्रीम-ओरिएंटेड सॉकेट है। दो सॉकेट डिस्क्रिप्टर (आपके और आपके सहकर्मी के स्वामित्व वाले) विश्वसनीय रूप से जुड़े हुए हैं। इसलिए आपको क्लाइंट के पोर्ट के बारे में चिंता करने की ज़रूरत नहीं है - बस अपना सॉकेट डिस्क्रिप्टर लिखें!

इसके अलावा, getsockname (2) के लिए स्वतंत्र महसूस करें यदि आप वास्तव में यह जानना चाहते हैं (शायद लॉगिंग के लिए)।


0

कनेक्शन एक टपल (स्रोत आईपी, स्रोत बंदरगाह, गंतव्य आईपी, गंतव्य बंदरगाह) द्वारा परिभाषित किया गया है। उत्तर उलटे चलते हैं।


@vondrand उस बिंदु को मैं वॉन समझ गया था। लेकिन किस फ़ंक्शन से सर्वर को क्लाइंट पोर्ट नंबर के बारे में पता चलता है? क्लाइंट पोर्ट नंबर जानने के साथ कि यह कैसे भेजेगा। क्या सर्वर क्लाइंट को लाने के लिए स्वीकार () में संरचना का उपयोग करता है? बंदरगाह ?
सुबी सुरेश '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.