के बीच कर्नेल-आधारित (लिनक्स) डेटा रिले मैंने टीसीपी रिले सर्वर लिखा जो पीयर-टू-पीयर राउटर (सुपरर्नोड) की तरह काम करता है।दो टीसीपी सॉकेट
सरलतम मामले रहे हैं दो खोला सॉकेट और उन दोनों के बीच डेटा रिले:
clientâ < ---> सर्वर < ---> clientB
हालांकि सर्वर लगभग 2000 ऐसी अटल बिहारी सेवा करने के लिए है जोड़े, यानी। 4000 सॉकेट ...
दो अच्छी तरह से ज्ञात userland में डेटा स्ट्रीम रिले कार्यान्वयन कर रहे हैं (socketA.recv() के आधार पर -> socketB.send() और socketB.recv() -> socketA.send()):
- का उपयोग करते हुए/चुनाव कार्यों (गैर अवरुद्ध विधि)
- धागे की का उपयोग कर चयन/कांटे (अवरुद्ध विधि)
मैंने थ्रेड का उपयोग किया ताकि सबसे खराब मामले में सर्वर 2 * 2000 धागे बनाता है! मुझे ढेर के आकार को सीमित करना था और यह काम करता है लेकिन क्या यह सही समाधान है? मेरे सवाल का
कोर:
वहाँ एक रास्ता userland में दो सॉकेट के बीच प्रसारण सक्रिय डेटा से बचने के लिए है?
ऐसा लगता है कि एक निष्क्रिय तरीका है। उदाहरण के लिए, मैं प्रत्येक सॉकेट से फ़ाइल डिस्क्रिप्टर बना सकता हूं, दो पाइप बना सकता हूं और dup2() का उपयोग कर सकता हूं - stdin/out रीडायरेक्टिंग जैसी ही विधि। फिर दो धागे डेटा रिले के लिए बेकार हैं और इसे समाप्त/बंद किया जा सकता है। सवाल यह है कि अगर सर्वर को सॉकेट और पाइप बंद करना चाहिए और तथ्य कैसे लॉग इन करने के लिए पाइप टूटा हुआ है तो कैसे पता होना चाहिए?
मुझे "सॉकेट जोड़े" भी मिला है लेकिन मुझे इसके उद्देश्य के बारे में निश्चित नहीं है।
उपयोगकर्तालैंड को ऑफ-लोड करने और थ्रेड के लिए राशि सीमित करने के लिए आप किस समाधान का सुझाव देंगे?
कुछ अतिरिक्त स्पष्टीकरण:
- सर्वर (ID_B साथ जैसे ID_A - बनती पहचानकर्ता।) स्थिर अनुमार्गण तालिका में परिभाषित किया गया है। क्लाइंट ए सर्वर से कनेक्ट होता है और आईडी_ए भेजता है। फिर सर्वर क्लाइंट बी के लिए इंतजार कर रहा है जब ए और बी जोड़े जाते हैं (दोनों सॉकेट खोले जाते हैं) सर्वर डेटा रिले शुरू करता है।
- ग्राहक सममित एनएटी के पीछे सरल उपकरण हैं इसलिए एन 2 एन प्रोटोकॉल या एनएटी ट्रैवर्सल तकनीक उनके लिए बहुत जटिल हैं।
गेरहार्ड Rieger के लिए धन्यवाद मैं संकेत है:
मैं दो गिरी अंतरिक्ष तरीके के बारे में पता से बचने के लिए कर रहा हूँ पढ़ने/लिखने, recv/उपयोगकर्ता अंतरिक्ष में भेज:
- sendfile
- splice
दोनों में फ़ाइल डिस्क्रिप्टर के प्रकार के संबंध में प्रतिबंध हैं।
dup2 कर्नेल, AFAIK में कुछ करने में मदद नहीं करेगा।
मैन पेज: splice(2)splice(2)vmsplice(2)sendfile(2)tee(2)
संबंधित लिंक:
- Understanding sendfile() and splice()
- http://blog.superpat.com/2010/06/01/zero-copy-in-linux-with-sendfile-and-splice/
- http://yarchive.net/comp/linux/splice.html (लीनुस)
- C, sendfile() and send() difference?
- bridging between two file descriptors
- Send and Receive a file in socket programming in Linux with C/C++ (GCC/G++)
- http://ogris.de/howtos/splice.html
उन कई कनेक्शनों के लिए, कुछ धागे और ['एपोल (4)'] (http://linux.die.net/man/4/epoll) का संयोजन शायद कुछ ऐसा है जो आपको देखना चाहिए। –
वह, और आप कुछ [libev] (http://software.schmorp.de/pkg/libev.html) – Hasturkun
धन्यवाद का उपयोग कर सकते हैं। हालांकि यह अभी भी उपयोगकर्तालैंड में सक्रिय रिले है। मेरा मानना है कि एक निष्क्रिय विधि मौजूद है। सर्वर 5 एस टाइमआउट के साथ क्लाइंट की आईडी के लिए इंतजार कर रहा है, इसलिए थ्रेड को युग्मन चरण के लिए प्राकृतिक पसंद लग रहा था। – nopsoft