Shtëpi lule shumëvjeçare Zhvillimi i aplikacioneve klient-server duke përdorur Indy në Delphi. Komponentët Indy të përdorura në Delphi. Disa shembuj të përdorimit të komponentëve Indy

Zhvillimi i aplikacioneve klient-server duke përdorur Indy në Delphi. Komponentët Indy të përdorura në Delphi. Disa shembuj të përdorimit të komponentëve Indy

Protokoll mjaft i mirë UDP për transmetim mesazhe me tekst, domethënë mund të organizoni bisedat lokale dhe gjëra të tilla. Vendosa të jap një shembull të punës më të thjeshtë me UDP në Delphi.

Udhëzim hap pas hapi:

Unë dhashë një shembull, por ju më falni, nuk fillova të pikturoj çdo rresht, sepse Unë nuk shoh asgjë të komplikuar dhe çdokush mund ta kuptojë atë.

Në fakt, nëse diçka nuk është e qartë, mund të më bëni një pyetje. Dhe këtu është kodi aktual:

përdor
Windows, Mesazhe, SysUtils, Variante, Klasa, Grafika, Kontrolle, Forma,
Dialogët, StdCtrls, IdUDPServer, IdBaseComponent, IdComponent, IdUDPBase,
IdUDPClient, IdSocketHandle;

lloji
TForm1 = klasë (TForm)
IdUDPClient1: TIdUDPClient;
IdUDPServer1: TIdUDPServer;
Butoni 1: TButton;
Label1: T Label;
procedura FormCreate(Dërguesi: TObject);
procedura FormClose(Dërguesi: TObject; var Veprimi: TCloseAction);
procedura Button1Click(Dërguesi: TObject);
procedura IdUDPServer1UDRead(AThread: TIdUDPListenerThread; AData: TBytes;
ABBinding: TIdSocketHandle);
private
(Deklarata private)
publike
(Deklarata publike)
fundi;

var
Forma1: TForm1;

($R *.dfm)
[b]//Procedura për dërgimin e një mesazhi
procedura TForm1.Button1Click(Dërguesi: TObject);
fillojnë
provoni
IdUDPClient1.Active:= E vërtetë;
IdUDPClient1.Host:= "localhost";
IdUDPClient1.Connect;
nëse IdUDPClient1.I lidhur atëherë
fillojnë
IdUDPClient1.Send(TimeToStr(Time));
Label1.Caption:= "ok";
fundi;
IdUDPClient1.Active:= False;
Beep;Beep;Beep;
përveç
MessageDlg("Diçka shkoi keq =(", mtGabim, , 0);
fundi;
fundi;
[b]
//Ndezur fikur. Serveri UDP në fillimin dhe mbylljen e formularit
procedura TForm1.FormClose(Dërguesi: TObject; var Veprimi: TCloseAction);
fillojnë
IdUDPServer1.Active:= False;
fundi;

procedura TForm1.FormCreate(Dërguesi: TObject);
fillojnë
IdUDPServer1.Active:= E vërtetë;
fundi;

[b]//Procedura e përgjigjes së serverit gjatë marrjes së të dhënave
procedura TForm1.IdUDPServer1UDRead(AThread: TIdUDPListenerThread;
AData: TBytes; ABBinding: TIdSocketHandle);
Var
i: Numër i plotë;
s:string;
fillojnë
s:="";
provoni
i:= 0;
ndërsa (AData[i] 0) bëjnë
fillojnë
s:= s + chr(AData[i]);
i:= i + 1;
fundi;
më në fund
Etiketa1.Titulli:= s;
fundi;
fundi;

Me pak fjalë, Indy janë komponentë për punë të përshtatshme me protokollet e njohura të Internetit. Parimi i funksionimit të tyre bazohet në përdorimin e prizave në modalitetin e bllokimit. Indy është interesant dhe i përshtatshëm në atë që është mjaft i abstraktuar. Dhe programimi në Indy zbret në programim linear. Nga rruga, një artikull i përkthyer është shpërndarë gjerësisht në internet, në të cilin ka fjalët "modaliteti i bllokimit nuk është djalli" :)) Në një kohë unë u argëtova shumë nga ky përkthim. Artikulli është pjesë e librit të Hoover dhe Haririt "The Depths of Indy". Në parim, për të punuar me Indy, nuk duhet t'i lexoni fare, por unë ende rekomandoj të njiheni me parimet e protokolleve të Internetit. Sa për mënyrën "djallëzore". Një telefonatë bllokuese e prizës nuk kthehet në të vërtetë derisa të ketë përfunduar detyrën e saj. Kur bëhen thirrje në lidhjen kryesore, ndërfaqja e aplikacionit mund të varet. Për të shmangur këtë situatë të pakëndshme, zhvilluesit indianë krijuan komponentin TIdAntiFreeze. Mjafton vetëm ta hidhni në formular - dhe ndërfaqja e përdoruesit do të rivizatohet në heshtje gjatë bllokimit të thirrjeve.

Ju ndoshta jeni njohur tashmë me përmbajtjen e skedave të ndryshme "Indy (...)" në Delphi. Ka shumë komponentë, dhe secili prej tyre mund të jetë i dobishëm. Unë vetë nuk kam punuar me të gjitha, sepse nuk e shoh të nevojshme t'i studioj pa një detyrë specifike.

Shpërndarja bazë e Delphi përfshin Indy v.9 me qindarka. Ndoshta është e këshillueshme që menjëherë të përmirësohet në më shumë version i ri(për shembull, unë kam 10.0.76 tani, por ka edhe të mëvonshme).

Ka komponentë klient dhe server për të punuar me të njëjtat protokolle. Indy thjeshton vërtet zhvillimin e aplikacioneve, në kontrast me opsionin e zhvillimit të të njëjtit funksionalitet në priza. Për shembull, për t'u lidhur me një server, thjesht duhet të telefononi metodën Connect. Një vendosje e suksesshme e lidhjes do të shënohet nga një kthim nga metoda pa u ngritur një përjashtim. Nëse lidhja nuk vendoset, do të bëhet një përjashtim.

Shembull "Akademik" (kodi nuk funksionon, mos e ekzekutoni :)):

Me IndyClient bëni
fillojnë
Host:= "test.com";
Porti:= 2000;
lidh;
provoni
// punë me të dhëna (lexim, shkrim...)
më në fund
Shkëputje;
fundi;
fundi;

Hosti dhe porti mund të vendosen në inspektorin e objektit ose në kohën e ekzekutimit.

Për çfarë mund të përdoren komponentët Indy në detyrat e analizimit? Aplikimi është i larmishëm! Më e thjeshta është marrja e përmbajtjes së faqes (të gjithë ndoshta e kanë hasur tashmë këtë) duke përdorur komponentin IdHTTP:

Var
rcvdata:TMemoryStream;
idHttp1: TidHttp;
fillojnë
idHttp1:= TidHttp.Create(nil);
rcvrdata:= TMemoryStream.Create;
idHttp1.Request.UserAgent:= "Mozilla/4.0 (e pajtueshme; MSIE 5.5; Windows 98)";
idHttp1.Request.AcceptLanguage:= "en";
idHttp1.Response.KeepAlive:= true;
idHttp1.HandleRedirects:= true;
provoni
idHttp1.Get(Edit1.Text, rcvrdata);
më në fund
idHttp1.Free;
fundi;
nëse rcvrdata.Madhësia > 0 atëherë filloni
ShowMessage("Marrë" + inttostr(rcvrdata.Size));
rcvrdata.SaveToFile("c:\111.tmp");
fundi;
rcvrdata.Falas;
fundi;

Siç mund ta shihni, jo vetëm që mund të merrni përmbajtjen e faqes, por edhe të simuloni ngarkimin e një dokumenti nga një klient specifik. Komponentët Indy janë përgjithësisht të përshtatshëm për formimin e titujve dhe kërkesave POST. Më shumë për këtë me shembuj herën tjetër.

Për të qëndruar të përditësuar me përditësimet e blogut, mundeni

Hyrje në Indy

Hyrje në Indy
Autori: Chad Z. Hower
Faqja kryesore: http://www.atozedsoftware.com
Përkthim: Anatoli Podgoretsky
fjalimi i hapjes
E shkrova këtë artikull kur versioni aktual ishte Indy 8.0. Pjesa më e madhe e këtij artikulli është e zbatueshme dhe shumë e dobishme në versionet e ardhshme të Indy. Nëse ju pëlqeu ky artikull dhe dëshironi të lexoni artikuj më të detajuar, atëherë hidhini një sy librit Indy in Depth.
Indy funksionon në modalitetin e bllokimit
Indy përdor priza bllokuese. Mënyra e bllokimit është si të lexosh-shkruash një skedar. Kur lexoni ose shkruani të dhëna, funksioni nuk e kthen kontrollin deri në fund të funksionimit. Dallimi nga puna me skedarë është se telefonata mund të jetë më e gjatë sepse të dhënat e kërkuara nuk janë ende të disponueshme, kjo varet nga shpejtësia me të cilën funksionon rrjeti ose modemi juaj.
Për shembull, thjesht bëni një thirrje metodë dhe prisni derisa kontrolli t'i kthehet telefonuesit. Nëse thirrja ishte e suksesshme, atëherë kontrolli do të kthehet nga metoda, në rast gabimi do të ngrihet një përjashtim.
Mënyra e bllokimit nuk është fatale
Për shkak të mënyrës së bllokimit, ne jemi rrahur vazhdimisht nga kundërshtarët tanë, por mënyra e bllokimit nuk është djalli.
Problemi u shfaq pasi Winsock u transferua në Windows. Në Unix, problemi zakonisht zgjidhej duke forcuar (ngjashëm me multi-threading, por në kurriz të proceset individuale në vend të përrenjve). Klientët dhe demonët e Unix-it duhej të forconin proceset për të ekzekutuar dhe përdorur modalitetin e bllokimit. Windows 3.x nuk mund të paralelizohej dhe nuk mbështette multi-threading. Përdorimi i një ndërfaqe bllokuese ngriu ndërfaqen e përdoruesit dhe i bëri programet të mos përgjigjen. Prandaj, modalitetet jo-bllokuese u shtuan në WinSock, duke lejuar Windows 3.x, me kufizimet e tij, të përdorë Winsock pa bllokuar fillin kryesor dhe të vetëm të programit. Kjo kërkonte programime të ndryshme, Microsoft dhe të tjerë denoncuan me forcë mënyrat e bllokimit për t'u fshehur disavantazhet e Windows 3.x.
Pastaj erdhi Win32, i cili ishte në gjendje të mbështeste multi-threading. Por deri në këtë pikë, truri ishte tashmë i pluhurosur (d.m.th., zhvilluesit e konsideruan bllokimin e prizave produkt të djallit) dhe tashmë ishte e vështirë të ndryshonin atë që kishin bërë. Prandaj, sharjet e regjimeve bllokuese vazhdojnë.
Në realitet, Unix ka vetëm priza bllokuese. Bllokimi i prizave ka gjithashtu avantazhet e tyre, dhe ato janë shumë më të mira, për shumë filetime, siguri dhe aspekte të tjera. Disa shtesa janë shtuar gjithashtu në Unix për prizat që nuk bllokojnë. Sidoqoftë, ato funksionojnë shumë ndryshe sesa në Windows. Ato janë gjithashtu jo standarde dhe jo shumë të zakonshme. Prizat bllokuese në Unix përdoren pothuajse në të gjitha rastet dhe do të vazhdojnë të përdoren.
Përfitimet e mënyrës së bllokimit Më e lehtë për t'u programuar - Mënyrat e bllokimit janë më të lehta për t'u programuar. I gjithë kodi i përdoruesit mund të jetë në një vend dhe të ekzekutohet në një rend të natyrshëm, vijues. Transportim më i lehtë në Unix - Meqenëse Unix përdor fole bllokuese, kodi portativ duhet të shkruhet këtë rast më e lehtë. Indy e përdor këtë fakt për të shkruar kod të qëndrueshëm. · Më i përshtatshëm për të punuar me fije - Meqenëse prizat bllokuese kanë një sekuencë të fituar nga trashëgimia, kështu që ato janë shumë të lehta për t'u përdorur në fije.
Disavantazhet e ndërfaqes së ndërfaqes së modalitetit të bllokimit ngrin te klientët - Një telefonatë bllokuese e prizës nuk kthehet derisa të ketë përfunduar detyrën e saj. Kur një telefonatë e tillë bëhet në lidhjen kryesore të aplikacionit, aplikacioni nuk mund të përpunojë mesazhet e përdoruesit. Për shkak të kësaj, ndërfaqja e përdoruesit është e ngrirë, dritaret nuk përditësohen dhe mesazhet e tjera nuk mund të përpunohen derisa kontrolli të kthehet nga priza bllokuese.
Komponenti TIdAntiFreeze
Indy ka një komponent të veçantë që zgjidh problemin e ngrirjes ndërfaqja e përdoruesit. Thjesht shtoni një komponent TIdAntiFreeze kudo në aplikacionin tuaj dhe mund të bëni thirrje bllokuese pa ngrirë ndërfaqen e përdoruesit.
TIdAntiFreeze funksionon në një kohëmatës të brendshëm jashtë grupit të thirrjeve dhe thërret Application.ProcessMessages kur skadon afati. Thirrjet e jashtme drejt Indy vazhdojnë të jenë të bllokuara dhe për këtë arsye funksionojnë saktësisht njësoj si pa përdorur komponentin TIdAntiFreeze. Përdorimi i TIdAntiFreeze ju lejon të përfitoni të gjitha avantazhet e bllokimit të prizave pa disavantazhe.
Transmetimet e kodit (Threading)
Bllokimi i prizave pothuajse gjithmonë përdorin kode. Prizat jo-bllokuese mund të përdorin edhe rryma, por kjo kërkon një përpunim shtesë dhe përfitimet e tyre humbasin në këtë rast në krahasim me prizat bllokuese.
Avantazhet e threads · Vendosja e prioriteteve - Prioritetet e threads individuale mund të konfigurohen. Kjo ju lejon të ndani pak a shumë kohë CPU për detyrat individuale. · Encapsulation - Çdo lidhje mund të përmbajë një ngjashmëri të një ndërfaqeje me një lidhje tjetër. ·Siguria - Çdo thread mund të ketë atribute të ndryshme sigurie. · Procesorë të shumëfishtë - jep përparësi në sistemet me procesorë të shumëfishtë. · Nuk ka nevojë për serializim - siguron harmonizim të plotë. Pa shumë fillesë, të gjitha kërkesat duhet të përpunohen në një fill. Prandaj, çdo detyrë duhet të ndahet në copa të vogla në mënyrë që të mund të funksionojë shpejt. Ndërsa një bllok është duke u ekzekutuar, të gjithë të tjerët janë të detyruar të presin përfundimin e tij. Në fund të një blloku, ekzekutohet blloku tjetër, e kështu me radhë. Me multithreading, çdo detyrë mund të programohet si një dhe sistemi operativ shpërndan kohën midis të gjitha detyrave.
Sondazhi i Temave
Krijimi dhe shkatërrimi i temave është shumë intensiv i burimeve. Kjo është një detyrë veçanërisht e vështirë për serverët që kanë lidhje jetëshkurtër. Çdo server krijon një fije, e përdor atë një kohë të shkurtër dhe më pas shkatërron. Kjo rezulton në krijimin dhe fshirjen shumë të shpeshtë të temave. Një shembull i kësaj është serveri në internet. Dërgohet një kërkesë e vetme dhe kthehet një përgjigje e thjeshtë. Qindra lidhje dhe shkëputje mund të ndodhin kur përdorni një shfletues gjatë shfletimit të një faqeje interneti.
Temat e votimit mund ta rregullojnë këtë situatë. Në vend që të krijohen dhe shkatërrohen temat sipas kërkesës, temat zgjidhen nga një listë e temave të papërdorura, por të krijuara tashmë, nga grupi. Kur një fije nuk nevojitet më, ajo kthehet në pishinë në vend që të shkatërrohet. Fijet në pishinë janë shënuar si të papërdorura dhe për këtë arsye ato nuk konsumojnë kohën e CPU-së. Për më shumë më shumë përmirësim rrymat mund të përshtaten në mënyrë dinamike me nevojat aktuale të sistemit.
Indy mbështet sondazhin e temave. Grupi i fijeve në Indy është i disponueshëm përmes komponentit TIdThreadMgrPool.
Fije të shumta
Një server i ngarkuar shumë mund të kërkojë qindra apo edhe mijëra tema. Ekziston një besim i zakonshëm se qindra e mijëra fije mund të vrasin sistemin tuaj. Ky është një besim i gabuar.
Në shumicën e serverëve, temat janë duke pritur për të dhëna. Ndërsa pret një telefonatë bllokuese, lidhja është joaktive. Në një server me 500 tema, vetëm 50 mund të jenë aktiv në të njëjtën kohë.
Numri i temave që janë duke u ekzekutuar në sistemin tuaj mund t'ju habisë. Në sasi minimale serverët që funksionojnë dhe aplikacionet e specifikuara në ekzekutim, sistemi im ka 333 thread të krijuar, edhe me 333 threads, procesori është vetëm 1% i ngarkuar. Server IIS i ngarkuar shumë ( Internet Microsoft Serveri i Informacionit) mund të krijojë qindra ose mijëra thread.
Temat dhe seksionet globale
Me fije të shumta, ju duhet të siguroni integritetin e të dhënave kur i përdorni ato. Kjo mund të jetë e vështirë për programuesit pa fije. Por, si rregull, shumica e serverëve nuk kanë nevojë të përdorin të dhëna globale. Shumica e serverëve kryejnë funksione të izoluara. Çdo fije kryen detyrën e vet të izoluar. Seksionet globale të leximit/shkrimit janë një veçori e shumë aplikacioneve me shumë fije, por nuk janë tipike për serverët.
Metodologjia Indy
Indy është i ndryshëm nga komponentët e tjerë të Winsock me të cilët jeni mësuar. Nëse keni punuar me komponentë të tjerë, atëherë zgjidhja më e mirë do të harrojnë se si funksionojnë. Shumë komponentë të tjerë përdorin thirrje jo-bllokuese (asinkrone) dhe funksionojnë në mënyrë asinkrone. Ata duhet t'i përgjigjen ngjarjeve, të krijojnë një makinë shtetërore dhe të kryejnë ciklin e pritjes të shpeshta.
Për shembull, me komponentët e tjerë, kur telefononi një lidhje, ose duhet të prisni që ngjarja e lidhjes të aktivizohet, ose të kaloni nëpër vetinë për të treguar që lidhja ka ndodhur. Me Indy, mund të telefononi metodën Connect dhe të prisni që ajo të kthehet. Një kthim do të bëhet nëse lidhja është e suksesshme ose nëse bëhet një përjashtim nëse ka një problem. Prandaj, puna me Indy është shumë e ngjashme me punën me skedarë. Indy ju lejon të vendosni të gjithë kodin tuaj në një vend në vend që ta shpërndani në të gjithë ngjarje të ndryshme. Për më tepër, Indy është shumë i thjeshtë dhe më i përshtatshëm kur punoni me fije.
Sa ndryshe është Indy
Vështrim i shkurtër · Përdor bllokimin e thirrjeve · Jo të orientuara drejt ngjarjeve - ngjarjet janë të pranishme, por ato përdoren për qëllime informative dhe nuk kërkohen realisht. ·Projektuar për fije - Indy është projektuar për fije, megjithatë mund të përdoret pa fije. Programimi sekuencial
Shqyrtim i detajuar
Indy jo vetëm që përdor bllokimin e thirrjeve (sinkrone), por funksionon edhe si kjo. Një seancë tipike në Indy duket kështu:
me IndyClient filloni
lidh; provoni
// Bëni gjërat tuaja këtu
më në fund Shkëputeni; fundi;
fundi;
Me komponentët e tjerë duket kështu:
procedura TFormMain.TestOnClick(Dërguesi: TComponent);
fillojnë
me SocketComponent filloni
lidh; provoni
ndërsa nuk është i lidhur, filloni
nëse IsError atëherë filloni
aborti;
fundi;

OutData:= "Të dhënat për të dërguar";
ndërsa gjatësia (OutData) > 0 fillon
Aplikimi.Procesi Mesazhet;
fundi;
më në fund Shkëputeni; fundi;
fundi;
fundi;
procedura TFormMain.OnConnectError;
fillojnë
IsError:= E vërtetë;
fundi;
procedura TFormMain.OnRead;
var
i: Numër i plotë;
fillojnë
i:= SocketComponent.Send(OutData);
OutData:= Kopjo (OutData, i + 1, MaxInt);
fundi;
Shumë komponentë nuk bëjnë një punë shumë të mirë për të izoluar programuesin nga grupi. Shumë komponentë, në vend që ta izolojnë përdoruesin nga kompleksiteti i pirgut, thjesht e lini përdoruesin vetëm me të ose siguroni një mbështjellës mbi pirg.
Rruga e veçantë e Indy
Indy është projektuar nga themeli për të qenë me shumë fije. Ndërtimi i serverëve dhe klientëve në Indy është i ngjashëm me ndërtimin e serverëve dhe klientëve në Unix. Aplikacionet Unix zakonisht thërrasin stack-in drejtpërdrejt me pak ose aspak shtresë abstraksioni.
Në mënyrë tipike, serverët Unix kanë një ose më shumë procese dëgjuesi që dëgjojnë kërkesat hyrëse të klientit. Për çdo klient që duhet të shërbehet, a proces i ri. Kjo e bën programimin të thjeshtë, çdo proces është vetëm për një klient. Çdo proces fillon më vete kontekstin e vet siguria, e cila jepet nga procesi i dëgjimit, ose nga një proces i bazuar në të drejtat ekzistuese, identitetin ose gjëra të tjera.
Serverët Indy punojnë në të njëjtën mënyrë. Windows, ndryshe nga Unix, nuk mund të përhapë mirë proceset, por funksionon mirë me thread-at. Serverët Indy krijojnë një fije të veçantë për çdo lidhje klienti.
Serverët Indy caktojnë një fill dëgjimi që është i ndarë nga rrjedha kryesore e kodit të programit. Fillimi i dëgjimit dëgjon kërkesat hyrëse nga klientët. Për çdo klient të cilit i përgjigjet, a fill i ri për shërbimin ndaj klientit. Ngjarjet përkatëse shërbehen më pas në kontekstin e asaj thread.
Përmbledhje e klientëve Indy
Indy është projektuar për të ofruar një shumë nivel të lartë abstraksioni. Kompleksiteti dhe detajet e pirgut TCP/IP janë të fshehura nga programuesi. Një sesion tipik i klientit në Indy zakonisht duket kështu:
me IndyClient filloni
Host:= "zip.pbe.com"; // host për të thirrur
Porti:= 6000; // Porta për të thirrur serverin
lidh; provoni
// Bëni gjërat tuaja këtu
më në fund Shkëputeni; fundi;
fundi;
Pasqyrë e serverëve Indy
Komponentët e serverit Indy krijojnë një fill dëgjimi që është i izoluar nga filli kryesor i kodit të programit. Fillimi i dëgjimit dëgjon kërkesat hyrëse nga klientët. Për çdo klient të cilit i përgjigjet, krijohet një fill i ri për t'i shërbyer klientit. Ngjarjet përkatëse shërbehen më pas në kontekstin e asaj thread.

Shembuj praktik
Shembujt e mëposhtëm do t'ju ndihmojnë të filloni me komponentët për përdorim të lehtë, por për të demonstruar shembujt janë bërë si aplikacione të thjeshta. Disa projekte janë bërë për t'u ekspozuar situata të ndryshme. Këta shembuj janë gjithashtu të disponueshëm për shkarkim si skedarë zip.
Shënim nga përkthyesi: lidhja në sit nuk funksionon.
Shembulli 1 - Kontrolli i kodit postar
Projekti i parë është bërë sa më i thjeshtë. Kërkoni sipas kodit postar, klienti pyet serverin se cilit qytet dhe shtet i përket kodi postar i specifikuar.
Për ata që jetojnë jashtë SHBA dhe nuk e dinë se çfarë është një kod postar, ky është një kod postar që tregon vendin e dorëzimit. Kodet postare përbëhen nga 5 shifra.
Protokolli
Hapi i parë në ndërtimin e një serveri dhe klienti është zhvillimi i protokollit. Për protokollet standarde, kjo përcaktohet nga RFC-ja përkatëse. Për një kod postar, protokolli është përcaktuar më poshtë.
Shumica e protokolleve të shkëmbimit funksionojnë në modalitetin e tekstit. Një shkëmbim do të thotë që një komandë dërgohet dhe përgjigja është gjendje dhe ndoshta të dhëna. Protokollet nuk kufizohen në shkëmbim, por teksti i thjeshtë përdoret ende. Protokolli për përcaktimin e kodit postar është gjithashtu tekst. Teksti i thjeshtë i bën protokollet të lehtë për tu korrigjuar dhe lejon komunikimin gjuhë të ndryshme programimi dhe sistemet operative.
Pas lidhjes, serveri dërgon një mesazh përshëndetje, më pas pranon komandën. Kjo komandë mund të jetë "ZipCode x" (Ku x është kodi postar) ose "Quit". Në përgjigje të komandës ZipCode, një përgjigje dërgohet si një rresht i vetëm me përgjigjen, ose një rresht bosh nëse kodi nuk gjendet. Komanda Quit bën që serveri të heqë lidhjen. Serveri mund të pranojë disa komanda përpara se të dërgohet komanda Quit.
Kodi burimor i serverit

unitServerMain;

ndërfaqe

përdor

lloji

TformMain = klasa (TForm)

IdTCPServer1: TIdTCPServer;

procedura FormCreate(Dërguesi: TObject);

procedura FormDestroy(Dërguesi: TObject);

procedura IdTCPServer1Connect(AThread: TIdPeerThread) ;

private

ZipCodeList: TStrings;

publike

fundi ;

FormMain: TformMain;

zbatimi

(R*.DFM)

procedura TformMain.IdTCPServer1Connect (AThread: TIdPeerThread) ;

fillojnë

AThread.Connection .WriteLn("Serveri i kodit postar Indy gati." );

fundi ;

SK Komanda: string ;

fillojnë

SCCommand:= ReadLn ;

fundi ;

fundi ;

fundi ;

procedura TformMain.FormCreate (Dërguesi: TObject) ;

fillojnë

ZipCodeList:= TStringList.Create ;

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

fundi ;

procedura TformMain.FormDestroy (Dërguesi: TObject ) ;

fillojnë

ZipCodeList.Free ;

fundi ;

fund.

Të vetmet pjesë specifike të Indy në projekt janë komponenti IdTCPServer1, metodat IdTCPServer1Connect dhe IdTCPServer1Execute.
Formulari përmban komponentin IdTCPServer1 të llojit TIdTCPServer. Vetitë e mëposhtme janë ndryshuar: ·Active = True - Pas fillimit të aplikacionit, serveri dëgjon. ·DefaultPort = 6000 - Vlera e portit për këtë projekt. Serveri dëgjon kërkesat e klientit në këtë port.
Metoda IdTCPServer1Execute lidhet me ngjarjen OnExecute të serverit. Ngjarja OnExecute aktivizohet pasi të pranohet lidhja e klientit. Ngjarja OnExecute është e ndryshme nga ngjarjet e tjera që njihni. OnExecute ekzekutohet në kontekstin e një thread. Ngjarja thread aktivizohet dhe i kalohet argumenti AThread që i kalohet metodës. Kjo është e rëndësishme sepse shumë ngjarje OneExecute mund të ekzekutohen në të njëjtën kohë. Kjo është bërë në mënyrë që serveri të mund të funksionojë pa krijuar një komponent të ri. Ekzistojnë gjithashtu metoda që mund të anashkalohen gjatë ndërtimit të pasardhësve.
Ngjarja OnConnect aktivizohet pasi është pranuar një lidhje dhe është krijuar një bashkëbisedim për të. Ky server e përdor këtë për t'i dërguar një mesazh përshëndetje klientit. Kjo mund të bëhet edhe në ngjarjen OnExecute nëse dëshironi.
Ngjarja OnExecute mund të aktivizohet disa herë derisa lidhja të shkëputet ose humbet. Kjo eliminon nevojën për të kontrolluar lidhjen për shkëputje ose humbje në lak brenda ngjarjes.
IdTCPServer1Execute përdor dy funksione bazë, ReadLn dhe WriteLn. ReadLn lexon një rresht nga lidhja dhe WriteLn dërgon linjën në lidhje.
sCommand:= ReadLn;
Kodi i mësipërm merr një varg nga klienti dhe e vendos atë në variablin e vargut lokal sCommand.

nëse SameText (sCommand, "QUIT") atëherë filloni

përfundoni tjetër nëse SameText (Copy (sCommand, 1, 8), "ZipCode") pastaj filloni

WriteLn (ZipCodeList.Values ​​[ Kopjo (sCommand, 9, MaxInt) ] );

fundi ;


Më pas, sCommand kontrollohet për komanda të vlefshme.
Nëse komanda është "Quit", atëherë kryhet një Shkëputje. Nuk lejohet leximi ose shkrimi pas shkëputjes. Pas përfundimit të ngjarjes, filli i dëgjimit nuk e thërret më atë, por pastron fillin dhe përfundon lidhjen.
Nëse komanda është "ZipCode", atëherë parametri pas komandës nxirret dhe kërkohet tabela për praninë e qytetit dhe shtetit. Qyteti dhe shteti i kalohen klientit ose kalohet një varg bosh nëse nuk ka përputhje.
Pastaj metoda del. Serveri do të riprovojë përsëri thirrjen e ngjarjes sapo të mbërrijë. ekip i ri, duke i lejuar klientit të dërgojë komanda të shumta.
Kodi burimor i klientit

unitClientMain;

ndërfaqe

përdor

Windows, Mesazhe, SysUtils, Klasa, Grafika, Kontrollet, Format, Dialogët,

StdCtrls, ExtCtrls, IdAntiFreezeBase,

IdAntiFreeze, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;

lloji

TformMain = klasa (TForm)

Klienti: TIdTCPClient;

IdAntiFreeze1: TIdAntiFreeze;

Paneli 1: TPanel;

Paneli 2: TPanel;

MemoInput:TMemo;

Rezultatet e Lbox: TListBox;

Paneli 3: TPanel;

Butoni 1: TButton;

Butoni 2: TButton;

Label1: T Label;

procedura Button2Click(Dërguesi: TObject ) ;

Procedura Button1Click(Dërguesi: TObject) ;

private

publike

fundi ;

FormMain: TformMain;

zbatimi

(R*.DFM)

procedura TformMain.Button2Click (Dërguesi: TObject ) ;

fillojnë

MemoInput.Clear;

LboxResults.Clear ;

fundi ;

procedura TformMain.Button1Click (Dërguesi: TObject) ;

I: numër i plotë;

S: varg

fillojnë

ButnLookup.Enabled := true; provoni

LboxResults.Clear ;

me Klientin filloni

lidh; provoni

LboxResults.Items .Add (ReadLn) ;

për i:= 0 në memoInput.Linjat .Numërimi - 1 fillon

WriteLn("ZipCode" + memoInput.Linjat[ i] );

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

S:= LexoLn ;

nëse s = "" atëherë filloni

S:= "-- Nuk u gjet asnjë hyrje për këtë kod postar.";

fundi ;

LboxResults.Items .Add(s) ;

LboxResults.Items .Shto ("");

fundi ;

WriteLn("Quit");

më në fund Shkëputeni; fundi ;

fundi ;

më në fund butnLookup.Enabled := true; fundi ;

fundi ;

fund.


Të vetmet pjesë specifike për komponentin e klientit janë metoda Button1Click.
Komponenti Client është i tipit TIdTCPClient dhe vendoset në formular. Karakteristikat e mëposhtme janë ndryshuar: Host = 127.0.0.1 - Serveri ndodhet në të njëjtën makinë si klienti. Port = 6000 - Porta e serverit
Metoda Button1Click shoqërohet me ngjarjen OnClick të komponentit Button1. Kur klikohet butoni, thirret kjo metodë. Pjesa Indy e kësaj metode mund të reduktohet në sa vijon: 1.Lidhja me serverin (Connect;) 1.Leximi i përshëndetjes nga serveri. 1. Për çdo rresht të futur nga përdoruesi në TMemo: 1. Dërgimi i një kërkese te serveri (WriteLn("ZipCode" + memoInput. Lines[i]);) 1. Leximi i përgjigjes nga serveri (s:= ReadLn; ) 1. Dërgimi i komandës Quit (WriteLn("Quit");) 1. Disconnect (Disconnect;)
Duke testuar
Ky shembull është testuar dhe funksionon me TCP/IP të instaluar. Mund ta ndryshoni që të funksionojë përmes një rrjeti nga një kompjuter në tjetrin. Duke ndezur serverin në një kompjuter tjetër dhe duke ndryshuar emrin ose IP-në e serverit në klient.
Për të testuar projektet, përpiloni dhe ekzekutoni serverin. Pastaj përpiloni dhe ekzekutoni klientin. Futni kodin postar në fushën e shënimeve dhe shtypni tastin e kërkimit.
Korrigjimi
Protokollet e tekstit janë shumë të lehta për tu korrigjuar, sepse ato mund të kontrollohen me Telnet. Për ta bërë këtë, mjafton të njihni portën e serverit. Serveri i kërkimit të kodit postar po dëgjon në portin 6000.
Nisni sërish Serverin e kërkimit të kodit postar. Pastaj hapni një tastierë (për shembull, një dritare Dos). Tani futni:
telnet 127.0.0.1 6000
Tani jeni lidhur me serverin. Disa serverë dërgojnë gjithashtu një mesazh përshëndetje. Disa jo. Ju nuk do t'i shihni linjat që futni. Shumica e serverëve nuk bëjnë jehonë për të kursyer trafikun. Megjithatë, mund të ndryshoni cilësimet e telnet duke vendosur opsionin "Echo On". Në klientë të ndryshëm telnet kjo bëhet në mënyra të ndryshme, dhe një numër prej tyre nuk e kanë fare një mundësi të tillë. Tani futni:
kodi postar 37642
Do të shihni përgjigjen e serverit:
Kodra e Kishës, TN
Për t'u shkëputur nga serveri, shkruani:

Shembulli 2 - qasja në bazën e të dhënave
Ky shembull imiton një server që duhet të kryejë detyra bllokuese të tjera përveç thirrjeve të prizës. Shumë serverë janë të detyruar të punojnë në kushte të tilla. Serverët që kanë nevojë për akses në bazën e të dhënave, thirrje të procedurave të jashtme ose llogaritje shpesh nuk mund t'i ndërpresin këto thirrje sepse janë thirrje të jashtme ose për shkak të kompleksitetit të kryerjes së kësaj. Thirrja bazë nuk mund të ndahet në pjesë të vogla dhe zhvilluesi duhet të presë që operacioni bazë të përfundojë. Ky është një veçori jo vetëm e akseseve në bazën e të dhënave, por edhe e operacioneve të tjera si kompresimi, llogaritjet dhe përpunimi i të njëjtit lloj.
Për qëllime demonstrimi, le të themi se serveri bën një telefonatë të bazës së të dhënave që kërkon 5 sekonda për të përfunduar. Për ta thjeshtuar, le ta bëjmë këtë me një pauzë, përdorni funksionin Sleep(5000) për këtë, në vend që të telefononi.
Ky shembull gjithashtu kërkon më pak detaje se shembulli i mëparshëm sepse shumë nga konceptet nuk janë kuptuar ende.
Burimi

njësia kryesore;

ndërfaqe

përdor

Windows, Mesazhe, SysUtils, Klasa, Grafika, Kontrollet, Format, Dialogët,

IdBaseComponent, IdComponent, IdTCPServer;

lloji

TformMain = klasa (TForm)

IdTCPServer1: TIdTCPServer;

procedura IdTCPServer1Execute(AThread: TIdPeerThread) ;

private

publike

fundi ;

FormMain: TformMain;

zbatimi

(R*.DFM)

procedura TformMain.IdTCPServer1Execute (AThread: TIdPeerThread) ;

I: numër i plotë;

fillojnë

me AThread.Lidhja fillon

WriteLn ("Përshëndetje. Serveri DB gati." );

I:= StrToIntDef (ReadLn, 0);

// Gjumi zëvendësohet me një DB të gjatë ose një telefonatë tjetër

Gjumi (5000);

WriteLn (IntToStr (i * 7 ) );

fundi ;

fundi ;

fund.

Për shkak se ngjarja Execute ndodh në kontekstin e një thread, kodi i përpunimit mund të jetë i çdo gjatësie. Çdo klient ka fillin e vet dhe nuk bllokon klientët e tjerë.
Duke testuar
Për të testuar serverin DB, përpiloni dhe ekzekutoni atë. Lidhu me të duke përdorur Telnet në portën 6001. Serveri do të përgjigjet me një mesazh përshëndetje. Futni një numër. Serveri do të "përpunojë" kërkesën tuaj dhe do të përgjigjet në 5 sekonda.

Pershendetje te gjitheve!

Gjatë zhvillimit të projektit të ardhshëm të Uebit, u ngrit detyra - të implementoni softuerin e klientit në Delphi, i cili do të transferonte të dhënat në server duke përdorur metodën POST. Aplikacioni duhet të transmetojë tekst dhe të ngarkojë skedarë në serverin e uebit.

Zbatimi i një dërgimi të tillë të të dhënave duke përdorur gjuhët e zhvillimit të uebit nga ana e serverit (për shembull, PHP) është mjaft i thjeshtë, por nëse keni nevojë të shkruani një aplikacion, softuer me shumë përdorues që ndërvepron me serverin, atëherë tashmë është pak më i ndërlikuar. . Metoda e lidhjes direkte me bazën e të dhënave dhe nëpërmjet FTP me serverin nga Delphi është jashtë diskutimit. nuk është i sigurt, jo i besueshëm (ndryshimi i fjalëkalimeve, të dhënave të lidhjes, etj.) dhe krijon shtesë. problemet e përputhshmërisë së softuerit në anën e klientit. Për të zgjidhur problemin, vendosa të shkruaj skripta në PHP (pjesa e serverit) që do të përpunojë kërkesat hyrëse POST dhe do t'ia kthejë rezultatin klientit (aplikacioni Delphi). Përparësitë e kësaj qasjeje janë se të gjitha lidhjet dhe përpunimi i të dhënave ndodhin në server, gjë që është shumë më e sigurt se një "lidhje" e drejtpërdrejtë.

Duke filluar të "google"-u, u lëshuan shumë informacione të ndryshme, kryesisht ishin forume, por të gjitha ishin pjesë. Një gjë përcaktoi saktësisht se çfarë do të përdorte Indy, përkatësisht komponenti IdHTTP me metodën POST të zbatuar. Në fakt, gjithçka është e thjeshtë, kjo metodë merr dy parametra Url të burimit dhe DataStream (rrjedhë e të dhënave), si përgjigje jep rezultatin në formë teksti (mund të jetë edhe kodi HTML i faqes). Gjëja kryesore ishte formimi i duhur DataStream (rrjedha e të dhënave të transmetuara), por gjatë rrugës dolën gracka shtesë, përkatësisht kodimi rus (nëse nuk është në rregull). Këtu nisi argëtimi për disa orë bredhje në hapësirat e hapura të rrjetit. Në përgjithësi, mjaft muhabet, le të kalojmë në praktikën dhe zbatimin e softuerit.

Pra, programi është i thjeshtë. Duhet të dërgojë të dhëna në server duke përdorur metodën POST, të dhënat përmbajnë " kokë " (linjë), " Përshkrim » (tekst me shumë rreshta) dhe skedar grafik(jpg, png, gif-binare të dhëna). Serveri duhet t'i pranojë këto të dhëna, t'i përpunojë ato, të ruajë skedarin grafik në server dhe të kthejë një përgjigje. Si përgjigje, ne do të kthejmë Delphi në aplikacion, të njëjtin tekst vetëm me shtimin e etiketave dhe një lidhje në skedarin e shkarkuar. Asgje tjeter.

Le të fillojmë me zbatimin e pjesës së serverit (të ngjashme me API të faqes së internetit). Hapni çdo redaktues teksti (notepad) dhe shkruani kodin e mëposhtëm në të:

"; ) else ( jehonë "Header: Mungon."
"; ) //Kontrollo të dhënat hyrëse për praninë e të dhënave të fushës "përmbajtje" nëse (!empty($_POST["përmbajtje"]))( jehonë "Përmbajtja: ".$_POST["përmbajtja"]."
"; ) else ( jehonë "Përmbajtja: Asnjë.""
"; ) //Kontrollo të dhënat hyrëse për praninë e një skedari "skedar" të bashkangjitur nëse (!empty($_FILES["file"])) ($finfo = pathinfo($_FILES["file"]["emri" ]); / /merr informacion rreth skedarit (emri, zgjerimi, etj.) //Kontrollo llojin e skedarit në listën e llojeve të lejuara(IMPROVIZIM:)) nëse (stripos("jpgpnggif",$finfo["extension"] )==0)( echo ">>>>>>>Lloji i skedarit të pavlefshëm<<<<<<<<"; exit; //Если не допустим тип, полностью останавливаем скрипт } $fname = "files/" . "testimgfile." . $finfo["extension"]; //формируем путь и новое имя файла move_uploaded_file($_FILES["file"]["tmp_name"],$fname);//сохраняем временный файл "tmp_name" в файл $fname echo "http://".$_SERVER["HTTP_HOST"]."/".$fname; //возвращаем полный путь к файлу } ?>

shënim! Kur ruani (nëpërmjet notepad), duhet të specifikoni kodimin "UTF-8", përndryshe do të ketë probleme me shfaqjen cirilike!

Skenari u përpoq të jepte komente të hollësishme. Kopjojeni këtë skript në serverin tuaj të uebit, nëse nuk ka, mund të përdorni skriptin tim për testin, ai ndodhet në: http://api.php

Paraqitja përdor komponentët e mëposhtëm: Label, Button(2pcs), Edit(2pcs), Memo(2pcs), CheckBox, OpenDialog, IdHTTP. Emërtoni komponentët e mëposhtëm (vetia " Emri”):

  1. Redakto (titull) - emër=titull;
  2. Redakto (rruga drejt skedarit) emri=imgfile;
  3. Memo (Përmbajtja)emri = përmbajtja;
  4. Memo (Rezultati) - emri = përgjigje;
  5. Butoni (...) - Emri = chkfile;
  6. Butoni (POST) Emri = PostPor;
  7. OpenDialog (Dialog për zgjedhjen e skedarit) - Emri = PictDialog;

Ne do të lëmë IdHTTP1 dhe CheckBox1 të pandryshuara (të lodhur! :)))).

Për të mos u aksidentuar redaktoni» rruga për të redaktuar( imgfile), vendosi pronësinë e tij ReadOnly në True. Po kështu, në imgfile dhe chkfile vendosni veçorinë Enabled në false. Ne do t'i aktivizojmë ato duke përdorur CheckBox d.m.th. Le të japim mundësinë për të zgjedhur nëse do të ngarkoni një imazh apo jo.

Për OpenDialog( PictDialog) duhet të vendosni filtrin (vetia Filter) si më poshtë:

Në fakt përgatitja vizuale ka mbaruar! Le të fillojmë të kodojmë!

Në projekt, ne do të formojmë një rrjedhë të dhënash duke përdorur llojin që vjen me Indy - TidMultiPartFormDataStream. Edhe pse hasa në opsione zbatimi në TStream, por duke punuar me TidMultiPartFormDataStream - më lehtë!

Për ta bërë këtë lloj të disponueshëm për projektin tonë, duhet të shtojmë bibliotekën e mëposhtme te Uses: IdMultipartFormData.

Për CheckBox1, krijoni një ngjarje OnClick (duke klikuar dy herë mbi objekt) dhe shtoni kodin e mëposhtëm në këtë ngjarje:

Procedura TForm1.CheckBox1Click(Dërguesi: TObject); fillo //bëj elemente aktive ose joaktive të shtegut të skedarit dhe butonave të dialogut imgfile.Enabled:=CheckBox1.Checked; chkfile.Enabled:=CheckBox1.Checked; fundi;

Këtu aktivizojmë objektet imgfile dhechkfile në varësi të pranisë së një shenje (nëse kutia e kontrollit është e kontrolluar, atëherë objektet bëhen aktive).

Tani le të organizojmë përzgjedhjen e imazhit. Për ta bërë këtë, krijoni një ngjarje OnClick në butonin chkfile(gjithashtu duke klikuar dy herë mbi objekt) dhe shkruani sa vijon:

Procedura TForm1.chkfileClick(Dërguesi: TObject); filloni //hapni dialogun dhe futni rrugën e plotë të skedarit në imgfile(TEdit) nëse PictDialog.Execute pastaj imgfile.Text:= PictDialog.FileName; fundi;

Kjo ngjarje do të shkaktojë një dialog për përzgjedhjen e imazhit dhe nëse përdoruesi klikon " Hapur”, atëherë do t'i shtohet shtegu i këtij skedari imgfile.

Dhe tani kemi ardhur te butoni përfundimtar "POST". Krijoni një ngjarje OnClick për këtë buton dhe shtoni kodin e mëposhtëm:

Procedura TForm1.PostButClick(Dërguesi: TObject); var dataPost:TIdMultiPartFormDataStream; start dataPost:=TIdMultiPartFormDataStream.Create; dataPost.AddFormField("title",title.Text,"utf-8").ContentTransfer:= "8bit"; dataPost.AddFormField("content",content.Text,"utf-8").ContentTransfer:= "8bit"; nëse CheckBox1.Checked dhe (trim(imgfile.Text)="") atëherë //kontrolloni nëse një skedar është zgjedhur ose nuk fillon ShowMessage("Duhet të zgjidhni një skedar grafik!"); dalje; fundi; nëse CheckBox1.Checked atëherë dataPost.AddFile("skedar",imgfile.Text,""); //shto fushë me përgjigje skedari.Text:= StringReplace(idHTTP1.Post("http://api..php",dataPost)"
",#13#10,); postim i të dhënave. Falas; fund;

Pra, me radhë (megjithëse ka komente):

Posta e të dhënave - objekt i llojit TIdMultiPartFormDataStream. Ju lejon të krijoni një strukturë të kërkesës POST të përbërë nga fusha të llojeve të ndryshme.

postimi i të dhënave . AddFormField (" titullin ", titullin . Teksti ," utf -8 "). transferimi i përmbajtjes := " 8 pak "; – shton një fushë të quajtur "title" në DataPost, vlerën nga "title.Text", vendos kodimin e të dhënave të transmetuara në "utf-8" (parametri nuk kërkohet, por pa treguesin e tij të qartë, alfabetin cirilik transmetohet me pikëpyetje “?”) dhe një metodë shumë e rëndësishme “Transferimi i përmbajtjes”. Pa këtë metodë, të dhënat dërgohen në server " abrakadabra". Ju lutemi vini re se emri i fushës ("titulli") në anën transmetuese duhet të përputhet me emrin e specifikuar në skript: $_POST["titulli"].

Në mënyrë të ngjashme, të dhënat transmetohen në fushën "përmbajtja".

postimi i të dhënave . skedar shtesë (" dosje ", imgfile . Teksti ,"") - me këtë rresht formojmë një rrymë me të dhëna nga një skedar.

Gjithçka, të dhënat gjenerohen, mbetet për ta transferuar atë në skriptin në server dhe për të marrë një përgjigje:

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

sepse TMemo nuk e kupton etiketën e ndërprerjes së linjës "
”, do të përdorim funksionin “ ” për ta zëvendësuar me karaktere të kuptueshme të ndërprerjes së rreshtit “#13#10”.

Pas përfundimit të gjithçkaje, ne pastrojmë kujtesën nga objekti DataPost me rreshtin:

datapost.Falas;

Edhe pse në shembullin tonë kjo do të ndodhë automatikisht në fund të procedurës, por ende ...

Në fakt rezultati i programit në ekran:

Kështu, ne mund të dërgojmë çdo të dhënë, skedar në server, t'i përpunojmë këto të dhëna në server dhe t'i tregojmë aplikacionit rezultatin e ekzekutimit të skriptit si përgjigje. Mund të jetë edhe vetëm 0 ose 1, gjë që do t'i sinjalizojë aplikacionit të reagojë më tej.

Të gjitha. Ju uroj fat të gjithëve. Shpresoj se informacioni ishte i dobishëm dhe ju do ta gjeni të dobishëm.

Shembulli dhe skripti i gatshëm që mund të shkarkoni.

Kodi i plotë i modulit:

Njësia PostNjësia; ndërfaqja përdor Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent, IdComponent, IdTCPdC IdHTTP, IdMultipartFormData, Vcl.ExtDlgs; tipi TForm1 = class(TForm) IdHTTP1: TIdHTTP; titulli: TEdit; përmbajtja: TMemo; PostBut: TButton; përgjigje: TMemo; Label1: T Label; Label2: T Label; Label3: T Label; imgfile: TEdit; chkfile: TButton; Label4: T Label; CheckBox1: TCheckBox; PictDialog: TOpenDialog; procedura PostButClick(Dërguesi: TObject); procedura chkfileClick(Dërguesi: TObject); procedura CheckBox1Click(Dërguesi: TObject); private (Deklarata private) publike (Deklarata publike) fund; var Form1: TForm1; procedura e zbatimit ($R *.dfm) TForm1.CheckBox1Click(Dërguesi: TObject); fillo //bëj elemente aktive ose joaktive të shtegut të skedarit dhe butonave të dialogut imgfile.Enabled:=CheckBox1.Checked; chkfile.Enabled:=CheckBox1.Checked; fundi; procedura TForm1.chkfileClick(Dërguesi: TObject); filloni //hapni dialogun dhe futni rrugën e plotë të skedarit në imgfile(TEdit) nëse PictDialog.Execute pastaj imgfile.Text:= PictDialog.FileName; fundi; procedura TForm1.PostButClick(Dërguesi: TObject); var dataPost:TIdMultiPartFormDataStream; start dataPost:=TIdMultiPartFormDataStream.Create; dataPost.AddFormField("title",title.Text,"utf-8").ContentTransfer:= "8bit"; dataPost.AddFormField("content",content.Text,"utf-8").ContentTransfer:= "8bit"; nëse CheckBox1.Checked dhe (trim(imgfile.Text)="") atëherë //kontrolloni nëse një skedar është zgjedhur ose nuk fillon ShowMessage("Duhet të zgjidhni një skedar grafik!"); dalje; fundi; nëse CheckBox1.Checked atëherë dataPost.AddFile("skedar",imgfile.Text,""); //shto fushë me përgjigje skedari.Text:= StringReplace(idHTTP1.Post("http://api..php",dataPost)"
",#13#10,); postim i të dhënave. Falas; fund; fund.

Indy është një paketë mjaft e fuqishme e komponentëve që ju lejon të zhvilloni aplikacione të ndryshme rrjeti. Në këtë tutorial, unë do t'ju tregoj se si mund të krijoni aplikacione klient-server duke përdorur komponentët TIdTCPClient dhe TIdTCPServer.

Para së gjithash, do të doja të shënoja dy avantazhe të rëndësishme të këtyre komponentëve. Më e rëndësishmja prej tyre është multithreading, që do të thotë se serveri krijon një thread të veçantë për secilin klient, dhe kjo sigurisht që ndikon në performancën e programit të serverit në kompjuterët me një procesor multi-core. Përparësia e dytë është lehtësia e përdorimit. 10-20 rreshta kodi janë të mjaftueshme për të shkruar një aplikacion të thjeshtë klient-server. Kjo paketë komponentësh është e pranishme në asambletë standarde Delphi.

Le të shkruajmë një program të thjeshtë që ju lejon të dërgoni një mesazh me tekst nga një klient në një server. Le të fillojmë krijimin e një serveri.
Vendosni komponentin IdTCPServer në formularin nga skeda Indy Servers. Ne do të bëjmë të gjitha cilësimet për këtë komponent në kohën e ekzekutimit në ngjarjen OnCreate të formularit:
IdTCPServer1.DefaultPort:= 12345;
IdTCPServer1.Active:= e vërtetë;
Gjithçka është e thjeshtë këtu - ne specifikojmë portën në të cilën do të funksionojë serveri dhe aktivizojmë vetë serverin.

Për të marrë të dhëna në server nga klienti, ekziston një ngjarje e veçantë "OnExecute". Kjo ngjarje duket si kjo:

fillojnë
fundi;

Le të modifikojmë përmbajtjen e ngjarjes si më poshtë:
procedura TForm3.IdTCPServer1Execute(AContext: TIdContext);
var
l:string; // variabël string në të cilin do të marrim
fillojnë
l:= AContext.Connection.IOHandler.ReadLn();
Memo1.Linjat.Add(l);
fundi;

Tani, sapo të arrijë një mesazh në server, ne do ta shkruajmë atë në variablin e vargut l dhe do ta shfaqim atë në një fushë teksti me shumë rreshta.

Në të, pasi nuk është për t'u habitur, krijimi i serverit përfundon. Gjithçka tjetër do të bëjë Indy për ne. Le të fillojmë me programin e klientit. Do të lidhet me serverin, do t'i dërgojë një mesazh dhe do të shkëputet nga serveri.

Le të krijojmë një projekt të ri, vendosim komponentin IdTCPClient në formular, i cili mund të gjendet në skedën "Indy Clients". Ne gjithashtu do të vendosim një Edit të thjeshtë dhe një buton. Le të krijojmë një mbajtës të ngjarjeve OnClick për butonin, brenda të cilit do të shkruajmë:
IdTCPClient1.Port:= 12345;
IdTCPClient1.Host:= '127.0.0.1';
IdTCPClient1.Connect;
IdTCPClient1.IOHandler.WriteLn(Edit1.Text);
IdTCPClient1.Disconnect;

Ky kod nuk duhet të vendoset në ngjarjen OnCreate. Ju mund ta vendosni këtë kod kudo që dëshironi.
Në rreshtin e parë, ne caktojmë një port dhe duhet të specifikojmë të njëjtin port siç kemi treguar në programin e serverit, përndryshe klienti thjesht nuk do ta gjejë serverin. Pastaj vendosni adresën IP të serverit. Vetë serveri mund të vendoset si në rrjetin lokal ashtu edhe në distancë. Në rastin e fundit, lidhja do të bëhet përmes Internetit dhe do t'ju duhet të specifikoni adresën IP në internet.

Kam specifikuar adresën "127.0.0.1", e cila tregon se serveri është kompjuteri në të cilin klienti po funksionon. Kjo metodë është shumë e përshtatshme për testimin e aplikacioneve të rrjetit.
Më pas lidhemi, dërgojmë një mesazh dhe shkëputemi.Si dhe vetë mesazhi, mund të merrni edhe adresën IP nga Edit ose nga ndonjë variabël string.

Puna në programin e klientit gjithashtu ka përfunduar. Siç mund ta shihni, Indy bën një punë të jashtëzakonshme për ne, gjë që bën të mundur që edhe një programues pa përvojë të krijojë aplikacionin e tij të rrjetit.

E re në vend

>

Më popullorja