2012-06-12 6 views
6

पर मल्टीथ्रेडेड टीसीपी सर्वर लिखना काम पर मुझे मॉडबस दास डिवाइस के हिस्से के रूप में एक टीसीपी सर्वर को लागू करने के साथ काम सौंपा गया है। मैंने यहां स्टैक एक्सचेंज और इंटरनेट पर सामान्य रूप से बहुत कुछ पढ़ा है (उत्कृष्ट http://beej.us/guide/bgnet/ सहित) लेकिन मैं एक डिजाइन मुद्दे के साथ संघर्ष कर रहा हूं। संक्षेप में, मेरा डिवाइस केवल 2 कनेक्शन स्वीकार कर सकता है और प्रत्येक कनेक्शन पर आने वाले मॉडबस अनुरोध होंगे जो मुझे अपने मुख्य नियंत्रक पाश में संसाधित करना होगा और फिर सफलता या विफलता स्थिति के साथ जवाब देना होगा। मेरे पास यह लागू करने के तरीके के बारे में निम्नलिखित विचार हैं।लिनक्स

  1. फिर एक नया pthread को आने वाले डेटा और एक निष्क्रिय समय समाप्ति की अवधि के बाद करीब कनेक्शन के लिए कनेक्शन पर सुनने spawns, एक श्रोता थ्रेड, बनाता है बांधता है, सुनता है और कनेक्शन स्वीकार लो। यदि सक्रिय धागे की संख्या वर्तमान में 2 है, तो केवल 2 सुनिश्चित करने के लिए नए कनेक्शन तुरंत बंद कर दिए जाते हैं।

  2. श्रोता धागे से नए धागे को न उतारें, इसके बजाय इनकमिंग कनेक्शन अनुरोधों का पता लगाने के लिए चयन() का उपयोग करें, साथ ही इनकमिंग मोडबस सक्रिय कनेक्शन पर कनेक्ट होता है (बीज गाइड में दृष्टिकोण के समान)।

  3. 2 श्रोता धागे बनाएं जिनमें से प्रत्येक सॉकेट (एक ही आईपी और पोर्ट नंबर) बनाता है जो स्वीकृति() कॉल पर अवरुद्ध कर सकता है, फिर सॉकेट एफडी बंद कर सकता है और कनेक्शन से निपट सकता है। यहां मैं मान रहा हूं (शायद बेवकूफ़) यह मानते हुए कि यह केवल अधिकतम 2 कनेक्शनों को अनुमति देगा जिन्हें मैं ब्लॉकिंग पढ़ने के साथ सौदा कर सकता हूं।

मैं लंबे समय से सी ++ का उपयोग कर रहा हूं लेकिन मैं लिनक्स विकास के लिए बिल्कुल नया हूं। मैं वास्तव में किसी भी सुझाव का स्वागत करता हूं कि उपरोक्त में से कौन सा दृष्टिकोण सबसे अच्छा है (यदि कोई है) और यदि लिनक्स के साथ मेरा अनुभवहीनता का अर्थ है कि उनमें से कोई वास्तव में वास्तव में खराब विचार हैं। मैं कांटा() से बचने के लिए उत्सुक हूं और पठारों तक चिपक जाता हूं क्योंकि इनकमिंग मोडबस अनुरोधों को कतारबद्ध किया जा रहा है और समय-समय पर मुख्य नियंत्रक पाश को पढ़ा जा रहा है। किसी भी सलाह के लिए अग्रिम धन्यवाद।

उत्तर

3

तीसरा विकल्प काम नहीं करेगा, आप केवल एक बार स्थानीय पते से जुड़ सकते हैं।

मैं शायद आपके दूसरे विकल्प का उपयोग करूंगा, जब तक कि आपको बहुत से प्रोसेसिंग करने की आवश्यकता न हो, इस मामले में पहले विकल्पों का संयोजन उपयोगी हो सकता है।

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

+0

मुझे इसकी आवाज़ पसंद है - केवल समस्या यह है कि मेरा मुख्य पाश सख्ती से अवरुद्ध नहीं होना चाहिए। यह प्रसंस्करण और आवधिक रूप से श्रोता धागे से अनुरोधों के साथ सौदा करना चाहिए। इस बात को ध्यान में रखते हुए आप विकल्प 2 कहते हैं। – mathematician1975

+0

@ गणितज्ञ 1 9 75 आप अभी भी मेरी विधि का उपयोग कर सकते हैं, लेकिन 'स्वीकार' पर अवरुद्ध करने के बजाय शॉर्ट या नो-टाइमआउट 'चयन' का उपयोग करें (या सुनने की सॉकेट को गैर-अवरुद्ध करें और 'स्वीकार करें' का उपयोग करें और 'EAGAIN'/'EWOULDBLOCK के लिए जांचें ') यह जानने के लिए कि कनेक्शन कब स्वीकार किया जा सकता है। –

+0

मुझे लगता है कि मेरी समय की बाधाओं को देखते हुए यह मेरे लिए अल्प अवधि में आगे बढ़ने का सबसे अच्छा समाधान है। आपके सुझाव के लिए धन्यवाद। – mathematician1975

2

जब से तुम केवल 2 कनेक्शन के साथ काम कर रहे हैं, कनेक्शन के प्रति धागा आवेदन के इस प्रकार के लिए एकदम सही है। गैर-अवरुद्ध या एसिंक्रोनस I/O का उपयोग करके ऑब्जेक्ट उन्मुख दृष्टिकोण बेहतर होंगे यदि आपको हजारों कनेक्शन तक पहुंचने की आवश्यकता है। 2 श्रोता धागे समझ में आता है, आपको स्वीकार एफडी को बंद करने की आवश्यकता नहीं है। कनेक्शन पूरा होने पर बस इसे स्वीकार करने के लिए वापस आएं। वास्तव में, एक भिन्नता है कि तीन धागे को स्वीकार करने से अवरुद्ध हो। यदि धागे के दो सक्रिय रूप से कनेक्शन संभाल रहे हैं, तो तीसरे नव निर्मित कनेक्शन रीसेट करता है (या व्यस्त प्रतिक्रिया, जो कुछ भी अपने डिवाइस के लिए उपयुक्त है देता है)।

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

man page for pthreads on Linux इंगित करता है कि स्वीकार थ्रेड-सुरक्षित है। (थ्रेड-सुरक्षित फ़ंक्शंस के तहत अनुभाग उन फ़ंक्शंस को सूचीबद्ध करता है जो थ्रेड-सुरक्षित नहीं हैं, आंकड़े पर जाएं।)

+0

क्या आप मेरे प्रश्न में विकल्प 3 का मतलब है? – mathematician1975

+0

@ गणितज्ञ 1 9 75: हाँ, मैं विकल्प 3 की विविधता सोच रहा था, लेकिन तीन धागे स्वीकार कर रहा था। – jxh

+0

लेकिन दूसरा जवाब यहां कहता है कि मैं केवल एक बार बांध सकता हूं, जो विकल्प 3 का नियम बनाता है ?? – mathematician1975

2

आपके द्वारा प्रस्तावित सभी डिज़ाइन विकल्प बहुत ऑब्जेक्ट उन्मुख नहीं हैं, और वे सभी सी ++ की तुलना में सी की ओर अधिक तैयार हैं । यदि आपका काम आपको बढ़ावा देने की अनुमति देता है, तो Boost.Asio लाइब्रेरी सरल (और जटिल) सॉकेट सर्वर बनाने के लिए शानदार है। आप अपने लगभग किसी भी उदाहरण ले सकते हैं और इसे केवल 2 सक्रिय कनेक्शनों को अनुमति देने के लिए इसे विस्तारित कर सकते हैं, जैसे ही वे खोले जाते हैं, अन्य सभी को बंद कर देते हैं।

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

यह आपकी पहली डिजाइन पसंद के समान निकटता से होगा, बूस्ट इसे 1 थ्रेड में कर सकता है और पृष्ठभूमि में select() (आमतौर पर epoll()) जैसा कुछ होता है। लेकिन यह "सी ++ रास्ता" है, और मेरी राय में select() और कच्चे pthread एस का उपयोग सी तरीका है।

+0

इस सुझाव के लिए धन्यवाद। मैं इसके साथ सी ++ और ओओ पहलुओं के बारे में पूरी तरह से सहमत हूं। हालांकि, मेरे समय पर मौजूदा बाधाओं को देखते हुए मुझे लगता है कि मुझे कच्चे लिनक्स एपीआई दृष्टिकोण को आगे बढ़ाना होगा क्योंकि इसमें मुझे इसका उपयोग करने के लिए समय लगता है और इसे प्रोटोटाइप तेजी से प्राप्त करने की आवश्यकता है। हालांकि, एक बार परियोजना स्वीकार होने के बाद मुझे लगता है कि मैं निश्चित रूप से इस दृष्टिकोण का पक्ष लेगा – mathematician1975