2012-10-23 8 views
21

मैं एक साधारण सर्वर, कि एक ही कनेक्शन को स्वीकार करता है और फिर एक साथ पढ़ सकते हैं और पढ़ने से संदेश लिख सकते हैं और धागे में लिखने के लिए है कि सॉकेट का उपयोग करता है को लागू करने कर रहा हूँ पर लिखें। लिनक्स पर सी/सी ++ में एक ही सॉकेट डिस्क्रिप्टर से एक साथ पढ़ने और लिखने का सुरक्षित और आसान तरीका क्या है? मुझे एक ही सॉकेट से पढ़ने और लिखने के कई धागे के बारे में चिंता करने की आवश्यकता नहीं है क्योंकि सॉकेट में एक समर्पित समर्पित और एकल समर्पित लेखन थ्रेड लेखन होगा।एक साथ पढ़ सकते हैं और सी में एक ही सॉकेट या सी ++

ऊपर परिदृश्य में, आवश्यक ताला लगा किसी भी तरह का है?

क्या उपरोक्त परिदृश्य में गैर अवरोधक सॉकेट की आवश्यकता है?

वहाँ किसी भी खुले स्रोत पुस्तकालय है, कि उपरोक्त परिदृश्य में मदद मिलेगी?

उत्तर

24

उपर्युक्त परिदृश्य में, किसी भी प्रकार की लॉकिंग आवश्यक है?

कोई नहीं।

उपरोक्त परिदृश्य गैर अवरुद्ध सॉकेट आवश्यकता होती है?

बिट आप शायद बारे में चिंतित हैं - पढ़ने और एक स्थापित कनेक्शन पर धागे बारे में - अगर आप खुश उन धागे वहाँ पूरा करने के लिए इंतजार कर बैठने के लिए के लिए कर रहे हैं गैर अवरुद्ध होने की जरूरत नहीं है। आमतौर पर चयन या मतदान या एसिंक ऑपरेशंस के बजाय धागे का उपयोग करने के कारणों में से एक है ... कोड को भी सरल रखता है।

धागा नए ग्राहकों को स्वीकार करने accept() करने के लिए कॉल में ब्लॉक करने के लिए खुश है, तो आप सब अच्छा वहाँ भी कर रहे हैं।

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

क्या कोई ओपनसोर्स लाइब्रेरी है, जो उपर्युक्त परिदृश्य में मदद करेगी?

बुनियादी सर्वर लिखने के लिए पुस्तकालयों के सैकड़ों रहे हैं, लेकिन आप के लिए आसानी से ऊपर ओएस द्वारा प्रदत्त बीएसडी सॉकेट या उनके Windows bastardisation हासिल की है अंत में क्या कहा है।

+3

+1 रेस हालत और डिज़ाइन विकल्पों का उपयोग करने के लिए चुनिंदा या मतदान – Jimm

+1

@ टोनी डी अच्छा सुझाव का उपयोग करने के लिए +1 विकल्प। वृद्धि के दृष्टिकोण से, यदि भविष्य में वह ओपनएसएसएल का उपयोग करने की योजना बना रहा है तो उसका आर्किटेक्चर बदल सकता है। वह एक ही एसएसएल * पर एक साथ पढ़ और लिख नहीं सकता है। – enthusiasticgeek

+0

@enthusiasticgeek: दिलचस्प - मैंने एसएसएल प्रोग्रामिंग नहीं किया है, इसलिए इसके बारे में पता नहीं था, लेकिन ध्यान में रखते हुए निश्चित रूप से लायक है। चीयर्स। –

11

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

12

सॉकेट बीआई-डायरेक्शनल हैं। यदि आपने कभी वास्तव में ईथरनेट या सीरियल केबल को विच्छेदित किया है या उनके लिए निम्न-स्तरीय हार्डवेयर वायरिंग आरेख देखा है, तो आप वास्तव में "TX" (प्रेषण) और "आरएक्स" (प्राप्त) लाइनों के लिए अलग तांबे के तार देख सकते हैं।सॉफ़्टवेयर नियंत्रक से सिग्नल भेजने के लिए सॉफ़्टवेयर, 'सॉकेट' के लिए अधिकांश ओएस एपीआई तक, यह दर्शाता है और अधिकांश सॉफ़्टवेयर (जैसे लिनक्स) पर सॉकेट और सामान्य पाइप के बीच यह महत्वपूर्ण अंतर है।

वास्तव में सॉकेट का अधिकाधिक लाभ उठाने के लिए, आप की जरूरत:
1) Async आईओ समर्थन आईओ समापन बंदरगाहों, epoll(), या कुछ इसी तरह की async कॉलबैक या घटना प्रणाली 'जाग' जब भी डेटा आता है का उपयोग करता है सॉकेट में इसके बाद सॉकेट कनेक्शन से संदेश पढ़ने के लिए अपने निम्नतम स्तर 'रीडडाटा' एपीआई को कॉल करना होगा।
2) एक दूसरा एपीआई जो निम्न स्तर के लिखने का समर्थन करता है, एक 'लिखित डेटा' (प्रेषण) जो सॉकेट पर बाइट को धक्का देता है और 'रीडडाटा' तर्क की ज़रूरतों पर निर्भर नहीं करता है। याद रखें, हार्डवेयर भेजने पर भी आपका प्रेषण और प्राप्त स्वतंत्र है, इसलिए इस स्तर पर लॉकिंग या अन्य सिंक्रनाइज़ेशन शुरू न करें।
3) सॉकेट आईओ थ्रेड्स का एक पूल, जो डेटा के किसी भी प्रसंस्करण को अंधाधुंध करता है जिसे पढ़ा जाता है या सॉकेट में लिखा जाएगा।
4) प्रोटोकॉल कॉलबैक: सॉकेट थ्रेड के कॉलबैक ऑब्जेक्ट में स्मार्ट पॉइंटर्स हैं। यह किसी भी प्रोटोकॉल परत को संभालता है- जैसे कि आपके डेटा ब्लॉब को वास्तविक HTTP अनुरोध में पार्स करना - जो कि मूल सॉकेट कनेक्शन के शीर्ष पर बैठता है। याद रखें, सॉकेट कंप्यूटर के बीच केवल एक डेटा पाइप है और उस पर भेजे गए डेटा अक्सर टुकड़ों की श्रृंखला के रूप में आते हैं- पैकेट। यूडीपी जैसे प्रोटोकॉल में पैकेट भी क्रम में नहीं हैं। निम्न स्तर 'रीडडाटा' और 'लिखित डेटा' उनके थ्रेड से यहां कॉलबैक करेंगे, क्योंकि यह वह जगह है जहां सामग्री-जागरूक डेटा प्रोसेसिंग वास्तव में शुरू होती है।
5) किसी भी कॉलबैक प्रोटोकॉल हैंडलर की जरूरत है। HTTP के लिए, आप कच्चे अनुरोध बफर को अच्छी ऑब्जेक्ट्स में पैकेज करते हैं जो आप एक असली सर्वलेट को सौंप देते हैं, जो एक अच्छा प्रतिक्रिया ऑब्जेक्ट लौटाता है जिसे HTTP spec-compliant प्रतिक्रिया में क्रमबद्ध किया जा सकता है।

मूल पैटर्न पर ध्यान दें: यदि आप द्वि-दिशात्मक, async IO सॉकेट पर पूर्ण लाभ लेना चाहते हैं तो आपको पूरी प्रणाली मूल रूप से async (कॉलबैक का 'प्याज') बनाना होगा। सॉकेट में एक साथ पढ़ने और लिखने का एकमात्र तरीका धागे के साथ है, इसलिए आप अभी भी 'लेखक' और 'पाठक' धागे के बीच सिंक्रनाइज़ कर सकते हैं, लेकिन अगर मैं प्रोटोकॉल या अन्य विचारों को मेरे हाथ पर मजबूर करता हूं तो मैं केवल तभी ऐसा करूंगा। अच्छी खबर यह है कि आप अत्यधिक एसिंक प्रोसेसिंग का उपयोग करके सॉकेट के साथ शानदार प्रदर्शन कर सकते हैं, बुरा यह है कि इस तरह की प्रणाली को मजबूत तरीके से बनाना एक गंभीर प्रयास है।

+4

'बिडरेक्शनल' पर्याप्त नहीं है। हाफ-डुप्लेक्स अभी भी द्विपक्षीय है, लेकिन एक ही समय में नहीं। ओपी की आवश्यकता को पूरा करने के लिए इसे पूर्ण डुप्लेक्स होना चाहिए। टीसीपी/आईपी पूर्ण-डुप्लेक्स के साथ-साथ द्विपक्षीय है। – EJP

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