2010-03-14 15 views
10

मैं एक बंद सॉकेट के लिए परीक्षण करने की कोशिश कर रहा हूं जिसे SIGPIPE प्रेरित करने के लिए डबल प्रेषण की विलंबता हिट किए बिना सहकर्मी द्वारा बंद कर दिया गया है।एक बंद सॉकेट के लिए परीक्षण

यहां धारणाओं में से एक यह है कि बंद होने पर सॉकेट को अंतिम लिखने/भेजने के तुरंत बाद सहकर्मी द्वारा बंद कर दिया गया था। समय-समय पर बंद होने जैसी वास्तविक त्रुटियों को कोड में कहीं और निपटाया जाता है।

यदि सॉकेट अभी भी खुला है, तो 0 या अधिक बाइट डेटा होंगे जो मैं वास्तव में सॉकेट बफर से बाहर नहीं हटाना चाहता हूं।

मैं सोच रहा था कि सॉकेट अभी भी कनेक्ट है या नहीं, यह निर्धारित करने के लिए मैं int ret = recv(sockfd, buf, 1, MSG_DONTWAIT | MSG_PEEK); पर कॉल कर सकता हूं। यदि यह कनेक्ट है लेकिन बफर में कोई डेटा नहीं है तो मुझे -1errno == EAGAIN के साथ वापसी होगी और पुन: उपयोग के लिए सॉकफ़ेड वापस कर देगा। अगर इसे सहकर्मी द्वारा बंद कर दिया गया है तो मुझे ret == 0 मिलेगा और एक नया कनेक्शन खोल देगा।

मैंने इसका परीक्षण किया है और यह काम करने के लिए लगता है। हालांकि, मुझे संदेह है कि जब मैं अपने डेटा के आखिरी बिट को पुन: प्राप्त करता हूं और जब सहकर्मी FIN आता है तो मुझे एक छोटी सी खिड़की होती है जिसमें मुझे अपने परीक्षण recv से झूठी-सकारात्मक EAGAIN मिल सकता है।

क्या यह मुझे काटने जा रहा है, या ऐसा करने का एक बेहतर तरीका है?

+0

एक वैकल्पिक तरीका चुनिंदा() (या पोल()) है, क्योंकि यह एक एफडी दोनों आरएफओ को पढ़ने और लिखने के लिए नियंत्रित कर सकता है, लेकिन मुझे नहीं पता कि यह वास्तव में एफआईएन समय के बारे में आपकी समस्या का समाधान करता है या नहीं। –

+0

@Giuseppe: नहीं, मुझे नहीं लगता कि चयन समय की समस्या को हल करेगा। –

उत्तर

3

ठीक है, तो मैं कुछ और परीक्षण भाग गया और यह मैं क्या पाया है।

मैं अपने ग्राहक की स्थापना के कारण सर्वर पास कॉल करने के लिए यह डेटा के अंतिम लिखने के बाद सर्वर से HTTP/1.1 Connection: close संदेश भेजने के लिए। जब मेरे ग्राहक ने जीईटी लेनदेन से डेटा पढ़ना समाप्त कर दिया तो यह सॉकेट का परीक्षण करेगा कि यह उपर्युक्त विधि का उपयोग करके अभी भी खुला है या फिर एक और जीईटी जारी करने का प्रयास करें।

मुझे जो मिला वह यह है कि सर्वर का FIN सर्वर के FIN से पहले मेरा परीक्षण होने पर लगभग 30% झूठी-सकारात्मक और विफल संचालन के लिए अग्रणी होगा।

शायद यह उचित रूप से विश्वसनीय बनाने का एकमात्र तरीका है, 99% के करीब कहना है कि पिछले पढ़ने और प्रयास सॉकेट पुन: उपयोग के बीच कनेक्शन विलंबता से संबंधित कृत्रिम देरी पेश करना होगा - हालांकि, यह बहुत अधिक हत्या प्रदर्शन करेगा।

तो, मुझे यह निष्कर्ष निकालना है कि यह उपकरण उपयोगी है, यह केवल मामूली है।

+1

+1: दिलचस्प परीक्षण। कोई समझ सकता है कि दूरसंचार में 90% कोड असाधारण व्यवहार के प्रबंधन के लिए क्यों है :) – neuro

0

क्या आप दूसरे छोर को नियंत्रित करते हैं? एक सॉकेट के "साफ" बंद करने का सबसे विश्वसनीय तरीका दूसरे छोर के लिए किसी प्रकार का "अलविदा" संदेश भेजने के लिए होता है।

+1

नहीं, मैं दूसरे छोर को नियंत्रित नहीं करता हूं। हालांकि, दूसरे छोर ** ** हमेशा एक आवेदन स्तर संदेश भेजना चाहिए जो दर्शाता है कि वे अपने अंत से बंद हो रहे हैं। यह सिर्फ असली दुनिया में है जो हमेशा नहीं होता है।मैं इसे नियमित त्रुटि की तरह व्यवहार कर सकता हूं, लेकिन मैं इसे अधिकतर समय तक कोशिश करना और सक्रिय रूप से पकड़ना चाहता हूं। –

0

(थोड़ा "विषय से बाहर", क्षमा करें)। शायद this discussion आप चार सहायक हो सकता है। यह अभी भी आपको "एफआईएन" प्रश्न का उत्तर नहीं देता है, लेकिन आपके प्रोग्राम भेजते समय सहकर्मी शटडाउन के लिए एक आसान तरीका में प्रतिक्रिया करने में आपकी सहायता कर सकता है।

अलविदा

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