2011-12-07 12 views
17

कैसे कर सकता है इंडी के TIdTCPClient और TIdTCPServer इस परिदृश्य में इस्तेमाल किया जा:इंडी टीसीपी क्लाइंट/सर्वर

Client ---------- initate connection -----------> Server 
... 
Client <---------------command------------------- Server 
Client ----------------response-----------------> Server 
... 
Client <---------------command------------------- Server 
Client ----------------response-----------------> Server 

ग्राहक कनेक्शन शुरुआत करता है, लेकिन एक "सर्वर" के रूप में कार्य (आदेशों की प्रतीक्षा और उन्हें निष्पादित)।

OnExecuteTIdTCPServer का दृष्टिकोण इस मामले में अच्छी तरह से काम नहीं करता है (कम से कम मुझे इसे अच्छी तरह से काम करने के लिए नहीं मिल रहा है)। मैं ये कैसे करूं?

मुझे आशा है कि प्रश्न पर्याप्त स्पष्ट है।

+2

हो सकता है कि आप इस व्यवहार को 'IdTCPClient1.IOHandler.ReadLnWait' या' IdTCPClient1.IOHandler.WaitFor' विधियों के साथ अनुकरण कर सकें। अन्यथा, 'TIdCmdTCPCLient' का उपयोग करके आपकी समस्या हल हो सकती है। – LightBulb

+0

इंडी का कौन सा संस्करण? –

+0

वर्तमान में, मैं डेल्फी 2010 में इंडी 10 का उपयोग कर रहा हूं। – LightBulb

उत्तर

17

इंडी के TIdTCPServer घटक के साथ ऐसा करने से आपको कुछ भी नहीं रोक रहा है।

एक TIdTCPServer केवल कनेक्शन सेट अप करता है। आपको बाकी को लागू करने की आवश्यकता होगी। तो वास्तविक भेजने और प्राप्त करने का अनुक्रम जो भी आप चाहते हैं हो सकता है।

अपने TIdTCPServer घटक के OnExecute घटना में इस कोड डालें:

var 
    sName: String; 
begin 
    // Send command to client immediately after connection 
    AContext.Connection.Socket.WriteLn('What is your name?'); 
    // Receive response from client 
    sName := AContext.Connection.Socket.ReadLn; 
    // Send a response to the client 
    AContext.Connection.Socket.WriteLn('Hello, ' + sName + '.'); 
    AContext.Connection.Socket.WriteLn('Would you like to play a game?'); 
    // We're done with our session 
    AContext.Connection.Disconnect; 
end; 

करने का तरीका यहां सेटअप कर सकते हैं TIdTCPServer वास्तव में बस:

IdTCPServer1.Bindings.Clear; 
IdTCPServer1.Bindings.Add.SetBinding('127.0.0.1', 8080); 
IdTCPServer1.Active := True; 

इस सर्वर बताता केवल लूपबैक पते पर सुनने के लिए, पोर्ट 8080 पर। यह आपके कंप्यूटर के बाहर से कनेक्ट होने से किसी को भी रोकता है।

फिर, अपने ग्राहक कनेक्ट करने के लिए, आप एक Windows कमांड प्रॉम्प्ट में जाकर निम्नलिखित लिख सकते हैं:

तुम्हारा नाम क्या है:

telnet 127.0.0.1 8080 

यहाँ उत्पादन है?

मार्कस

हैलो, मार्कस।

क्या आप एक खेल खेलना चाहते हैं?

खोने वाले होस्ट के लिए कनेक्शन।

टेलनेट नहीं है? यहां बताया गया है कि install telnet client on Vista and 7 कैसे करें।

या एक TIdTCP क्लाइंट के साथ, आप ऐसा कर सकते हैं:

var 
    sPrompt: String; 
    sResponse: String; 
begin 
    // Set port to connect to 
    IdTCPClient1.Port := 8080; 
    // Set host to connect to 
    IdTCPClient1.Host := '127.0.0.1'; 
    // Now actually connect 
    IdTCPClient1.Connect; 
    // Read the prompt text from the server 
    sPrompt := IdTCPClient1.Socket.ReadLn; 
    // Show it to the user and ask the user to respond 
    sResponse := InputBox('Prompt', sPrompt, ''); 
    // Send user's response back to server 
    IdTCPClient1.Socket.WriteLn(sResponse); 
    // Show the user the server's final message 
    ShowMessage(IdTCPClient1.Socket.AllData); 
end; 

यहाँ नोट करने के लिए एक महत्वपूर्ण बात यह है कि ReadLn बयान इंतजार डेटा उपलब्ध होने तक। यह सब के पीछे जादू है।

+7

'जादू' को अपने धागे में रखा जाना चाहिए ताकि एप्लिकेशन जारी रहे, जबकि सर्वर के पास – mjn

5

जब ग्राहक सर्वर से कनेक्ट होता है, तो सर्वर पर AContext: TIdContext पैरामीटर के साथ ऑनकनेक्ट ईवेंट होता है।

इसकी एक संपत्ति AContext.Connection है, जिसे आप उस घटना के बाहर स्टोर कर सकते हैं (कहें, एक ऐरे में)। यदि आप इसे आईपी या बेहतर अभी तक जेनरेटेड सत्र आईडी के साथ जोड़ते हैं, तो उस मानदंड से कनेक्शन का संदर्भ लें, तो आप सर्वर को एडॉक कमांड या क्लाइंट को संदेश भेज सकते हैं।

आशा है कि इससे मदद मिलती है!

+0

वह पूछ रहा है कि कोई ग्राहक सर्वर से कमांड सुन सकता है या नहीं। – LightBulb

+2

हां, और यह समाधान इसके लिए अनुमति देता है! सर्वर को केवल प्रत्येक क्लाइंट के कनेक्शन को स्टोर करने की आवश्यकता होती है ताकि वह क्लाइंट कमांड का जवाब देने के लिए सीमित किए बिना संदेश या आदेश सीधे एक या अधिक क्लाइंट को पास कर सके! – LaKraven

+0

और ग्राहक को पता चलेगा कि क्लाइंट पक्ष पर कोई श्रवण धागा नहीं है तो उसे एक आदेश प्राप्त हुआ है? – LightBulb

-3

इंडी के साथ इस डिजाइन से संभव नहीं है:
इंडी केवल ग्राहक द्वारा आरंभ किए गए संचार का समर्थन करता है, क्या अर्थ है कि सर्वर केवल ग्राहक द्वारा अनुरोध के जवाब में भेज सकते हैं।
पुल-प्रोसेस का उपयोग करना चाहते हैं जो प्राप्त करने के लिए सबसे आसान तरीका (लेकिन सबसे स्मार्ट नहीं) है। एक नया आदेश होने पर ग्राहक टाइमर द्वारा नियंत्रित सर्वर से सर्वर से पूछते हैं। बेशक यह बहुत अधिक ट्रैफिक-ओवरहेड का कारण बनता है और आपके पुल-इंटरवॉल के आधार पर देरी होती है।
वैकल्पिक रूप से आप एक और (http://www.overbyte.be/eng/products/ics.html) आईसीएस की तरह पुस्तकालय

+1

क्या यह वास्तव में इंडी का एक डिज़ाइन दोष है? मैंने हमेशा सोचा कि यह एक टीसीपी सीमा थी ... –

+0

ओह, ठीक है उस मामले में मुझे लगता है कि हम "मिशन असंभव" में टॉम क्रूज़ की तरह हैं क्योंकि हमारे ग्राहकों से कोई भी खींचने के बिना, हमारा सर्वर हमारे ग्राहकों को संदेश भेज रहा है, उदाहरण के लिए जब यह बंद हो रहा है, या कुछ डेटा में परिवर्तन के सभी जुड़े ग्राहकों को बताने के लिए ... –

+3

IIUC टीसीपी/आईपी संचार है: 1. क्लाइंट सर्वर से कनेक्ट होता है (जिस पार्टी को कनेक्शन शुरू होता है वह क्लाइंट परिभाषा द्वारा क्लाइंट है), 2।दोनों पार्टियां किसी भी समय डेटा भेज सकती हैं (क्योंकि एक टीसीपी/आईपी सॉकेट बिडरेक्शनल है) – mjn

4

इस्तेमाल कर सकते हैं सामान्य रूप से ग्राहक और सर्वर साइड एक धागा है कि भेजे टेलीग्राम पढ़ रही है, और लंबित टेलीग्राम भेजने है ... लेकिन प्रोटोकॉल के इस प्रकार (/ प्राप्त भेजते हैं, कब और क्या) आवेदन पर निर्भर करता है।

3

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

इंडी टेलनेट ग्राहक टेलनेट सर्वर से कनेक्ट और और डेटा को पढ़ने लिखने के लिए केवल एक सॉकेट उपयोग करता है। श्रोता धागे में पढ़ना होता है।

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

+0

कहने के लिए कुछ भी नहीं है, मैंने पहले इस तरह एक प्रोटोकॉल लागू किया है और इसे टेलनेट क्लाइंट कोड पर सफलतापूर्वक आधारित किया है। – MikeT

6

यदि आपके आदेश प्रकृति में टेक्स्ट हैं, तो TIdCmdTCPClient घटक पर एक नज़र डालें, यह विशेष रूप से उन स्थितियों के लिए डिज़ाइन किया गया है जब सर्वर क्लाइंट के बजाय आदेश भेज रहा है। आदेश भेजने के लिए सर्वर TIdContext.Connection.IOHandler.WriteLn() या TIdContext.Connection.IOHandler.SendCmd() का उपयोग कर सकता है।

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