2010-04-20 17 views
9

दो जुड़े हुए सॉकेट हैं। मैं उन्हें कैसे जोड़ सकता हूं?मैं लिनक्स में दो सॉकेट "इंटरकनेक्ट" कैसे कर सकता हूं?

  1. एक सॉकेट पर दिखाई देने वाला डेटा दूसरे को लिखा जाना चाहिए।
  2. ईओएफ/एफआईएन अच्छी तरह से प्रचार करना चाहिए। यदि कोई आधा बंद है, तो दूसरा भी आधा बंद होना चाहिए।
 
int client = get_connected_client_socket(); 
int proxy = get_connected_proxy_socket(); 
negotiate_with_proxy(proxy); 
iterconnect(client, proxy); 
// Now forgot about both client and proxy. 
// System should handle IO/shutdown/close. 
// Ideally even without any support of the user-space process. 

लिनक्स यह कर सकते हैं? क्या मौजूदा कनेक्शन की ट्रैकिंग स्थिति बदलने के लिए कनेक्शन ट्रैकिंग को ट्रिक करके किया जा सकता है?

Determine how much can I write into a filehandle; copying data from one FH to the other

उत्तर

4

क्या आप splice() से अवगत हैं। आपके दो प्रश्नों के आधार पर मैं सोचता हूं यह वह जगह है जहां आप जा रहे हैं। आखिरी बार मैंने जांच की कि आप इसे एक स्प्लिस कॉल में नहीं कर सकते क्योंकि फाइल डिस्क्रिप्टर दोनों सॉकेट नहीं हो सकते हैं। लेकिन आप इसे 2 कॉल (सॉकिन-> पाइप-> सॉकआउट) में करने में सक्षम होना चाहिए। tee() पर भी एक नज़र डालें। ये वही नहीं हो सकता जो आप चाहते हैं लेकिन जो मैं समझ सकता हूं उससे वे बॉलपार्क में हैं।

+0

नहीं, मुझे 'splice' के बारे में पता नहीं था (मैं केवल सैद्धांतिक रूप से' sendfile' के बारे में जानता था)। मैं सोचूंगा और इसका परीक्षण करूंगा। –

+0

सॉकेट -> पाइप -> सॉकेट 'splice' श्रृंखला काम करता है। –

+0

@Vi .: मुझे लगता है कि आप टीसीपी सॉकेट का उपयोग कर रहे थे? ऐसा लगता है कि यह दृष्टिकोण यूडीपी सॉकेट के लिए काम नहीं करेगा? –

0

एक यूनिक्स डोमेन सॉकेट मदद मिल सकती है @related। मैन पेज देखें:

man unix 
+0

'मैन 7 यूनिक्स' में कुछ भी उपयोगी नहीं मिला। मैं चाहता हूं कि मेरे सॉकेट को 'सॉकेटपेयर' सॉकेट के समान अंतर-प्रभाव प्राप्त हो। मुझे उम्मीद है कि 'इंटरकनेक्ट' टीसीपी, यूनिक्स सॉकेट और फ़ाइल डिस्क्रिप्टर के साथ काम करेगी। –

2

आपको एक सॉकेट से दूसरे सॉकेट में डेटा की प्रतिलिपि बनाने और प्रतिलिपि बनाने के लिए एक उपयोगकर्ता स्पेस प्रक्रिया की आवश्यकता होगी। हालांकि यह बहुत सरल है:

  • सॉकेट एक का कोई भी डेटा read, write बी सॉकेट से;
  • सॉकेट बी, write से सॉकेट ए के लिए कोई भी डेटा read;
  • यदि read सॉकेट ए पर 0 देता है, तो सॉकेट बी पर shutdown(SHUT_WR) पर कॉल करें;
  • यदि read सॉकेट बी पर 0 देता है, तो सॉकेट ए पर shutdown(SHUT_WR) पर कॉल करें;
  • एक बार दोनों सॉकेट पढ़ने से 0 लौट आए हैं, close दोनों सॉकेट और बाहर निकलें;
  • यदि सॉकेट EPIPE, close दोनों सॉकेट और बाहर निकलता है।

Newton Falls के रूप में उल्लेख है, आप splice() उपयोग कर सकते हैं एक शून्य-प्रतिलिपि ढंग से ऐसा करने के लिए, लेकिन यह सिर्फ एक प्रदर्शन को बढ़ाने है, इसे read/write के साथ पहले काम करें। ऐसा करने के लिए आपको बच्चे से सिर्फ fork() करने में सक्षम होना चाहिए, जो आपकी मुख्य प्रक्रिया के लिए "आग और भूल" देगा।

+0

ऐसा लगता है कि 'splice' चीज मदद कर सकती है। 'लिखना' अच्छा नहीं है, क्योंकि यह कम लिख सकता है तो मैंने अनुरोध किया और मुझे बाकी को कहीं और बचा लेना चाहिए। 'फोर्क' अच्छा नहीं है, नए कनेक्शन => नई प्रक्रिया के कारण, इसे एफडी (विरासत/विरासत में प्राप्त) की सावधानी से संभालने की भी आवश्यकता है। –

+0

जैसा कि मैंने कहा था, 'splice() 'केवल एक प्रदर्शन वृद्धि है - यह भी आपके अनुरोध से कम विभाजित कर सकता है, और यह' फोर्क() 'को कम या ज्यादा उपयोगी नहीं बनायेगा (आपको अभी भी' splice रखना होगा () जब तक कनेक्शन समाप्त नहीं हो जाता है)। – caf

+0

यदि स्प्लिसे ने अनुरोध किए गए से कम विभाजन किया है, तो बाकी ('size_I_requested - size_actually_spliced') एक पढ़ा गया एफडी में रहेगा, इसलिए जब मैं आउटपुट को प्रक्रिया में डेटा संग्रहीत किए बिना अनब्लॉक कर दूंगा तो मैं इसे बाद में विभाजित कर सकता हूं। तो पाइप बफर का उपयोग किया जाएगा और मुझे अपने कार्यक्रम में चीजों को आवंटित/रद्द करने की आवश्यकता नहीं है। –

0

सोशल टूल चेकआउट करें। इस तरह की समस्याओं को हल करने के लिए यह सबसे अच्छा टूल है।

+1

मुझे पता है और अक्सर इसका उपयोग करें। लेकिन सवाल यह है कि कार्यक्रम में इसे कैसे किया जाए। इसके लिए 'सामाजिक -' पैदा करना बहुत अपमानजनक है। –

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