2011-02-17 10 views
10

मेरा सर्वर-ऐप एक TIdTCPServer का उपयोग करता है, कई क्लाइंट ऐप्स सर्वर से कनेक्ट करने के लिए TIdTCPClients का उपयोग करते हैं (सभी कंप्यूटर एक ही लैन में हैं)।सर्वोत्तम अभ्यास: प्रत्येक स्थानांतरण के बाद टीसीपी/आईपी कनेक्शन खोलें या बंद करें?

कुछ ग्राहकों को केवल हर दो मिनट में सर्वर से संपर्क करने की आवश्यकता होती है, अन्य हर बार एक बार और एक दूसरे के बारे में 20 बार ऐसा करेंगे।

यदि मैं किसी ग्राहक और सर्वर के बीच कनेक्शन को खोलता हूं, तो मैं पुनः कनेक्ट कर दूंगा, लेकिन यह जांचना होगा कि कनेक्शन गुम हो गया है या नहीं।

यदि मैं प्रत्येक स्थानांतरण के बाद कनेक्शन बंद करता हूं, तो उसे हर बार फिर से कनेक्ट करना होगा, लेकिन यह जांचने की कोई आवश्यकता नहीं है कि कनेक्शन अभी भी है या नहीं।

ऐसा करने का सबसे अच्छा तरीका क्या है?

डेटा स्थानांतरण की आवृत्ति पर मुझे सामान्य रूप से कनेक्शन को खुला रखना चाहिए?

दोनों परिदृश्यों के लिए अन्य फायदे/नुकसान क्या हैं?

+3

एक नया टीसीपी कनेक्शन बनाने का ओवरहेड मुख्य रूप से कुछ राउंडट्रिप्स है। और वे लैन पर बहुत तेज हैं। तो मैं इसे इस्तेमाल करने के कुछ सेकंड के बाद कनेक्शन बंद कर दूंगा। – CodesInChaos

+3

लेकिन मैं इसे पहले तरीके से लिखता हूं (सबसे अधिक संभावना तत्काल बंद) और फिर जांच करें कि प्रदर्शन संतोषजनक है या नहीं। – CodesInChaos

+4

इस प्रश्न का मेरा उत्तर देखें: http://stackoverflow.com/questions/4872800/socket-open-and-close-on-1-sec-or-to-hold-open/4873002#4873002 –

उत्तर

8

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

+0

रेमी, अच्छा काम पिछले कुछ वर्षों में इंडी पर ;-) मैं इंडी के टीसीपी घटकों का व्यापक रूप से उपयोग करता हूं, और मेरा मतलब है कि मेरे वितरित अनुप्रयोग ढांचे के आंतरिक हिस्से के रूप में व्यापक रूप से मेरा मतलब है। आप इसे देखना चाह सकते हैं। – Misha

6

हालांकि कुछ मिनटों में एक बार सक्रिय होने वाले एप्लिकेशन के लिए कनेक्ट और डिस्कनेक्ट करना ठीक हो सकता है, तो एप्लिकेशन जो दूसरे बार कई बार संचार कर रहा है, कनेक्शन को खोलकर प्रदर्शन को बढ़ावा देगा।

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

मैं अधिकांश एंटरप्राइज़ अनुप्रयोगों में एक कनेक्शन खोलने की दिशा में दुबला हूं। यह आमतौर पर क्लीनर कोड का नेतृत्व करेगा, जो बनाए रखना आसान है।

प्रयोग से/twocents

8

दो सेंट ...

मेरी पहली टीसीपी/आईपी ग्राहक/सर्वर अनुप्रयोग एक नए कनेक्शन और प्रत्येक अनुरोध के लिए एक नया धागा उपयोग कर रहा था ... साल पहले ...

फिर मैंने पाया (ProcessExplorer का उपयोग करके) कि यह कुछ नेटवर्क संसाधनों को समाप्त कर दिया क्योंकि सभी बंद कनेक्शन वास्तव में नष्ट नहीं हुए हैं, लेकिन कुछ समय के लिए किसी विशेष स्थिति में रहते हैं। बहुत सारे धागे बनाए गए थे ...

मुझे बहुत से संगत अनुरोधों के साथ कुछ कनेक्शन समस्याएं भी थीं: मेरे पास मेरे सर्वर पर पर्याप्त बंदरगाह नहीं थे!

तो I rewrote it, HTTP/1.1 योजना के बाद, और KeepAlive सुविधा। यह बहुत अधिक कुशल है, धागे की एक छोटी संख्या का उपयोग करें, और ProcessExplorer मेरा नया सर्वर पसंद करता है। और मैं फिर से बंदरगाह से बाहर नहीं चला। :)

ग्राहक बंद हो गया है, तो मैं एक ThreadPool संक्षेप में उपयोग करने के लिए, कम से कम, ग्राहक प्रति एक धागा नहीं बनाते देंगे ...

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

3

मुझे लगता है कि यह सब आपके लक्ष्य और सर्वर पर किए गए अनुरोधों की मात्रा किसी भी समय उपलब्ध बैंडविड्थ और सर्वर पर हार्डवेयर का उल्लेख न करने पर निर्भर करता है।

आपको भविष्य के बारे में भी सोचने की ज़रूरत है, क्या भविष्य में आपको कनेक्शन को खोलने की आवश्यकता होगी? यदि हां, तो आपने अपने प्रश्न का उत्तर दिया है।

मैंने एक परियोजना के लिए एक चैट सिस्टम लागू किया है जिसमें ~ 50 लोग (प्रत्येक 2 महीने के साथ संख्या बढ़ रही है) हमेशा जुड़े हुए हैं और इसके अलावा चैट करने के अलावा डाटा ट्रांसफर, डेटाबेस कमांडिंग कुछ कमांड आदि का उपयोग भी शामिल है। कार्यान्वयन एप्लिकेशन को बंद होने तक सर्वर स्टार्टअप से खोलने वाले सर्वर से कनेक्शन रख रहा है, अब तक कोई समस्या नहीं है, हालांकि अगर किसी कारण से कनेक्शन खो जाता है तो यह स्वचालित रूप से पुनः स्थापित हो जाता है और सबकुछ निरंतर जारी रहता है।

कुल मिलाकर मेरा सुझाव है कि आप दोनों को कोशिश करें (कनेक्शन को खोलने के बाद इसे खोलें और इसे बंद कर दें) और देखें कि आपकी आवश्यकताओं को कौन सा फिट बैठता है।

3

जब तक कि आप कई सैकड़ों समवर्ती कनेक्शनों को स्केल नहीं कर रहे हैं, मैं निश्चित रूप से इसे खोलता रहूंगा - यह अब तक दो विकल्पों में से बेहतर है। एक बार जब आप हजारों समवर्ती कनेक्शनों में सैकड़ों को स्केल करते हैं तो आपको ड्रॉप और रीकनेक्ट करना पड़ सकता है। मैंने इस (http://www.csinnovations.com/framework_overview.htm) के आस-पास अपने पूरे ढांचे को आर्किटेक्टेड किया है क्योंकि यह मुझे जब भी आवश्यक हो, सर्वर से डेटा को "धक्का" देता है। यह सुनिश्चित करने के लिए कि कनेक्शन चालू है और काम कर रहा है (नेटवर्क ड्रॉप-आउट, टाइम पिंग्स इत्यादि), लेकिन यदि आप इसे अपने "ढांचे" में करते हैं तो आपके आवेदन कोड को इस तरह लिखा जा सकता है जिस तरह से आप मान सकते हैं कि कनेक्शन हमेशा "ऊपर" होता है।

0

समस्या प्रति आवेदन धागे की सीमा है, लगभग 1400 धागे। तो अधिकतम 1300 ग्राहक एक ही समय में जुड़े + -।

+0

हालांकि ओएस थ्रेड पूल मैं इंडी सर्वर (क्लाइंट थ्रेड के बजाए) में लागू किया जाएगा, जो आप यहां दावा करते हैं वह सही नहीं है - उदाहरण देखें https://blogs.msdn.microsoft.com/oldnewthing/20050729-14/?p=34773 – Victoria

0

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

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