मैंने HTTP रखने के बारे में सुना है, लेकिन अब मैं दूरस्थ सर्वर के साथ सॉकेट कनेक्शन खोलना चाहता हूं।
अब क्या यह सॉकेट कनेक्शन हमेशा के लिए खुला रहेगा या क्या इससे संबंधित कोई समय सीमा है जो HTTP के समान है?
मैंने HTTP रखने के बारे में सुना है, लेकिन अब मैं दूरस्थ सर्वर के साथ सॉकेट कनेक्शन खोलना चाहता हूं।
अब क्या यह सॉकेट कनेक्शन हमेशा के लिए खुला रहेगा या क्या इससे संबंधित कोई समय सीमा है जो HTTP के समान है?
जवाबों:
बंद होने तक टीसीपी सॉकेट खुले रहते हैं।
यह कहा, वास्तव में डेटा भेजने के बिना टूटे हुए कनेक्शन (टूटे हुए, जैसा कि एक राउटर में मृत्यु हो गई थी, आदि, बंद होने के विपरीत) का पता लगाना बहुत मुश्किल है, इसलिए ज्यादातर आवेदन हर बार पिंग / पोंग प्रतिक्रिया के कुछ प्रकार करते हैं ताकि यह सुनिश्चित हो सके। कनेक्शन वास्तव में अभी भी जीवित है।
अब क्या यह सॉकेट कनेक्शन हमेशा के लिए खुला रहेगा या क्या इससे संबंधित कोई समय सीमा है जो HTTP के समान है?
संक्षिप्त उत्तर है नहीं यह हमेशा के लिए खुले रहते हैं नहीं होगा, यह शायद कुछ घंटों के बाद बाहर समय होगा। इसलिए हाँ वहाँ है एक टाइमआउट और यह के माध्यम से लागू की जाती है टीसीपी रखें-जिंदा ।
यदि आप अपनी मशीन पर की-अलाइव टाइमआउट कॉन्फ़िगर करना चाहते हैं, तो नीचे "बदलते टीसीपी टाइमआउट" अनुभाग देखें। अन्यथा टीसीपी कीप-अलाइव कैसे काम करता है, यह जानने के लिए शेष उत्तर के माध्यम से पढ़ें।
टीसीपी कनेक्शन में दो सॉकेट शामिल होते हैं, कनेक्शन के प्रत्येक छोर पर एक। जब एक पक्ष कनेक्शन समाप्त करना चाहता है, तो वह एक RST
पैकेट भेजता है जिसे दूसरा पक्ष स्वीकार करता है और दोनों अपनी सॉकेट बंद कर देते हैं।
हालांकि ऐसा होने तक, दोनों पक्ष अपने सॉकेट को अनिश्चित काल तक खुला रखेंगे। यह इस संभावना को खोलता है कि एक पक्ष अपने सॉकेट को बंद कर सकता है, या तो जानबूझकर या किसी त्रुटि के कारण, दूसरे छोर को बिना बताए RST
। इस परिदृश्य का पता लगाने और पास के बासी कनेक्शन के लिए टीसीपी कीप अलाइव प्रक्रिया का उपयोग किया जाता है।
तीन विन्यास गुण हैं जो यह निर्धारित करते हैं कि कैसे रखें-कार्य करते हैं। लिनक्स पर वे 1 हैं :
tcp_keepalive_time
tcp_keepalive_probes
tcp_keepalive_intvl
प्रक्रिया इस तरह काम करती है:
tcp_keepalive_time
सेकंड के लिए चुप है , तो एक एकल खाली ACK
पैकेट भेजें । 1ACK
ने स्वयं के अनुरूप जवाब दिया ?
tcp_keepalive_intvl
सेकंड रुकें , फिर दूसरा भेजेंACK
ACK
बराबर न हो जाए, तब तक दोहराएं tcp_keepalive_probes
।RST
और कनेक्शन समाप्त करें।यह प्रक्रिया अधिकांश ऑपरेटिंग सिस्टम पर डिफ़ॉल्ट रूप से सक्षम है, और इस तरह से मृत टीसीपी कनेक्शन नियमित रूप से छंटनी हो जाती है, क्योंकि दूसरा छोर 2 घंटे 11 मिनट (7200 सेकंड + 75 * 9 सेकंड) के लिए अनुत्तरदायी है।
चूंकि प्रक्रिया तब तक शुरू नहीं होती है जब तक कि कोई कनेक्शन डिफ़ॉल्ट रूप से दो घंटे के लिए निष्क्रिय नहीं हो जाता है, बासी टीसीपी कनेक्शन छंटनी होने से पहले बहुत लंबे समय तक टिका रह सकता है। यह महंगा कनेक्शन जैसे डेटाबेस कनेक्शन के लिए विशेष रूप से हानिकारक हो सकता है।
RFC 1122 4.2.3.6 के अनुसार , टीसीपी कीप-अलाइव पैकेट का जवाब देना और / देना वैकल्पिक है :
कार्यान्वयनकर्ता अपने टीसीपी कार्यान्वयन में "कीप-अलाइव" को शामिल करते हैं, हालांकि यह अभ्यास सार्वभौमिक रूप से स्वीकार नहीं किया गया है। यदि कीप-अलाइव को शामिल किया जाता है, तो आवेदन प्रत्येक टीसीपी कनेक्शन के लिए उन्हें चालू या बंद करने में सक्षम हो सकता है, और वे डिफ़ॉल्ट रूप से बंद होना चाहिए।
...
यह याद रखना बेहद जरूरी है कि जिन एसीके खंडों में कोई डेटा नहीं है, वे टीसीपी द्वारा मज़बूती से प्रसारित नहीं किए जाते हैं।
यह तर्क दिया जा रहा है कि कीप-अलाइव पैकेट में कोई डेटा नहीं है और ये अति आवश्यक नहीं हैं और अधिक उपयोग होने पर इंटरव्यू के ट्यूबों को रोकना जोखिम का कारण है।
व्यवहार में , मेरा अनुभव यह रहा है कि यह चिंता समय के साथ कम हो गई है क्योंकि बैंडविड्थ सस्ता हो गया है; और इस तरह कीप-अलाइव पैकेट आमतौर पर नहीं गिराए जाते हैं। उदाहरण के लिए अमेज़ॅन EC2 दस्तावेज़ीकरण , Keep-Alive का अप्रत्यक्ष समर्थन देता है, इसलिए यदि आप AWS के साथ होस्ट कर रहे हैं, तो संभवतः आप Keep-Alive पर निर्भर हैं, लेकिन आपका माइलेज भिन्न हो सकता है।
दुर्भाग्य से चूंकि टीसीपी कनेक्शन ओएस स्तर पर प्रबंधित किए जाते हैं, जावा प्रति-सॉकेट स्तर जैसे टाइमआउट को कॉन्फ़िगर करने का समर्थन नहीं करता है java.net.Socket
। मुझे जावा सॉकेट बनाने के लिए जावा नेटिव इंटरफ़ेस (JNI) का उपयोग करने के लिए कुछ प्रयास 3 मिले हैं जो इन विकल्पों को कॉन्फ़िगर करने के लिए मूल कोड को कॉल करते हैं, लेकिन व्यापक रूप से समुदाय को अपनाने या समर्थन करने के लिए कोई भी प्रकट नहीं होता है।
इसके बजाय, आपको अपने कॉन्फ़िगरेशन को संपूर्ण रूप से ऑपरेटिंग सिस्टम पर लागू करने के लिए मजबूर किया जा सकता है। ज्ञात हो कि यह कॉन्फ़िगरेशन पूरे सिस्टम पर चलने वाले सभी टीसीपी कनेक्शन को प्रभावित करेगा।
वर्तमान में कॉन्फ़िगर की गई टीसीपी कीप-अलाइव सेटिंग्स को पाया जा सकता है
/proc/sys/net/ipv4/tcp_keepalive_time
/proc/sys/net/ipv4/tcp_keepalive_probes
/proc/sys/net/ipv4/tcp_keepalive_intvl
आप इनमें से किसी को भी अपडेट कर सकते हैं:
# Send first Keep-Alive packet when a TCP socket has been idle for 3 minutes
$ echo 180 > /proc/sys/net/ipv4/tcp_keepalive_time
# Send three Keep-Alive probes...
$ echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes
# ... spaced 10 seconds apart.
$ echo 10 > /proc/sys/net/ipv4/tcp_keepalive_intvl
इस तरह के परिवर्तन एक पुनरारंभ के माध्यम से जारी नहीं रहेंगे। लगातार परिवर्तन करने के लिए, उपयोग करें sysctl
:
sysctl -w net.ipv4.tcp_keepalive_time=180 net.ipv4.tcp_keepalive_probes=3 net.ipv4.tcp_keepalive_intvl=10
वर्तमान में कॉन्फ़िगर की गई सेटिंग्स को इसके साथ देखा जा सकता है sysctl
:
$ sysctl net.inet.tcp | grep -E "keepidle|keepintvl|keepcnt"
net.inet.tcp.keepidle: 7200000
net.inet.tcp.keepintvl: 75000
net.inet.tcp.keepcnt: 8
ध्यान दें, मैक OS X परिभाषित करता है keepidle
और keepintvl
मिलीसेकंड की इकाइयों में लिनक्स के विपरीत है जो सेकंड का उपयोग करता है।
गुण सेट किए जा सकते हैं, sysctl
जो रिबूट में इन सेटिंग्स को बनाए रखेंगे:
sysctl -w net.inet.tcp.keepidle=180000 net.inet.tcp.keepcnt=3 net.inet.tcp.keepintvl=10000
वैकल्पिक रूप से, आप उन्हें /etc/sysctl.conf
(यदि यह मौजूद नहीं है तो फ़ाइल बनाकर) जोड़ सकते हैं ।
$ cat /etc/sysctl.conf
net.inet.tcp.keepidle=180000
net.inet.tcp.keepintvl=10000
net.inet.tcp.keepcnt=3
मेरे पास पुष्टि करने के लिए एक विंडोज़ मशीन नहीं है, लेकिन आपको रजिस्ट्री में संबंधित टीसीपी कीप-अलाइव सेटिंग ढूंढनी चाहिए
\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP\Parameters
फुटनोट
1. man tcp
अधिक जानकारी के लिए देखें ।
2. इस पैकेट को अक्सर "कीप-अलाइव" पैकेट के रूप में जाना जाता है, लेकिन टीसीपी विनिर्देश के भीतर यह सिर्फ एक नियमित ACK
पैकेट है। वाइरसार्क जैसे एप्लिकेशन इसे अनुक्रम के मेटा-विश्लेषण द्वारा सॉकेट पर पूर्ववर्ती संचार के संदर्भ में "कीप-अलाइव" पैकेट के रूप में लेबल करने में सक्षम हैं।
3. कुछ उदाहरण जो मुझे Google की मूल खोज से मिले हैं, वे हैं ल्यूविल्लियम्स / JavaLinuxNet और फ़्लोनटेल / लिबडेन्डी ।
$ no -a | grep tcp_keep
कमांड का उपयोग करके क्वेर किया जा सकता है ।
आप SO_KEEPALIVE सॉकेट विकल्प की तलाश कर रहे हैं।
जावा सॉकेट API उजागर "जीवित-रखें" के माध्यम से आवेदन करने के लिए setKeepAlive
और getKeepAlive
तरीकों।
EDIT: SO_KEEPALIVE बिना किसी "वास्तविक" डेटा के OS नेटवर्क प्रोटोकॉल स्टैक में लागू किया गया है। जीवित-जीवित अंतराल ऑपरेटिंग सिस्टम पर निर्भर है, और कर्नेल पैरामीटर के माध्यम से ट्यून करने योग्य हो सकता है।
चूंकि कोई डेटा नहीं भेजा जाता है, इसलिए SO_KEEPALIVE केवल नेटवर्क कनेक्शन के लेनन का परीक्षण कर सकता है, न कि उस सेवा की परत जो सॉकेट से जुड़ा है। उत्तरार्द्ध का परीक्षण करने के लिए, आपको कुछ ऐसा लागू करना होगा जिसमें सर्वर को संदेश भेजना और प्रतिक्रिया प्राप्त करना शामिल हो।
टीसीपी कीपेलिव और HTTP कीपैलिव बहुत अलग अवधारणाएं हैं। टीसीपी में, बासी कनेक्शन का पता लगाने के लिए भेजी जाने वाली प्रशासनिक पैकेट है। HTTP में, Keepalive का अर्थ है लगातार कनेक्शन स्थिति।
यह टीसीपी विनिर्देश से है,
जीवित-जीवित पैकेट केवल तभी भेजे जाने चाहिए जब कोई अंतराल के भीतर कनेक्शन के लिए कोई डेटा या पावती पैकेट प्राप्त नहीं हुआ हो। यह अंतराल जरूरी होना चाहिए और दो घंटे से कम नहीं होना चाहिए।
जैसा कि आप देख सकते हैं, अधिकांश अनुप्रयोगों के लिए डिफ़ॉल्ट टीसीपी रखने योग्य अंतराल बहुत लंबा है। आपको अपने एप्लिकेशन प्रोटोकॉल में मुख्य भूमिका निभानी पड़ सकती है।
HTTP/1.0
प्रत्येक अनुरोध / प्रतिक्रिया में सर्वर को फिर से जोड़ने की आवश्यकता होती है। के लिए HTTP/1.1
उन्होंने एक Keep-Alive
हेडर पेश किया, जिसका उपयोग सर्वर को ट्रिगर करने के लिए कनेक्शन को मारने के लिए नहीं किया जा सकता था क्योंकि यह अधिक फ़ाइलों का अनुरोध करने और 'पाइपलाइनिंग' की अनुमति देने के लिए प्रतिक्रिया को संसाधित करने के लिए किया गया था; कई अनुरोध भेजने के बाद सभी डेटा के वापस आने का इंतज़ार किया जाता है।
यदि आप एक संदेशवाहक NAT के पीछे हैं (जैसा कि अधिकांश घरेलू उपयोगकर्ता इन दिनों हैं), बाहरी बंदरगाहों का एक सीमित पूल है, और इन्हें टीसीपी कनेक्शनों के बीच साझा किया जाना चाहिए। इसलिए, एक निश्चित समय अवधि के लिए कोई डेटा नहीं भेजा गया है, तो एक अनुमान लगाने के लिए NATs एक कनेक्शन समाप्त कर दिया गया है।
यह और इस तरह के अन्य मुद्दे (दो एंडपॉइंट के बीच में कहीं भी) का अर्थ है कि कनेक्शन अब "काम" नहीं करेगा यदि आप एक उचित निष्क्रिय अवधि के बाद डेटा भेजने की कोशिश करते हैं। हालाँकि, जब तक आप डेटा भेजने का प्रयास नहीं करते हैं, तब तक आप इसे खोज नहीं सकते हैं ।
रखवाले का उपयोग करना दोनों कनेक्शन की संभावना को कम कर देता है कहीं लाइन के बीच बाधित हो जाता है, और आपको टूटे हुए कनेक्शन के बारे में जल्द पता लगाने देता है।
यहाँ रखने पर कुछ पूरक साहित्य दिया गया है जो इसे बहुत महीन विवरण देता है।
http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO
चूंकि जावा आपको वास्तविक रखवाली के समय को नियंत्रित करने की अनुमति नहीं देता है, इसलिए यदि आप लिनक्स कर्नेल (या आधारित ओएस खरीद रहे हैं) का उपयोग करने के लिए आप उन्हें बदलने के लिए उदाहरणों का उपयोग कर सकते हैं।
जावा सॉकेट में - टीसीपी कनेक्शन ओएस स्तर पर प्रबंधित किए जाते हैं, java.net.Socket प्रति-सॉकेट स्तर पर रखने योग्य पैकेट के लिए टाइमआउट सेट करने के लिए कोई अंतर्निहित फ़ंक्शन प्रदान नहीं करता है। लेकिन हम जावा सॉकेट के लिए रखने योग्य विकल्प को सक्षम कर सकते हैं लेकिन बासी टीसीपी कनेक्शन के बाद प्रक्रिया में डिफ़ॉल्ट रूप से 2 घंटे 11 मिनट (7200 सेकंड) लगते हैं। यह कारण कनेक्शन purge से पहले बहुत लंबे समय के लिए उपलब्ध होगा। तो हमने जावा नेटिव इंटरफ़ेस (JNI) का उपयोग करने के लिए कुछ समाधान पाया जो इन विकल्पों को कॉन्फ़िगर करने के लिए मूल कोड (c ++) को कॉल करते हैं।
**** विंडोज ओएस ****
विंडोज़ ऑपरेटिंग सिस्टम में Keepalive_time और Keepalive_intvl को कॉन्फ़िगर किया जा सकता है, लेकिन tcp_keepalive_probes को परिवर्तित नहीं किया जा सकता है। डिफ़ॉल्ट रूप से, जब टीसीपी सॉकेट को इनिशियलाइज़ किया जाता है, तो 2-घंटे के लिए समय-सजीव समय-सीमा निर्धारित करता है और 1 सेकंड के लिए ज़िंदा रहता है। कीप-लाइव टाइमआउट के डिफ़ॉल्ट सिस्टम-वाइड मान को KeepAliveTime रजिस्ट्री सेटिंग के माध्यम से चलाया जा सकता है जो मिलीसेकंड में मान लेता है।
विंडोज विस्टा और बाद में, रखने-जीवित जांच (डेटा पुनर्प्राप्ति) की संख्या 10 पर सेट है और इसे बदला नहीं जा सकता है।
विंडोज सर्वर 2003, विंडोज एक्सपी, और विंडोज 2000 पर, कीप-लिस्टेड प्रोब की संख्या के लिए डिफ़ॉल्ट सेटिंग है 5. कीप-सजीव जांच की संख्या नियंत्रणीय है। विंडोज़ के लिए Winsock IOCTLs लाइब्रेरी का उपयोग tcp-keepalive पैरामीटर को कॉन्फ़िगर करने के लिए किया जाता है।
int WSAIoctl (SocketFD, // डिस्क्रिप्टर) सॉकेट SIO_KEEPALIVE_VALS, // dwIoControlCode (LPVOID) lpvInBuffer, // पॉइंटर को tcp_keepalive स्ट्रक्चर (DWORD) cbInBuffer, // इनपुट बफर की लंबाई की पहचान करना। आउटपुट बफर (LPDWORD) lpcbBytesReturned, // बाइट्स की संख्या NULL, // OVERLAPPED संरचना NULL // पूरा होने की दिनचर्या;
लिनक्स ओएस
लिनक्स में इसे रखने के लिए अंतर्निहित समर्थन है जो इसे उपयोग करने के लिए टीसीपी / आईपी नेटवर्किंग को सक्षम करने की आवश्यकता है। प्रोग्राम को सेटस्कॉपटॉप इंटरफ़ेस का उपयोग करके अपनी सॉकेट्स के लिए नियंत्रण रखने का अनुरोध करना चाहिए।
int setsockopt (इंट सॉकेट, इंट लेवल, इंट ऑप्टेम, कॉन्स्ट वॉयड * ऑप्टवल, socklen_t ऑप्टलेन)
प्रत्येक क्लाइंट सॉकेट java.net.Socket का उपयोग करके बनाया जाएगा। प्रत्येक सॉकेट के लिए फ़ाइल डिस्क्रिप्टर आईडी जावा प्रतिबिंब का उपयोग करके पुनः प्राप्त करेगा।
Microsoft डॉक्स के अनुसार विंडोज के लिए