घर बारहमासी फूल डेल्फी में इंडी का उपयोग कर क्लाइंट-सर्वर अनुप्रयोगों का विकास। डेल्फी में प्रयुक्त इंडी घटक। इंडी घटकों का उपयोग करने के कुछ उदाहरण

डेल्फी में इंडी का उपयोग कर क्लाइंट-सर्वर अनुप्रयोगों का विकास। डेल्फी में प्रयुक्त इंडी घटक। इंडी घटकों का उपयोग करने के कुछ उदाहरण

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

चरण-दर-चरण निर्देश:

मैंने एक उदाहरण दिया, लेकिन आप मुझे क्षमा करें, मैंने प्रत्येक पंक्ति को चित्रित करना शुरू नहीं किया, क्योंकि मुझे कुछ भी जटिल नहीं दिखता और कोई भी इसका पता लगा सकता है।

दरअसल, अगर कुछ स्पष्ट नहीं है, तो आप मुझसे एक प्रश्न पूछ सकते हैं। और यहाँ वास्तविक कोड है:

उपयोग
विंडोज, संदेश, SysUtils, वेरिएंट, क्लास, ग्राफिक्स, कंट्रोल, फॉर्म,
संवाद, StdCtrls, IdUDPServer, IdBaseComponent, IdComponent, IdUDPBase,
IdUDPClient, IdSocketHandle;

प्रकार
TForm1 = वर्ग (TForm)
IdUDPClient1: TIdUDPClient;
IdUDPServer1: TIdUDPServer;
बटन 1: टीबीटन;
लेबल1: टी लेबल;
प्रक्रिया फॉर्मक्रिएट (प्रेषक: टॉब्जेक्ट);
प्रक्रिया फॉर्मक्लोज (प्रेषक: टॉब्जेक्ट; वर एक्शन: टीक्लोजएक्शन);
प्रक्रिया बटन 1 क्लिक करें (प्रेषक: टॉब्जेक्ट);
प्रक्रिया IdUDPServer1UDPRead(Athread: TIdUDPLListenerThread; AData: TBytes;
एबाइंडिंग: TIdSocketHandle);
निजी
(निजी घोषणाएं)
जनता
(सार्वजनिक घोषणाएं)
समाप्त;

वर
फॉर्म1: टीफॉर्म1;

($आर *.dfm)
[बी] // संदेश भेजने की प्रक्रिया
प्रक्रिया TForm1.Button1Click (प्रेषक: टॉब्जेक्ट);
शुरू
कोशिश करो
IdUDPClient1.सक्रिय:= सच;
IdUDPClient1.Host:= "लोकलहोस्ट";
IdUDPClient1.कनेक्ट;
अगर IdUDPClient1.Connected तो
शुरू
IdUDPClient1.Send(TimeToStr(Time));
लेबल1.कैप्शन:= "ओके";
समाप्त;
IdUDPClient1.सक्रिय:= असत्य;
बीप, बीप, बीप;
के अलावा
MessageDlg ("कुछ गलत हुआ =(", mtError, , 0);
समाप्त;
समाप्त;
[बी]
//चालू बंद। फॉर्म पर यूडीपी सर्वर प्रारंभ और बंद करें
प्रक्रिया TForm1.FormClose (प्रेषक: टॉब्जेक्ट; var क्रिया: TCloseAction);
शुरू
IdUDPServer1.सक्रिय:= असत्य;
समाप्त;

प्रक्रिया TForm1.FormCreate (प्रेषक: टॉब्जेक्ट);
शुरू
IdUDPServer1.सक्रिय:= सच;
समाप्त;

[बी]//डेटा प्राप्त करते समय सर्वर प्रतिक्रिया की प्रक्रिया
प्रक्रिया TForm1.IdUDPServer1UDPRead(Athread: TIdUDPLListenerThread;
एडाटा: टीबीइट्स; एबाइंडिंग: TIdSocketHandle);
वर
मैं: पूर्णांक;
एस: स्ट्रिंग;
शुरू
एस: = "";
कोशिश करो
मैं: = 0;
जबकि (एडाटा [i] 0) करते हैं
शुरू
एस: = एस + सीआर (एडाटा [i]);
मैं: = मैं + 1;
समाप्त;
आखिरकार
लेबल1.कैप्शन:= एस;
समाप्त;
समाप्त;

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

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

डेल्फ़ी के मूल वितरण में पेनीज़ के साथ इंडी v.9 शामिल है। शायद, तुरंत एक नए संस्करण में अपग्रेड करने की सलाह दी जाती है (उदाहरण के लिए, मेरे पास वर्तमान में 10.0.76 है, लेकिन बाद में भी हैं, ऐसा लगता है)।

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

"अकादमिक" उदाहरण (कोड काम नहीं कर रहा है, इसे न चलाएं :)):

इंडी क्लाइंट के साथ
शुरू
होस्ट: = "test.com";
पोर्ट: = 2000;
जुडिये;
कोशिश करो
// डेटा के साथ काम करें (पढ़ना, लिखना ...)
आखिरकार
डिस्कनेक्ट;
समाप्त;
समाप्त;

होस्ट और पोर्ट को ऑब्जेक्ट इंस्पेक्टर या रनटाइम पर सेट किया जा सकता है।

पार्सिंग कार्यों में इंडी घटकों का क्या उपयोग किया जा सकता है? आवेदन विविध है! IdHTTP घटक का उपयोग करके पृष्ठ की सामग्री प्राप्त करना सबसे आसान है (सभी शायद पहले ही इसका सामना कर चुके हैं):

वर
आरसीवीआरडेटा: टीमेमरीस्ट्रीम;
idHttp1: TidHttp;
शुरू
idHttp1:= TidHttp.Create(nil);
rcvrdata:= TMemoryStream.Create;
idHttp1.Request.UserAgent: = "मोज़िला/4.0 (संगत; एमएसआईई 5.5; विंडोज 98)";
idHttp1.Request.AcceptLanguage:= "en";
idHttp1.Response.KeepAlive:= सच;
idHttp1.HandleRedirects:= true;
कोशिश करो
idHttp1.Get(Edit1.Text, rcvrdata);
आखिरकार
idHttp1.नि: शुल्क;
समाप्त;
अगर rcvrdata.Size > 0 तो शुरू करें
ShowMessage ("प्राप्त" + inttostr (rcvrdata.Size));
rcvrdata.SaveToFile("c:\111.tmp");
समाप्त;
rcvrdata.नि: शुल्क;
समाप्त;

जैसा कि आप देख सकते हैं, आप न केवल पृष्ठ की सामग्री प्राप्त कर सकते हैं, बल्कि किसी विशिष्ट क्लाइंट से दस्तावेज़ लोड करने का अनुकरण भी कर सकते हैं। इंडी घटक आम तौर पर हेडर और POST अनुरोध उत्पन्न करने के लिए आसान होते हैं। अगली बार उदाहरणों के साथ इस पर और अधिक।

ब्लॉग अपडेट से अपडेट रहने के लिए, आप कर सकते हैं

इंडी का परिचय

इंडी का परिचय
लेखक: चाड जेड होवर
होमपेज: http://www.atozedsoftware.com
अनुवाद: अनातोली पोडगोरेत्स्की
परिचय
मैंने यह लेख तब लिखा था जब वर्तमान संस्करण इंडी 8.0 था। इस लेख का अधिकांश भाग इंडी के भविष्य के संस्करणों में लागू और बहुत उपयोगी है। अगर आपको यह लेख पसंद आया है और अधिक विस्तृत लेख पढ़ना चाहते हैं, तो इंडी इन डेप्थ पुस्तक पर एक नज़र डालें।
इंडी ब्लॉकिंग मोड में चल रहा है
इंडी ब्लॉकिंग सॉकेट्स का उपयोग करता है। ब्लॉकिंग मोड एक फाइल को पढ़ने-लिखने जैसा है। डेटा पढ़ते या लिखते समय, फ़ंक्शन ऑपरेशन के अंत तक नियंत्रण वापस नहीं करता है। फाइलों के साथ काम करने से अंतर यह है कि कॉल लंबी हो सकती है क्योंकि अनुरोधित डेटा अभी तक उपलब्ध नहीं है, यह उस गति पर निर्भर करता है जिस पर आपका नेटवर्क या मॉडेम काम कर रहा है।
उदाहरण के लिए, बस एक विधि कॉल करें और कॉल करने वाले को नियंत्रण वापस आने तक प्रतीक्षा करें। यदि कॉल सफल रही, तो विधि से नियंत्रण वापस कर दिया जाएगा, और त्रुटि पर एक अपवाद उठाया जाएगा।
ब्लॉकिंग मोड घातक नहीं है
ब्लॉकिंग मोड के कारण, हमें अपने विरोधियों द्वारा बार-बार पीटा गया है, लेकिन ब्लॉकिंग मोड शैतान नहीं है।
विंसॉक को विंडोज़ में पोर्ट किए जाने के बाद समस्या सामने आई। यूनिक्स में, समस्या को आमतौर पर फोर्किंग (मल्टी-थ्रेडिंग के समान, लेकिन थ्रेड्स के बजाय अलग प्रक्रियाओं द्वारा) द्वारा हल किया गया था। यूनिक्स क्लाइंट और डेमॉन को ब्लॉकिंग मोड को चलाने और उपयोग करने के लिए प्रक्रियाओं को फोर्क करना पड़ता था। विंडोज 3.x समानांतर नहीं हो सका और बहु-थ्रेडिंग का समर्थन नहीं करता। ब्लॉकिंग इंटरफेस का उपयोग करने से यूजर इंटरफेस फ्रीज हो जाता है और प्रोग्राम अनुत्तरदायी हो जाते हैं। इसलिए, WinSock में गैर-अवरुद्ध मोड जोड़े गए, जिससे Windows 3.x, इसकी सीमाओं के साथ, प्रोग्राम के मुख्य और एकमात्र थ्रेड को अवरुद्ध किए बिना Winsock का उपयोग करने की अनुमति देता है। इसके लिए अलग प्रोग्रामिंग की आवश्यकता थी, और माइक्रोसॉफ्ट और अन्य ने विंडोज 3.x की कमियों को छिपाने के लिए ब्लॉकिंग मोड की कड़ी निंदा की।
फिर आया Win32, जो मल्टी-थ्रेडिंग को सपोर्ट करने में सक्षम था। लेकिन इस बिंदु तक, दिमाग पहले से ही पाउडर हो चुके थे (अर्थात, डेवलपर्स ने सॉकेट्स को शैतान का उत्पाद माना था), और जो उन्होंने किया था उसे बदलना पहले से ही कठिन था। इसलिए, अवरुद्ध शासनों की बदनामी जारी है।
वास्तव में, यूनिक्स में केवल ब्लॉकिंग सॉकेट हैं। ब्लॉकिंग सॉकेट के भी अपने फायदे हैं, और वे बहुत सारे थ्रेडिंग, सुरक्षा और अन्य पहलुओं के लिए बहुत बेहतर हैं। गैर-अवरुद्ध सॉकेट के लिए यूनिक्स में कुछ एक्सटेंशन भी जोड़े गए हैं। हालांकि, वे विंडोज़ की तुलना में बहुत अलग तरीके से काम करते हैं। वे गैर-मानक भी हैं और बहुत सामान्य नहीं हैं। यूनिक्स में ब्लॉकिंग सॉकेट का उपयोग लगभग सभी मामलों में किया जाता है, और इनका उपयोग जारी रहेगा।
ब्लॉकिंग मोड के लाभ प्रोग्राम में आसान - ब्लॉकिंग मोड प्रोग्राम करने में आसान होते हैं। सभी उपयोगकर्ता कोड एक ही स्थान पर हो सकते हैं और प्राकृतिक, अनुक्रमिक क्रम में निष्पादित किए जा सकते हैं। · यूनिक्स में आसान पोर्टिंग - चूंकि यूनिक्स ब्लॉकिंग सॉकेट का उपयोग करता है, इस मामले में पोर्टेबल कोड लिखना आसान है। इंडी इस तथ्य का उपयोग लगातार कोड लिखने के लिए करता है। · थ्रेड्स के साथ काम करने के लिए अधिक सुविधाजनक - चूंकि ब्लॉकिंग सॉकेट्स में आनुवंशिकता द्वारा प्राप्त अनुक्रम होता है, इसलिए उन्हें थ्रेड्स में उपयोग करना बहुत आसान होता है।
क्लाइंट में ब्लॉकिंग मोड UI के नुकसान - एक ब्लॉकिंग सॉकेट कॉल तब तक वापस नहीं आती जब तक कि यह अपना कार्य पूरा नहीं कर लेता। जब एप्लिकेशन के मुख्य थ्रेड पर ऐसी कॉल की जाती है, तो एप्लिकेशन उपयोगकर्ता संदेशों को संसाधित नहीं कर सकता है। इस वजह से, उपयोगकर्ता इंटरफ़ेस जमे हुए है, विंडोज़ अपडेट नहीं हैं, और अन्य संदेशों को तब तक संसाधित नहीं किया जा सकता है जब तक कि ब्लॉकिंग सॉकेट से नियंत्रण वापस नहीं किया जाता है।
टीआईडीएंटीफ्रीज घटक
इंडी में एक विशेष घटक है जो यूजर इंटरफेस को फ्रीज करने की समस्या को हल करता है। बस अपने एप्लिकेशन में कहीं भी एक TIdAntiFreeze घटक जोड़ें और आप उपयोगकर्ता इंटरफ़ेस को फ़्रीज़ किए बिना ब्लॉकिंग कॉल कर सकते हैं।
TIdAntiFreeze कॉल स्टैक के बाहर एक आंतरिक टाइमर पर चलता है और समय समाप्त होने पर Application.ProcessMessages को कॉल करता है। इंडी के लिए बाहरी कॉल ब्लॉक करना जारी रखते हैं और इसलिए ठीक उसी तरह काम करते हैं जैसे TIdAntiFreeze घटक का उपयोग किए बिना। TIdAntiFreeze का उपयोग करने से आप बिना नुकसान के सॉकेट्स को ब्लॉक करने के सभी फायदे प्राप्त कर सकते हैं।
कोड स्ट्रीम (थ्रेडिंग)
ब्लॉकिंग सॉकेट लगभग हमेशा कोडस्ट्रीम का उपयोग करते हैं। गैर-अवरुद्ध सॉकेट भी धाराओं का उपयोग कर सकते हैं, लेकिन इसके लिए कुछ अतिरिक्त प्रसंस्करण की आवश्यकता होती है और इस मामले में अवरुद्ध सॉकेट की तुलना में उनके लाभ खो जाते हैं।
थ्रेड्स के लाभ · प्राथमिकताएँ निर्धारित करना - अलग-अलग थ्रेड्स की प्राथमिकताओं को कॉन्फ़िगर किया जा सकता है। यह आपको अलग-अलग कार्यों के लिए कम या ज्यादा CPU समय आवंटित करने की अनुमति देता है। · एनकैप्सुलेशन - प्रत्येक कनेक्शन में किसी अन्य कनेक्शन के साथ एक इंटरफ़ेस की कुछ समानता हो सकती है। · सुरक्षा - प्रत्येक थ्रेड में अलग-अलग सुरक्षा विशेषताएँ हो सकती हैं। एकाधिक प्रोसेसर - एकाधिक प्रोसेसर वाले सिस्टम पर लाभ देता है। · क्रमांकन की कोई आवश्यकता नहीं - पूर्ण संगामिति प्रदान करता है। बहुत सारे थ्रेडिंग के बिना, सभी अनुरोधों को एक थ्रेड में संसाधित किया जाना चाहिए। इसलिए प्रत्येक कार्य को छोटे-छोटे टुकड़ों में तोड़ा जाना चाहिए ताकि वह तेजी से चल सके। जबकि एक ब्लॉक का निष्पादन किया जा रहा है, अन्य सभी को इसके पूरा होने की प्रतीक्षा करने के लिए मजबूर किया जाता है। एक ब्लॉक के अंत में, अगला ब्लॉक निष्पादित किया जाता है, और इसी तरह। मल्टीथ्रेडिंग के साथ, प्रत्येक कार्य को एक के रूप में प्रोग्राम किया जा सकता है और ऑपरेटिंग सिस्टम सभी कार्यों के बीच समय वितरित करता है।
थ्रेड पोलिंग
धागे बनाना और नष्ट करना बहुत संसाधन गहन है। यह उन सर्वरों के लिए विशेष रूप से कठिन कार्य है जिनके पास अल्पकालिक कनेक्शन हैं। प्रत्येक सर्वर एक थ्रेड बनाता है, इसे थोड़े समय के लिए उपयोग करता है, और फिर इसे नष्ट कर देता है। इसके परिणामस्वरूप थ्रेड्स का निर्माण और विलोपन बहुत बार होता है। इसका एक उदाहरण वेब सर्वर है। एक एकल अनुरोध भेजा जाता है और एक साधारण प्रतिक्रिया दी जाती है। वेब साइट ब्राउज़ करते समय ब्राउज़र का उपयोग करते समय सैकड़ों कनेक्शन और डिस्कनेक्शन हो सकते हैं।
मतदान सूत्र इस स्थिति को ठीक कर सकते हैं। मांग पर धागे बनाने और नष्ट करने के बजाय, पूल से अप्रयुक्त, लेकिन पहले से ही बनाए गए धागे की सूची से धागे का चयन किया जाता है। जब किसी धागे की जरूरत नहीं रह जाती है, तो उसे नष्ट होने के बजाय पूल में वापस कर दिया जाता है। पूल में थ्रेड्स को अप्रयुक्त के रूप में चिह्नित किया जाता है और इसलिए वे CPU समय का उपभोग नहीं करते हैं। और भी अधिक सुधार के लिए, धाराएं सिस्टम की वर्तमान जरूरतों के लिए गतिशील रूप से समायोजित हो सकती हैं।
इंडी थ्रेड पोलिंग का समर्थन करता है। इंडी में थ्रेड पूल TIdThreadMgrPool घटक के माध्यम से उपलब्ध है।
एकाधिक धागे
भारी लोड वाले सर्वर को सैकड़ों या हजारों थ्रेड्स की आवश्यकता हो सकती है। एक आम धारणा है कि सैकड़ों और हजारों धागे आपके सिस्टम को मार सकते हैं। यह गलत धारणा है।
अधिकांश सर्वरों में, थ्रेड डेटा की प्रतीक्षा कर रहे हैं। ब्लॉकिंग कॉल पर प्रतीक्षा करते समय, थ्रेड निष्क्रिय है। 500 थ्रेड वाले सर्वर में, एक ही समय में केवल 50 ही सक्रिय हो सकते हैं।
आपके सिस्टम पर चल रहे थ्रेड्स की संख्या आपको चौंका सकती है। सर्वरों की न्यूनतम संख्या और निर्दिष्ट के अनुसार चल रहे अनुप्रयोगों के साथ, मेरे सिस्टम में 333 थ्रेड्स बनाए गए हैं, यहां तक ​​कि 333 थ्रेड्स के साथ भी सीपीयू केवल 1% लोड है। एक भारी लोड आईआईएस (माइक्रोसॉफ्ट इंटरनेट सूचना सर्वर) सर्वर सैकड़ों या हजारों धागे बना सकता है।
धागे और वैश्विक खंड
एकाधिक थ्रेड्स के साथ, आपको उन्हें एक्सेस करते समय डेटा अखंडता सुनिश्चित करनी चाहिए। गैर-थ्रेड प्रोग्रामर के लिए यह मुश्किल हो सकता है। लेकिन, एक नियम के रूप में, अधिकांश सर्वरों को वैश्विक डेटा का उपयोग करने की आवश्यकता नहीं होती है। अधिकांश सर्वर पृथक कार्य करते हैं। प्रत्येक धागा अपना पृथक कार्य करता है। वैश्विक पठन/लेखन अनुभाग कई बहुप्रचारित अनुप्रयोगों की एक विशेषता है, लेकिन सर्वर के लिए विशिष्ट नहीं हैं।
कार्यप्रणाली इंडी
इंडी अन्य विंसॉक घटकों से अलग है जिसका आप उपयोग करते हैं। यदि आपने अन्य घटकों के साथ काम किया है, तो सबसे अच्छा उपाय यह है कि वे कैसे काम करते हैं, यह भूल जाएं। कई अन्य घटक गैर-अवरुद्ध (एसिंक्रोनस) कॉल का उपयोग करते हैं और अतुल्यकालिक रूप से संचालित होते हैं। उन्हें घटनाओं पर प्रतिक्रिया देने, एक राज्य मशीन बनाने और लगातार प्रतीक्षा लूप करने की आवश्यकता होती है।
उदाहरण के लिए, अन्य घटकों के साथ, जब आप किसी कनेक्शन को कॉल करते हैं, तो आपको या तो कनेक्शन ईवेंट के सक्रिय होने की प्रतीक्षा करनी चाहिए, या यह इंगित करने के लिए कि कनेक्शन हुआ है, प्रॉपर्टी के माध्यम से लूप करना चाहिए। इंडी के साथ, आप कनेक्ट विधि को कॉल कर सकते हैं और इसके वापस आने की उम्मीद कर सकते हैं। यदि कनेक्शन सफल होता है या कोई समस्या होने पर अपवाद फेंक दिया जाता है तो वापसी की जाएगी। इसलिए, इंडी के साथ काम करना फाइलों के साथ काम करने के समान ही है। इंडी आपको अपने सभी कोड को विभिन्न घटनाओं में फैलाने के बजाय एक ही स्थान पर रखने की अनुमति देता है। इसके अलावा, धागे के साथ काम करते समय इंडी बहुत सरल और सबसे सुविधाजनक है।
इंडी कितना अलग है
संक्षिप्त अवलोकन · अवरुद्ध कॉल का उपयोग करता है · घटना-उन्मुख नहीं - ईवेंट मौजूद हैं, लेकिन उनका उपयोग सूचना के उद्देश्यों के लिए किया जाता है, और वास्तव में इसकी आवश्यकता नहीं होती है। · थ्रेड्स के लिए डिज़ाइन किया गया - इंडी को थ्रेड्स के लिए डिज़ाइन किया गया है, हालाँकि इसे थ्रेड्स के बिना भी इस्तेमाल किया जा सकता है। अनुक्रमिक प्रोग्रामिंग
विस्तृत विचार
इंडी न केवल ब्लॉकिंग कॉल (सिंक्रोनस) का उपयोग करता है बल्कि इस तरह काम भी करता है। इंडी में एक विशिष्ट सत्र इस तरह दिखता है:
इंडी क्लाइंट के साथ शुरू करें
जुडिये; कोशिश करो
// अपना सामान यहां करें
अंत में डिस्कनेक्ट; समाप्त;
समाप्त;
अन्य घटकों के साथ यह इस तरह दिखता है:
प्रक्रिया TFormMain.TestOnClick (प्रेषक: TComponent);
शुरू
सॉकेटकंपोनेंट के साथ शुरू करें
जुडिये; कोशिश करो
कनेक्ट नहीं होने पर शुरू करें
अगर IsError तो शुरू करें
गर्भपात;
समाप्त;

आउटडाटा: = "डेटा भेजने के लिए";
जबकि लंबाई (आउटडाटा)> 0 शुरू करें
आवेदन। प्रक्रिया संदेश;
समाप्त;
अंत में डिस्कनेक्ट; समाप्त;
समाप्त;
समाप्त;
प्रक्रिया TFormMain.OnConnectError;
शुरू
इसरर: = सच;
समाप्त;
प्रक्रिया TFormMain.OnRead;
वर
मैं: पूर्णांक;
शुरू
i:= SocketComponent.Send(OutData);
आउटडाटा: = कॉपी (आउटडाटा, आई + 1, मैक्सइंट);
समाप्त;
कई घटक प्रोग्रामर को स्टैक से अलग करने का बहुत अच्छा काम नहीं करते हैं। कई घटक, उपयोगकर्ता को स्टैक की जटिलताओं से अलग करने के बजाय, उपयोगकर्ता को अकेला छोड़ देते हैं या स्टैक के ऊपर एक आवरण प्रदान करते हैं।
इंडी का विशेष पथ
इंडी को जमीन से ऊपर तक बहु-थ्रेडेड होने के लिए डिज़ाइन किया गया है। इंडी में सर्वर और क्लाइंट बनाना यूनिक्स में सर्वर और क्लाइंट बनाने के समान है। यूनिक्स एप्लिकेशन आमतौर पर स्टैक को सीधे कॉल करते हैं जिसमें बहुत कम या कोई अमूर्त परत नहीं होती है।
आम तौर पर, यूनिक्स सर्वर में एक या अधिक श्रोता प्रक्रियाएं होती हैं जो आने वाले क्लाइंट अनुरोधों को सुनती हैं। प्रत्येक ग्राहक के लिए जिसे सेवा की आवश्यकता होती है, एक नई प्रक्रिया बनाई जाती है। यह प्रोग्रामिंग को सरल बनाता है, प्रत्येक प्रक्रिया केवल एक क्लाइंट के लिए होती है। प्रत्येक प्रक्रिया अपने स्वयं के सुरक्षा संदर्भ में चलती है, जो सुनने की प्रक्रिया या मौजूदा अधिकारों, पहचान या अन्य चीजों पर आधारित प्रक्रिया द्वारा निर्धारित होती है।
इंडी सर्वर काफी हद तक उसी तरह काम करते हैं। विंडोज, यूनिक्स के विपरीत, प्रक्रियाओं को अच्छी तरह से प्रचारित नहीं कर सकता है, लेकिन यह थ्रेड्स के साथ अच्छी तरह से काम करता है। इंडी सर्वर प्रत्येक क्लाइंट कनेक्शन के लिए एक अलग थ्रेड बनाते हैं।
इंडी सर्वर एक लिसनिंग थ्रेड असाइन करते हैं जो प्रोग्राम के मुख्य कोड स्ट्रीम से अलग होता है। सुनने वाला धागा ग्राहकों से आने वाले अनुरोधों को सुनता है। प्रत्येक क्लाइंट के लिए यह प्रतिक्रिया करता है, क्लाइंट की सेवा के लिए एक नया थ्रेड बनाया जाता है। संबंधित घटनाओं को तब उस धागे के संदर्भ में सेवित किया जाता है।
इंडी ग्राहक अवलोकन
इंडी को उच्च स्तर की अमूर्तता प्रदान करने के लिए डिज़ाइन किया गया है। टीसीपी/आईपी स्टैक की जटिलता और विवरण प्रोग्रामर से छिपा हुआ है। इंडी में एक विशिष्ट क्लाइंट सत्र आमतौर पर इस तरह दिखता है:
इंडी क्लाइंट के साथ शुरू करें
होस्ट: = "zip.pbe.com"; // कॉल करने के लिए होस्ट
पोर्ट: = 6000; // सर्वर पर कॉल करने के लिए पोर्ट
जुडिये; कोशिश करो
// अपना सामान यहां करें
अंत में डिस्कनेक्ट; समाप्त;
समाप्त;
इंडी सर्वर का अवलोकन
इंडी सर्वर घटक एक सुनने वाला धागा बनाते हैं जो प्रोग्राम के मुख्य कोड थ्रेड से अलग होता है। सुनने वाला धागा ग्राहकों से आने वाले अनुरोधों को सुनता है। प्रत्येक क्लाइंट के लिए यह प्रतिक्रिया करता है, क्लाइंट की सेवा के लिए एक नया थ्रेड बनाया जाता है। संबंधित घटनाओं को तब उस धागे के संदर्भ में सेवित किया जाता है।

व्यावहारिक उदाहरण
निम्नलिखित उदाहरणों से आपको सरल उपयोग के लिए घटकों के साथ आरंभ करने में मदद मिलेगी, लेकिन उदाहरणों को प्रदर्शित करने के उद्देश्य से सरल अनुप्रयोगों के रूप में बनाया गया है। कुछ परियोजनाओं को विभिन्न स्थितियों को प्रदर्शित करने के लिए बनाया जाता है। ये उदाहरण ज़िप फ़ाइलों के रूप में डाउनलोड के लिए भी उपलब्ध हैं।
अनुवादक का नोट: साइट पर लिंक काम नहीं कर रहा है।
उदाहरण 1 - पोस्टकोड चेक
पहली परियोजना को यथासंभव सरल बनाया गया है। ज़िप कोड द्वारा खोजें, क्लाइंट सर्वर से पूछता है कि निर्दिष्ट ज़िप कोड किस शहर और राज्य से संबंधित है।
उन लोगों के लिए जो यूएस से बाहर रहते हैं और नहीं जानते कि ज़िप कोड क्या है, यह एक डाक कोड है जो डिलीवरी के स्थान को इंगित करता है। पोस्टल कोड में 5 अंक होते हैं।
शिष्टाचार
सर्वर और क्लाइंट के निर्माण में पहला कदम प्रोटोकॉल विकास है। मानक प्रोटोकॉल के लिए, यह संबंधित RFC द्वारा परिभाषित किया गया है। डाक कोड के लिए, प्रोटोकॉल नीचे परिभाषित किया गया है।
अधिकांश एक्सचेंज प्रोटोकॉल टेक्स्ट मोड में काम करते हैं। एक एक्सचेंज का मतलब है कि एक कमांड भेजा गया है, और प्रतिक्रिया राज्य और संभवतः डेटा है। प्रोटोकॉल केवल विनिमय तक सीमित नहीं हैं, लेकिन सादा पाठ अभी भी उपयोग किया जाता है। डाक कोड निर्धारित करने का प्रोटोकॉल भी टेक्स्ट है। सादा पाठ प्रोटोकॉल को डिबग करना आसान बनाता है और विभिन्न प्रोग्रामिंग भाषाओं और ऑपरेटिंग सिस्टम को संचार करने की अनुमति देता है।
कनेक्ट करने के बाद, सर्वर एक हैलो संदेश भेजता है, फिर कमांड को स्वीकार करता है। यह आदेश "ज़िपकोड x" (जहाँ x ज़िप कोड है) या "छोड़ें" हो सकता है। ZipCode कमांड के जवाब में, जवाब के साथ सिंगल लाइन के रूप में एक रिस्पॉन्स भेजा जाता है, या कोड नहीं मिलने पर एक खाली लाइन के रूप में भेजा जाता है। छोड़ो आदेश सर्वर को कनेक्शन समाप्त करने का कारण बनता है। क्विट कमांड भेजे जाने से पहले सर्वर कई कमांड स्वीकार कर सकता है।
सर्वर स्रोत कोड

यूनिटसर्वरमेन;

इंटरफेस

उपयोग

प्रकार

TformMain = वर्ग (TForm)

आईडीटीसीपीसर्वर1: टीआईडीटीसीपीसर्वर;

प्रक्रिया फॉर्मक्रिएट (प्रेषक: टॉब्जेक्ट);

प्रक्रिया फॉर्मडेस्ट्रॉय (प्रेषक: टॉब्जेक्ट);

प्रक्रिया IdTCPServer1Connect (एथ्रेड: TIdPeerThread);

निजी

ZipCodeList: TStrings;

जनता

समाप्त ;

फॉर्ममेन: टीफॉर्ममेन;

कार्यान्वयन

(आर *। डीएफएम)

प्रक्रिया TformMain.IdTCPServer1Connect (एथ्रेड: TIdPeerThread);

शुरू

AThread.Connection .WriteLn ("इंडी ज़िप कोड सर्वर तैयार है।");

समाप्त ;

SCommand: स्ट्रिंग;

शुरू

SCommand:= ReadLn;

समाप्त ;

समाप्त ;

समाप्त ;

प्रक्रिया TformMain.FormCreate (प्रेषक: टॉब्जेक्ट);

शुरू

ZipCodeList:= TStringList.Create;

ZipCodeList.LoadFromFile (ExtractFilePath (Application.EXEName) + "ZipCodes.dat");

समाप्त ;

प्रक्रिया TformMain.FormDestroy (प्रेषक: टॉब्जेक्ट);

शुरू

ZipCodeList.Free ;

समाप्त ;

समाप्त।

प्रोजेक्ट में केवल इंडी-विशिष्ट भाग IdTCPServer1 घटक, IdTCPServer1Connect और IdTCPServer1Execute विधियाँ हैं।
प्रपत्र में TIdTCPServer प्रकार का IdTCPServer1 घटक है। निम्नलिखित गुण बदल दिए गए हैं: सक्रिय = सत्य - आवेदन शुरू होने के बाद, सर्वर सुनता है। · डिफॉल्टपोर्ट = 6000 - इस परियोजना के लिए पोर्ट मूल्य। सर्वर इस पोर्ट पर क्लाइंट के अनुरोधों को सुनता है।
IdTCPServer1Execute विधि सर्वर के OnExecute ईवेंट से संबद्ध है। क्लाइंट कनेक्शन स्वीकार किए जाने के बाद OnExecute ईवेंट सक्रिय हो जाता है। OnExecute ईवेंट आपके द्वारा ज्ञात अन्य ईवेंट से भिन्न है। OnExecute को थ्रेड के संदर्भ में निष्पादित किया जाता है। थ्रेड इवेंट को निकाल दिया जाता है और विधि को दिए गए एथ्रेड तर्क को पास कर दिया जाता है। यह महत्वपूर्ण है क्योंकि एक ही समय में एकाधिक OnExecute ईवेंट निष्पादित हो सकते हैं। ऐसा इसलिए किया जाता है ताकि सर्वर एक नया कंपोनेंट बनाए बिना काम कर सके। ऐसे तरीके भी हैं जिन्हें वंशज बनाते समय ओवरराइड किया जा सकता है।
कनेक्शन स्वीकार किए जाने के बाद ऑनकनेक्ट घटना को निकाल दिया जाता है और इसके लिए एक धागा बनाया जाता है। यह सर्वर क्लाइंट को एक हैलो संदेश भेजने के लिए इसका उपयोग करता है। यह वांछित होने पर OnExecute ईवेंट में भी किया जा सकता है।
कनेक्शन डिस्कनेक्ट या खो जाने तक OnExecute ईवेंट कई बार सक्रिय हो सकता है। यह घटना के भीतर लूप में डिस्कनेक्शन या हानि के लिए कनेक्शन की जांच करने की आवश्यकता को समाप्त करता है।
IdTCPServer1Execute दो बुनियादी कार्यों, ReadLn और WriteLn का उपयोग करता है। ReadLn कनेक्शन से एक लाइन पढ़ता है, और WriteLn कनेक्शन को लाइन भेजता है।
sCommand:= ReadLn;
उपरोक्त कोड क्लाइंट से एक स्ट्रिंग लेता है और इसे स्थानीय स्ट्रिंग वेरिएबल sCommand में डालता है।

अगर SameText (sCommand, "QUIT") तो start

अंत में अगर SameText (कॉपी (sCommand, 1, 8), "ZipCode") तो शुरू करें

WriteLn (ZipCodeList.Values ​​​​[प्रतिलिपि (sCommand, 9, MaxInt)]);

समाप्त ;


इसके बाद, मान्य आदेशों के लिए sCommand की जाँच की जाती है।
यदि आदेश "छोड़ो" है तो एक डिस्कनेक्ट किया जाता है। डिस्कनेक्ट के बाद पढ़ने या लिखने की अनुमति नहीं है। घटना समाप्त होने के बाद, सुनने वाला धागा अब इसे कॉल नहीं करता है, लेकिन धागे को साफ करता है और कनेक्शन को समाप्त करता है।
यदि कमांड "ज़िपकोड" है, तो कमांड के बाद के पैरामीटर को निकाला जाता है और तालिका को शहर और राज्य की उपस्थिति के लिए देखा जाता है। शहर और राज्य तब क्लाइंट को पास कर दिए जाते हैं, या कोई मेल नहीं होने पर एक खाली स्ट्रिंग पास की जाती है।
फिर विधि निकल जाती है। जैसे ही एक नया कमांड आता है, सर्वर फिर से ईवेंट को फिर से उठाएगा, जिससे क्लाइंट को कई कमांड भेजने की अनुमति मिलती है।
ग्राहक स्रोत कोड

यूनिट क्लाइंटमेन;

इंटरफेस

उपयोग

विंडोज, संदेश, SysUtils, कक्षाएं, ग्राफिक्स, नियंत्रण, प्रपत्र, संवाद,

StdCtrls, ExtCtrls, IdAntiFreezeBase,

IdAntiFreeze, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;

प्रकार

TformMain = वर्ग (TForm)

क्लाइंट: TIdTCP क्लाइंट;

IdAntiFreeze1: TIdAntiFreeze;

पैनल1: टीपीनल;

पैनल 2: टीपीनल;

मेमो इनपुट: टीएममो;

एलबॉक्स परिणाम: टीएलिस्टबॉक्स;

पैनल 3: टीपीनल;

बटन 1: टीबीटन;

बटन 2: टीबीटन;

लेबल1: टी लेबल;

प्रक्रिया Button2Click (प्रेषक: टॉब्जेक्ट);

प्रक्रिया बटन 1 क्लिक करें (प्रेषक: टॉब्जेक्ट);

निजी

जनता

समाप्त ;

फॉर्ममेन: टीफॉर्ममेन;

कार्यान्वयन

(आर *। डीएफएम)

प्रक्रिया TformMain.Button2Click (प्रेषक: टॉब्जेक्ट);

शुरू

मेमो इनपुट। साफ़ करें;

LboxResults.Clear;

समाप्त ;

प्रक्रिया TformMain.Button1Click (प्रेषक: टॉब्जेक्ट);

मैं: पूर्णांक;

एस: स्ट्रिंग

शुरू

ButnLookup.Enabled := true ; कोशिश करो

LboxResults.Clear;

क्लाइंट के साथ शुरू करें

जुडिये; कोशिश करो

LboxResults.Items .Add (ReadLn);

i:= 0 to memoInput.Lines .Count - 1 do start

WriteLn ("ज़िपकोड" + memoInput.Lines [i]);

LboxResults.Items .Add(memoInput.Lines[i]);

एस: = रीडएलएन;

अगर s = "" तो शुरू करें

एस:= "-- इस ज़िप कोड के लिए कोई प्रविष्टि नहीं मिली।";

समाप्त ;

LboxResults.Items .Add(s);

LboxResults.Items .Add ("");

समाप्त ;

राइटलेन ("छोड़ो");

अंत में डिस्कनेक्ट; समाप्त ;

समाप्त ;

अंत में butnLookup.Enabled := true ; समाप्त ;

समाप्त ;

समाप्त।


क्लाइंट घटक के लिए केवल विशिष्ट भाग Button1Click विधि हैं।
क्लाइंट घटक TIdTCPClient प्रकार का है और इसे प्रपत्र पर रखा गया है। निम्नलिखित गुण बदल दिए गए हैं: होस्ट = 127.0.0.1 - सर्वर क्लाइंट के समान मशीन पर स्थित है। पोर्ट = 6000 - सर्वर पोर्ट
Button1Click विधि Button1 घटक के ऑनक्लिक ईवेंट से संबद्ध है। जब बटन पर क्लिक किया जाता है, तो इस विधि को कहा जाता है। इस पद्धति के इंडी भाग को निम्न में घटाया जा सकता है: 1. सर्वर से कनेक्ट करना (कनेक्ट;) 1. सर्वर से हैलो पढ़ना। 1. TMemo में उपयोगकर्ता द्वारा दर्ज की गई प्रत्येक पंक्ति के लिए: 1. सर्वर को एक अनुरोध भेजना (WriteLn("ZipCode" + memoInput. Lines[i]);) 1. सर्वर से प्रतिक्रिया पढ़ना (s:= ReadLn; ) 1. Quit कमांड भेजना (WriteLn("Quit");) 1. डिस्कनेक्ट (डिस्कनेक्ट;)
परिक्षण
इस उदाहरण का परीक्षण किया गया है और यह स्थापित टीसीपी/आईपी के साथ काम करता है। आप इसे एक कंप्यूटर से दूसरे कंप्यूटर पर नेटवर्क पर काम करने के लिए बदल सकते हैं। सर्वर को दूसरे कंप्यूटर पर शुरू करके और क्लाइंट पर सर्वर का नाम या आईपी बदलकर।
परियोजनाओं का परीक्षण करने के लिए, सर्वर को संकलित करें और चलाएं। फिर क्लाइंट को संकलित और चलाएं। ज्ञापन क्षेत्र में ज़िप कोड दर्ज करें और लुकअप कुंजी दबाएं।
डिबगिंग
टेक्स्ट प्रोटोकॉल डिबग करना बहुत आसान है क्योंकि उन्हें टेलनेट के साथ चेक किया जा सकता है। ऐसा करने के लिए, सर्वर पोर्ट को जानना पर्याप्त है। ज़िप कोड लुकअप सर्वर पोर्ट 6000 पर सुन रहा है।
ज़िप कोड लुकअप सर्वर फिर से प्रारंभ करें। फिर एक कंसोल खोलें (उदाहरण के लिए, एक डॉस विंडो)। अब दर्ज करें:
टेलनेट 127.0.0.1 6000
अब आप सर्वर से जुड़े हैं। कुछ सर्वर एक हैलो संदेश भी भेजते हैं। कुछ नहीं। आपके द्वारा दर्ज की गई पंक्तियाँ आपको दिखाई नहीं देंगी। ट्रैफ़िक बचाने के लिए अधिकांश सर्वर प्रतिध्वनित नहीं होते हैं। हालाँकि, आप "इको ऑन" विकल्प सेट करके टेलनेट सेटिंग्स को बदल सकते हैं। अलग-अलग टेलनेट क्लाइंट में यह अलग-अलग तरीकों से किया जाता है, और उनमें से कई के पास ऐसा अवसर बिल्कुल भी नहीं होता है। अब दर्ज करें:
पिन कोड 37642
आप सर्वर प्रतिक्रिया देखेंगे:
चर्च हिल, तमिलनाडु
सर्वर से डिस्कनेक्ट करने के लिए, दर्ज करें:
छोड़ना
उदाहरण 2 - डेटाबेस एक्सेस
यह उदाहरण एक सर्वर का अनुकरण करता है जिसे सॉकेट कॉल के अलावा अन्य ब्लॉकिंग कार्य करना चाहिए। कई सर्वर ऐसे हालात में काम करने को मजबूर हैं। सर्वर जिन्हें डेटाबेस एक्सेस, बाहरी प्रक्रिया कॉल या गणना की आवश्यकता होती है, वे अक्सर इन कॉलों को बाधित नहीं कर सकते क्योंकि वे बाहरी कॉल हैं या ऐसा करने की जटिलता के कारण। बेस कॉल को छोटे टुकड़ों में नहीं तोड़ा जा सकता है और डेवलपर को बेस ऑपरेशन खत्म होने तक इंतजार करना चाहिए। यह न केवल डेटाबेस एक्सेस की विशेषता है, बल्कि अन्य संचालन जैसे कि संपीड़न, गणना और उसी तरह के अन्य प्रसंस्करण की भी विशेषता है।
प्रदर्शन के प्रयोजनों के लिए, मान लें कि सर्वर एक डेटाबेस कॉल करता है जिसे पूरा होने में 5 सेकंड लगते हैं। सरल बनाने के लिए, आइए इसे एक विराम के साथ करें, इसके लिए स्लीप (5000) फ़ंक्शन का उपयोग करें, वास्तव में कॉल करने के बजाय।
इस उदाहरण में भी पिछले उदाहरण की तुलना में कम विवरण की आवश्यकता है क्योंकि कई अवधारणाएं अभी तक समझ में नहीं आई हैं।
स्रोत

इकाई मुख्य;

इंटरफेस

उपयोग

विंडोज, संदेश, SysUtils, कक्षाएं, ग्राफिक्स, नियंत्रण, प्रपत्र, संवाद,

IdBaseComponent, IdComponent, IdTCPServer;

प्रकार

TformMain = वर्ग (TForm)

आईडीटीसीपीसर्वर1: टीआईडीटीसीपीसर्वर;

प्रक्रिया IdTCPServer1Execute(AThread: TIdPeerThread);

निजी

जनता

समाप्त ;

फॉर्ममेन: टीफॉर्ममेन;

कार्यान्वयन

(आर *। डीएफएम)

प्रक्रिया TformMain.IdTCPServer1Execute (एथ्रेड: TIdPeerThread);

मैं: पूर्णांक;

शुरू

AThread.Connection के साथ प्रारंभ करें

WriteLn ("हैलो। डीबी सर्वर तैयार है।");

I:= StrToIntDef (ReadLn , 0 );

// नींद को एक लंबी डीबी या अन्य कॉल के लिए प्रतिस्थापित किया जाता है

नींद (5000);

WriteLn (IntToStr (i * 7));

समाप्त ;

समाप्त ;

समाप्त।

चूंकि निष्पादन घटना थ्रेड के संदर्भ में होती है, इसलिए प्रोसेसिंग कोड किसी भी लम्बाई का हो सकता है। प्रत्येक क्लाइंट का अपना थ्रेड होता है और अन्य क्लाइंट को ब्लॉक नहीं करता है।
परिक्षण
डीबी सर्वर का परीक्षण करने के लिए, इसे संकलित करें और चलाएं। पोर्ट 6001 पर टेलनेट का उपयोग करके इसे कनेक्ट करें। सर्वर एक हैलो संदेश के साथ प्रतिक्रिया देगा। एक नंबर दर्ज करें। सर्वर आपके अनुरोध को "प्रोसेस" करेगा और 5 सेकंड में जवाब देगा।

नमस्कार!

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

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

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

तो कार्यक्रम सरल है। इसे POST विधि का उपयोग करके सर्वर को डेटा भेजना होगा, डेटा में " हैडर " (रेखा), " विवरण » (बहु-पंक्ति पाठ) और एक ग्राफिक फ़ाइल (jpg, png, gif-बाइनरी डेटा)। सर्वर को इस डेटा को स्वीकार करना चाहिए, इसे संसाधित करना चाहिए, ग्राफिक फ़ाइल को सर्वर पर संग्रहीत करना चाहिए, और एक प्रतिक्रिया वापस करनी चाहिए। प्रतिक्रिया के रूप में, हम डेल्फी को एप्लिकेशन पर वापस कर देंगे, वही टेक्स्ट केवल लेबल जोड़ने और डाउनलोड की गई फ़ाइल के लिंक के साथ। और अधिक कुछ नहीं।

आइए सर्वर भाग (वेबसाइट एपीआई के समान) के कार्यान्वयन के साथ शुरू करें। कोई भी टेक्स्ट एडिटर (नोटपैड) खोलें और उसमें निम्नलिखित कोड लिखें:

"; ) और (गूंज "हैडर: गुम है।"
"; ) // "सामग्री" फ़ील्ड डेटा की उपस्थिति के लिए आने वाले डेटा की जाँच करें यदि (!खाली($_POST["सामग्री"]))(echo "Content:".$_POST["content"]."
"; ) और (गूंज "सामग्री: कोई नहीं।"
"; ) // संलग्न फ़ाइल "फ़ाइल" की उपस्थिति के लिए आने वाले डेटा की जाँच करें यदि (!खाली($_FILES["file"])) ($finfo = pathinfo($_FILES["file"]["name" ]); // फ़ाइल के बारे में जानकारी प्राप्त करें (नाम, एक्सटेंशन, आदि) // अनुमत प्रकारों की सूची में फ़ाइल प्रकार की जाँच करें (सुधार :)) )==0)(गूंज ">>>>>>> अमान्य फ़ाइल प्रकार<<<<<<<<"; exit; //Если не допустим тип, полностью останавливаем скрипт } $fname = "files/" . "testimgfile." . $finfo["extension"]; //формируем путь и новое имя файла move_uploaded_file($_FILES["file"]["tmp_name"],$fname);//сохраняем временный файл "tmp_name" в файл $fname echo "http://".$_SERVER["HTTP_HOST"]."/".$fname; //возвращаем полный путь к файлу } ?>

ध्यान दें! सहेजते समय (नोटपैड के माध्यम से), आपको "UTF-8" एन्कोडिंग निर्दिष्ट करनी होगी, अन्यथा सिरिलिक को प्रदर्शित करने में समस्या होगी!

स्क्रिप्ट ने विस्तृत टिप्पणियां प्रदान करने का प्रयास किया। इस स्क्रिप्ट को अपने वेब सर्वर पर कॉपी करें, यदि कोई नहीं है, तो आप परीक्षण के लिए मेरी स्क्रिप्ट का उपयोग कर सकते हैं, यह यहां स्थित है: http://api.php

लेआउट निम्नलिखित घटकों का उपयोग करता है: लेबल, बटन (2 पीसी), संपादित करें (2 पीसी), मेमो (2 पीसी), चेकबॉक्स, ओपनडिअलॉग, आईडीएचटीटीपी। निम्नलिखित घटकों के नाम लिखिए (संपत्ति “ नाम”):

  1. संपादित करें (शीर्षक) - नाम = शीर्षक;
  2. संपादित करें (फ़ाइल का पथ) नाम = आईएमजीफाइल;
  3. मेमो (सामग्री)नाम = सामग्री;
  4. मेमो (परिणाम) - नाम = प्रतिक्रिया;
  5. बटन (...) - नाम = chkfile;
  6. बटन (पोस्ट) नाम = पोस्टबट;
  7. OpenDialog (फ़ाइल चयन संवाद) - नाम = PicDialog;

हम IdHTTP1 और CheckBox1 को अपरिवर्तित छोड़ देंगे (थक गए! :)))।

गलती से नहीं करने के लिए संपादित करें» संपादित करने के लिए पथ ( imgfile), इसकी केवल पढ़ने योग्य संपत्ति को सही पर सेट करें। इसी तरह, अत imgfileऔर chkfileसक्षम संपत्ति को गलत पर सेट करें। हम उन्हें चेकबॉक्स का उपयोग करके सक्रिय करेंगे अर्थात। आइए यह चुनने का विकल्प दें कि छवि अपलोड करना है या नहीं।

ओपनडिअलॉग के लिए ( चित्रसंवाद) आपको फ़िल्टर (फ़िल्टर प्रॉपर्टी) को निम्नानुसार सेट करना होगा:

वास्तव में दृश्य तैयारी समाप्त हो गई है! आइए कोडिंग शुरू करें!

प्रोजेक्ट में, हम इंडी के साथ आने वाले प्रकार का उपयोग करके डेटा प्रवाह बनाएंगे - TidMultiPartFormDataStream.हालांकि मुझे टीस्ट्रीम पर कार्यान्वयन विकल्प मिले, लेकिन साथ काम कर रहा था TidMultiPartFormDataStream -सरल!

इस प्रकार को हमारी परियोजना के लिए उपलब्ध कराने के लिए, हमें निम्नलिखित पुस्तकालय को उपयोग में जोड़ना होगा: IdMultipartFormData.

CheckBox1 के लिए, एक ऑनक्लिक ईवेंट बनाएं (ऑब्जेक्ट पर डबल क्लिक करके) और इस ईवेंट में निम्न कोड जोड़ें:

प्रक्रिया TForm1.CheckBox1Click (प्रेषक: टॉब्जेक्ट); start // फ़ाइल पथ और संवाद बटन के सक्रिय या निष्क्रिय तत्व बनाएं imgfile.Enabled:=CheckBox1.checked; chkfile.Enabled:=CheckBox1.checked; समाप्त;

यहां हम वस्तुओं को सक्रिय करते हैं imgfile औरchkfileचेकमार्क की उपस्थिति के आधार पर (यदि चेकबॉक्स चेक किया गया है, तो ऑब्जेक्ट सक्रिय हो जाते हैं)।

अब छवि चयन को व्यवस्थित करते हैं। ऐसा करने के लिए, बटन पर एक ऑनक्लिक ईवेंट बनाएं chkfile(ऑब्जेक्ट पर डबल क्लिक करके भी) और निम्नलिखित लिखें:

प्रक्रिया TForm1.chkfileClick (प्रेषक: टॉब्जेक्ट); start//संवाद खोलें और imgfile(TEDIT) में फ़ाइल का पूरा पथ दर्ज करें यदि PictDialog.Execute तब imgfile.Text:= PictDialog.FileName; समाप्त;

यह घटना एक छवि चयन संवाद को ट्रिगर करेगी और यदि उपयोगकर्ता क्लिक करता है " खुला हुआ”, फिर इस फ़ाइल का पथ इसमें जोड़ा जाएगा imgfile.

और अब हम अंतिम “POST” बटन पर आते हैं। इस बटन के लिए एक ऑनक्लिक घटना बनाएं और निम्नलिखित कोड जोड़ें:

प्रक्रिया TForm1.PostbutClick (प्रेषक: टॉब्जेक्ट); var डेटापोस्ट:TIdMultiPartFormDataStream; डेटा शुरू करेंपोस्ट:=TIdMultiPartFormDataStream.Create; dataPost.AddFormField("title",title.Text,"utf-8").ContentTransfer:= "8bit"; dataPost.AddFormField("content",content.Text,"utf-8").ContentTransfer:= "8bit"; अगर CheckBox1.checked और (trim(imgfile.Text)="") तो // जांचें कि क्या कोई फ़ाइल चुनी गई है या नहीं ShowMessage ("आपको एक ग्राफिक फ़ाइल का चयन करना होगा!"); बाहर जाएं; समाप्त; अगर CheckBox1. Checked तो dataPost.AddFile("file",imgfile.Text,""); // फ़ाइल प्रतिक्रिया के साथ फ़ील्ड जोड़ें। टेक्स्ट: = स्ट्रिंग रिप्लेस (idHTTP1.Post ("http://api..php", डेटापोस्ट), "
",#13#10,); डेटापोस्ट। नि: शुल्क; समाप्त;

तो, क्रम में (हालांकि टिप्पणियां हैं):

डाटापोस्ट - प्रकार की वस्तु TIdMultiPartFormDataStream. आपको विभिन्न प्रकार के क्षेत्रों से युक्त एक POST अनुरोध संरचना बनाने की अनुमति देता है।

डेटा पोस्ट . AddFormField (" शीर्षक ", शीर्षक . मूलपाठ ," यूटीएफ -8 "). सामग्री स्थानांतरण := " 8 अंश "; - डेटापोस्ट में "शीर्षक" नामक एक फ़ील्ड जोड़ता है, "शीर्षक। टेक्स्ट" से मान, प्रेषित डेटा के एन्कोडिंग को "utf-8" पर सेट करता है (पैरामीटर की आवश्यकता नहीं है, लेकिन इसे स्पष्ट रूप से निर्दिष्ट किए बिना, सिरिलिक वर्णमाला प्रश्न चिह्न "?") और एक बहुत ही महत्वपूर्ण विधि "ContentTransfer" के साथ प्रेषित होती है। इस पद्धति के बिना, सर्वर को डेटा भेजा जाता है" मंत्र". कृपया ध्यान दें कि संचारण पक्ष पर फ़ील्ड का नाम ("शीर्षक") स्क्रिप्ट में निर्दिष्ट नाम से मेल खाना चाहिए: $_POST["शीर्षक"]।

इसी तरह, डेटा "सामग्री" फ़ील्ड में प्रसारित किया जाता है।

डेटा पोस्ट . फाइल जोड़िए (" फ़ाइल ", imgfile . मूलपाठ ,"") - इस लाइन के साथ हम एक फाइल से डेटा के साथ एक स्ट्रीम बनाते हैं।

सब कुछ, डेटा उत्पन्न होता है, इसे सर्वर पर स्क्रिप्ट में स्थानांतरित करने और प्रतिक्रिया प्राप्त करने के लिए रहता है:

response.Text:= StringReplace(idHTTP1.Post("http://api..php",dataPost),"
",#13#10,);

इसलिये TMemo लाइन ब्रेक टैग को नहीं समझता है"
"", हम "" फ़ंक्शन का उपयोग इसे समझने योग्य लाइन ब्रेक वर्णों "#13#10" से बदलने के लिए करेंगे।

सब कुछ पूरा होने पर, हम डेटापोस्ट ऑब्जेक्ट से मेमोरी को लाइन के साथ साफ़ करते हैं:

डाटापोस्ट मुक्त;

हालांकि हमारे उदाहरण में यह प्रक्रिया के अंत में स्वचालित रूप से होगा, लेकिन फिर भी ...

असल में स्क्रीन पर प्रोग्राम का नतीजा:

इस प्रकार, हम सर्वर पर कोई भी डेटा, फाइल भेज सकते हैं, सर्वर पर इस डेटा को संसाधित कर सकते हैं और एप्लिकेशन को प्रतिक्रिया के साथ स्क्रिप्ट निष्पादन का परिणाम बता सकते हैं। यह सिर्फ 0 या 1 भी हो सकता है, जो एप्लिकेशन को आगे प्रतिक्रिया करने के लिए संकेत देगा।

हर चीज़। आप सभी को शुभकामनायें। मुझे आशा है कि जानकारी उपयोगी थी और आपको यह उपयोगी लगेगी।

तैयार उदाहरण और स्क्रिप्ट जिसे आप डाउनलोड कर सकते हैं।

पूर्ण मॉड्यूल कोड:

यूनिट पोस्टयूनिट; इंटरफ़ेस Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, का उपयोग करता है। IdHTTP, IdMultipartFormData, Vcl.ExtDlgs; टाइप करें TForm1 = वर्ग (TForm) IdHTTP1: TIdHTTP; शीर्षक: टीईडीआईटी; सामग्री: टीएममो; पोस्टबट: टीबीटन; प्रतिक्रिया: टीएममो; लेबल1: टी लेबल; लेबल 2: टी लेबल; लेबल3: टी लेबल; imgfile: टीईडीआईटी; chkfile: टीबीटन; लेबल4: टी लेबल; चेकबॉक्स 1: टीचेकबॉक्स; PictDialog: TOpenDialog; प्रक्रिया पोस्टबटक्लिक (प्रेषक: टॉब्जेक्ट); प्रक्रिया chkfileClick (प्रेषक: टॉब्जेक्ट); प्रक्रिया CheckBox1Click (प्रेषक: टॉब्जेक्ट); निजी (निजी घोषणाएँ) सार्वजनिक (सार्वजनिक घोषणाएँ) समाप्त; वर प्रपत्र1: TForm1; कार्यान्वयन ($R *.dfm) प्रक्रिया TForm1.CheckBox1Click(प्रेषक: टॉब्जेक्ट); start // फ़ाइल पथ और संवाद बटन के सक्रिय या निष्क्रिय तत्व बनाएं imgfile.Enabled:=CheckBox1.checked; chkfile.Enabled:=CheckBox1.checked; समाप्त; प्रक्रिया TForm1.chkfileClick (प्रेषक: टॉब्जेक्ट); start//संवाद खोलें और imgfile(TEDIT) में फ़ाइल का पूरा पथ दर्ज करें यदि PictDialog.Execute तब imgfile.Text:= PictDialog.FileName; समाप्त; प्रक्रिया TForm1.PostbutClick (प्रेषक: टॉब्जेक्ट); var डेटापोस्ट:TIdMultiPartFormDataStream; डेटा शुरू करेंपोस्ट:=TIdMultiPartFormDataStream.Create; dataPost.AddFormField("title",title.Text,"utf-8").ContentTransfer:= "8bit"; dataPost.AddFormField("content",content.Text,"utf-8").ContentTransfer:= "8bit"; अगर CheckBox1.checked और (trim(imgfile.Text)="") तो // जांचें कि क्या कोई फ़ाइल चुनी गई है या नहीं ShowMessage ("आपको एक ग्राफिक फ़ाइल का चयन करना होगा!"); बाहर जाएं; समाप्त; अगर CheckBox1. Checked तो dataPost.AddFile("file",imgfile.Text,""); // फ़ाइल प्रतिक्रिया के साथ फ़ील्ड जोड़ें। टेक्स्ट: = स्ट्रिंग रिप्लेस (idHTTP1.Post ("http://api..php", डेटापोस्ट), "
",#13#10,); डेटापोस्ट। नि: शुल्क; अंत; अंत।

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

सबसे पहले, मैं इन घटकों के दो महत्वपूर्ण लाभों पर ध्यान देना चाहूंगा। उनमें से सबसे महत्वपूर्ण मल्टीथ्रेडिंग है, जिसका अर्थ है कि सर्वर प्रत्येक क्लाइंट के लिए एक अलग थ्रेड बनाता है, और यह निश्चित रूप से मल्टी-कोर प्रोसेसर वाले कंप्यूटर पर सर्वर प्रोग्राम के प्रदर्शन को प्रभावित करता है। दूसरा लाभ उपयोग में आसानी है। एक साधारण क्लाइंट-सर्वर एप्लिकेशन लिखने के लिए कोड की 10-20 लाइनें पर्याप्त हैं। घटकों का यह पैकेज मानक डेल्फी असेंबली में मौजूद है।

आइए एक सरल प्रोग्राम लिखें जो आपको क्लाइंट से सर्वर पर एक टेक्स्ट संदेश भेजने की अनुमति देता है। आइए एक सर्वर बनाना शुरू करें।
IdTCPServer घटक को इंडी सर्वर टैब से प्रपत्र पर रखें। हम इस घटक के लिए फॉर्म के ऑनक्रिएट इवेंट में रनटाइम पर सभी सेटिंग्स करेंगे:
IdTCPServer1.DefaultPort:= 12345;
IdTCPServer1.सक्रिय:= सत्य;
यहां सब कुछ सरल है - हम उस पोर्ट को निर्दिष्ट करते हैं जिस पर सर्वर काम करेगा और सर्वर को ही सक्रिय करेगा।

क्लाइंट से सर्वर पर डेटा प्राप्त करने के लिए, एक विशेष घटना "ऑनएक्सक्यूट" होती है। यह घटना इस तरह दिखती है:

शुरू
समाप्त;

आइए घटना की सामग्री को इस प्रकार संपादित करें:
प्रक्रिया TForm3.IdTCPServer1Execute(AContext: TIdContext);
वर
एल: स्ट्रिंग; // स्ट्रिंग वेरिएबल जिसमें हम प्राप्त करेंगे
शुरू
एल: = AContext.Connection.IOHandler.ReadLn ();
Memo1.Lines.Add(l);
समाप्त;

अब, जैसे ही सर्वर पर कोई संदेश आता है, हम इसे स्ट्रिंग वेरिएबल l पर लिखेंगे और इसे एक मल्टीलाइन टेक्स्ट फ़ील्ड में प्रदर्शित करेंगे।

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

आइए एक नया प्रोजेक्ट बनाएं, IdTCPClient घटक को फॉर्म पर रखें, जो "इंडी क्लाइंट्स" टैब पर पाया जा सकता है। हम एक साधारण संपादन और एक बटन भी रखेंगे। आइए बटन के लिए एक ऑनक्लिक ईवेंट हैंडलर बनाएं, जिसके अंदर हम लिखेंगे:
IdTCPClient1.Port:= 12345;
IdTCPClient1.होस्ट:= '127.0.0.1';
IdTCPClient1.कनेक्ट;
IdTCPClient1.IOHandler.WriteLn(Edit1.Text);
IdTCPClient1.डिस्कनेक्ट;

इस कोड को ऑनक्रिएट इवेंट में रखने की जरूरत नहीं है। आप इस कोड को अपनी पसंद के किसी भी स्थान पर रख सकते हैं।
पहली पंक्ति में, हम एक पोर्ट असाइन करते हैं, और हमें उसी पोर्ट को निर्दिष्ट करना होगा जैसा हमने सर्वर प्रोग्राम पर इंगित किया था, अन्यथा क्लाइंट को बस सर्वर नहीं मिलेगा। फिर सर्वर का आईपी पता दर्ज करें। सर्वर स्वयं स्थानीय नेटवर्क और दूरस्थ रूप से स्थित हो सकता है। बाद के मामले में, कनेक्शन इंटरनेट के माध्यम से किया जाएगा और आपको इंटरनेट पर आईपी पता निर्दिष्ट करने की आवश्यकता होगी।

मैंने पता "127.0.0.1" निर्दिष्ट किया, जो इंगित करता है कि सर्वर वह कंप्यूटर है जिस पर क्लाइंट चल रहा है। नेटवर्क अनुप्रयोगों के परीक्षण के लिए यह विधि बहुत सुविधाजनक है।
फिर हम एक कनेक्शन बनाते हैं, एक संदेश भेजते हैं और डिस्कनेक्ट करते हैं। साथ ही संदेश के साथ ही, आप आईपी एड्रेस को एडिट से या किसी स्ट्रिंग वेरिएबल से भी ले सकते हैं।

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

साइट पर नया

>

सबसे लोकप्रिय