मुझे पता है कि इस पर कुछ एसई प्रश्न हैं, और मुझे विश्वास है कि मैंने उनमें से कई को पढ़ा क्योंकि यह इस बिंदु पर आने से पहले मायने रखता है।
"सर्वर-साइड TIME_WAIT
" से मेरा मतलब है कि सर्वर-साइड सॉकेट जोड़ी की स्थिति जो सर्वर साइड पर शुरू हुई थी।
मैं अक्सर इन बयानों को देखता हूं जो मुझे विरोधाभासी लगते हैं:
- सर्वर-साइड
TIME_WAIT
हानिरहित है - आपको अपने नेटवर्क ऐप्स को डिज़ाइन करना चाहिए जिससे क्लाइंट्स को पास होना चाहिए (), इसलिए क्लाइंट को सहन करना होगा
TIME_WAIT
मेरे विरोधाभासी होने का कारण यह है कि क्योंकि TIME_WAIT
ग्राहक को कोई समस्या हो सकती है - क्लाइंट उपलब्ध पोर्ट को चला सकता है, इसलिए संक्षेप में ऊपर TIME_WAIT
क्लाइंट पक्ष के बोझ को स्थानांतरित करने की सिफारिश कर रहा है जहां यह समस्या हो सकती है, से सर्वर साइड जहां यह कोई समस्या नहीं है।
क्लाइंट-साइड TIME_WAIT
बेशक सीमित संख्या में उपयोग के मामलों के लिए एक समस्या है। अधिकांश क्लाइंट-सर्वर समाधानों में एक सर्वर और कई क्लाइंट शामिल होंगे, क्लाइंट आमतौर पर इसके लिए पर्याप्त मात्रा में कनेक्शन के साथ सौदा नहीं करते हैं क्योंकि यह एक समस्या है, और यहां तक कि अगर वे करते हैं, तो "sanely" के लिए कई सिफारिशें हैं ( के रूप में SO_LINGER
0 मध्यांतर के साथ विरोध किया , या tcp_tw के साथ मध्यस्थता) sysctls) TIME_WAIT
बहुत अधिक कनेक्शन बनाने से बचने के द्वारा क्लाइंट-साइड का मुकाबला करें । लेकिन यह हमेशा संभव नहीं है, उदाहरण के लिए जैसे अनुप्रयोगों के वर्ग के लिए:
- निगरानी प्रणाली
- लोड जनरेटर
- प्रॉक्सी
दूसरी तरफ, मुझे यह भी समझ में नहीं आ रहा है कि सर्वर-साइड कैसे TIME_WAIT
सहायक है। इसका कारण TIME_WAIT
यहां तक है, यह इसलिए है क्योंकि यह बासी TCP
अंशों को उन धाराओं में इंजेक्ट करने से रोकता है जो वे अब नहीं हैं। क्लाइंट-साइड के लिए TIME_WAIT
यह केवल उन ip:port
जोड़ियों के साथ संबंध बनाने के लिए असंभव है, जो इस बासी कनेक्शन के साथ हो सकते थे (उपयोग किए गए जोड़े बाहर से बंद हैं TIME_WAIT
)। लेकिन सर्वर साइड के लिए, इसे रोका नहीं जा सकता है क्योंकि स्थानीय पते में स्वीकार पोर्ट होगा, और हमेशा एक ही होगा, और सर्वर नहीं कर सकता है (AFAIK, मेरे पास केवल अनुभवजन्य प्रमाण है) केवल इसलिए कनेक्शन से इनकार करें एक आने वाली सहकर्मी वही पता जोड़ी बनाएगी जो सॉकेट टेबल में पहले से मौजूद है।
मैंने एक प्रोग्राम लिखा था जो दिखाता है कि सर्वर-साइड TIME-WAIT को अनदेखा किया गया है। इसके अलावा, क्योंकि परीक्षण 127.0.0.1 पर किया गया था, कर्नेल के पास एक विशेष बिट होना चाहिए जो यह भी बताता है कि क्या यह सर्वर साइड है या क्लाइंट साइड (क्योंकि अन्यथा ट्यूपल समान होगा)।
स्रोत: http://pastebin.com/5PWjkjEf , फेडोरा 22 पर परीक्षण किया गया, डिफ़ॉल्ट नेट कॉन्फिग।
$ gcc -o rtest rtest.c -lpthread
$ ./rtest 44400 s # will do server-side close
Will initiate server close
... iterates ~20 times successfully
^C
$ ss -a|grep 44400
tcp TIME-WAIT 0 0 127.0.0.1:44400 127.0.0.1:44401
$ ./rtest 44500 c # will do client-side close
Will initiate client close
... runs once and then
connecting...
connect: Cannot assign requested address
इसलिए, सर्वर-साइड के लिए TIME_WAIT
, ठीक उसी पोर्ट जोड़ी पर कनेक्शन तुरंत और सफलतापूर्वक पुन: स्थापित किए जा सकते हैं, और क्लाइंट-साइड के लिए TIME-WAIT
, दूसरी पुनरावृत्ति पर connect()
सही असफल रहे
संक्षेप में, प्रश्न दो गुना है:
- क्या सर्वर-साइड
TIME_WAIT
वास्तव में कुछ भी नहीं करता है, और सिर्फ इसलिएRFC
इसे छोड़ दिया जाता है क्योंकि इसके लिए आवश्यकता होती है? - क्या कारण यह है कि ग्राहक द्वारा सर्वर
TIME_WAIT
को बंद करने की सिफारिश की गई है क्योंकि सर्वर बेकार है?
TIME_WAIT
।