տուն բազմամյա ծաղիկներ Delphi-ում Indy-ի օգտագործմամբ հաճախորդ-սերվերի հավելվածների մշակում: Դելֆիում օգտագործվող Indy բաղադրիչները: Indy բաղադրիչների օգտագործման որոշ օրինակներ

Delphi-ում Indy-ի օգտագործմամբ հաճախորդ-սերվերի հավելվածների մշակում: Դելֆիում օգտագործվող Indy բաղադրիչները: Indy բաղադրիչների օգտագործման որոշ օրինակներ

Բավականին լավ UDP արձանագրություն փոխանցման համար տեքստային հաղորդագրություններ, այսինքն՝ կարող ես կազմակերպել տեղական զրույցներև նման բաներ: Ես որոշեցի բերել Դելֆիում UDP-ի հետ ամենապարզ աշխատանքի օրինակը:

Քայլ առ քայլ հրահանգ:

Ես օրինակ բերեցի, բայց դուք ներեցեք ինձ, ես չեմ սկսել նկարել յուրաքանչյուր տող, քանի որ Ես ոչ մի բարդ բան չեմ տեսնում, և յուրաքանչյուրը կարող է դա պարզել:

Իրականում, եթե ինչ-որ բան պարզ չէ, կարող եք ինձ հարց տալ. Եվ ահա իրական կոդը.

օգտագործում է
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Երկխոսություններ, StdCtrls, IdUDPServer, IdBaseComponent, IdComponent, IdUDPBase,
IdUDPClient, IdSocketHandle;

տիպ
TForm1 = դաս (TForm)
IdUDPClient1. TIdUDPClient;
IdUDPServer1. TIdUDPServer;
Կոճակ 1. TButton;
Պիտակ 1. T Label;
ընթացակարգ FormCreate (Ուղարկող՝ TObject);
ընթացակարգ FormClose (Ուղարկող՝ TObject; var Գործողություն՝ TCloseAction);
ընթացակարգը Button1Click(Ուղարկող՝ TObject);
ընթացակարգ IdUDPServer1UDRead (AThread՝ TIdUDPListenerThread; AData՝ TBytes;
ABinding՝ TIdSocketHandle);
մասնավոր
(Մասնավոր հայտարարություններ)
հանրային
(Հրապարակային հայտարարություններ)
վերջ;

var
Ձև 1. TForm1;

($R *.dfm)
[b]//Հաղորդագրություն ուղարկելու կարգը
ընթացակարգ TForm1.Button1Click(Ուղարկող՝ TObject);
սկսել
փորձել
IdUDPClient1.Active:= Ճշմարիտ;
IdUDPClient1.Host:= «localhost»;
IdUDPClient1.Connect;
եթե IdUDPClient1.Connected, ապա
սկսել
IdUDPClient1.Send(TimeToStr(Time));
Label1.Caption:= «ok»;
վերջ;
IdUDPClient1.Active:= False;
Բիփ;Բիփ;Բիփ;
բացի
MessageDlg ("Սխալ առաջացավ =(", mtError, , 0);
վերջ;
վերջ;
[բ]
//Միացում անջատում. UDP սերվերը ձևի մեկնարկի և փակման վրա
ընթացակարգ TForm1.FormClose(Ուղարկող՝ TObject; var Գործողություն՝ TCloseAction);
սկսել
IdUDPServer1.Active:= False;
վերջ;

ընթացակարգ TForm1.FormCreate (Ուղարկող՝ TObject);
սկսել
IdUDPServer1.Active:= Ճշմարիտ;
վերջ;

[b]//Տվյալների ստացման ժամանակ սերվերի արձագանքման կարգը
ընթացակարգ TForm1.IdUDPServer1UDRead(AThread՝ TIdUDPListenerThread;
AData: TBytes; ABinding՝ TIdSocketHandle);
Վար
i: Ամբողջ թիվ;
s:string;
սկսել
s:="";
փորձել
i:= 0;
մինչդեռ (AData[i] 0) անել
սկսել
s:= s + chr(AData[i]);
i:= i + 1;
վերջ;
վերջապես
Label1.Caption:= s;
վերջ;
վերջ;

Մի խոսքով, Indy-ն բաղադրիչներ է հանրաճանաչ ինտերնետային արձանագրությունների հետ հարմար աշխատանքի համար: Նրանց գործունեության սկզբունքը հիմնված է արգելափակման ռեժիմում վարդակների օգտագործման վրա: Ինդին հետաքրքիր և հարմար է նրանով, որ բավականին վերացական է։ Իսկ Indy-ում ծրագրավորումը իջնում ​​է գծային ծրագրավորման: Ի դեպ, համացանցում լայն տարածում է գտել մի թարգմանված հոդված, որում գրված է «արգելափակման ռեժիմը սատանան չէ» :)) Ժամանակին ինձ շատ զվարճացրեց այս թարգմանությունը։ Հոդվածը Հուվերի և Հարիրիի «Ինդիի խորքերը» գրքի մի մասն է։ Սկզբունքորեն, Indy-ի հետ աշխատելու համար պետք չէ ընդհանրապես կարդալ այն, բայց ես դեռ խորհուրդ եմ տալիս ծանոթանալ ինտերնետ արձանագրությունների սկզբունքներին: Ինչ վերաբերում է «սատանայական» ռեժիմին. Արգելափակող վարդակից զանգը իրականում չի վերադառնում, քանի դեռ չի կատարել իր առաջադրանքը: Երբ զանգեր են կատարվում հիմնական շղթայի վրա, հավելվածի միջերեսը կարող է կախվել: Այս տհաճ իրավիճակից խուսափելու համար հնդիկ մշակողները ստեղծել են TIdAntiFreeze բաղադրիչը։ Բավական է պարզապես նետել այն ձևաթղթի վրա, և օգտատիրոջ միջերեսը հանգիստ կվերանկարվի զանգերի արգելափակման ժամանակ:

Դուք հավանաբար արդեն ծանոթացել եք Դելֆիի տարբեր «Indy (...)» ներդիրների բովանդակությանը: Բաղադրիչները շատ են, և դրանցից յուրաքանչյուրը կարող է օգտակար լինել: Ես ինքս բոլորի հետ չեմ աշխատել, քանի որ առանց կոնկրետ առաջադրանքի ուսումնասիրելու անհրաժեշտություն չեմ տեսնում։

Delphi-ի բազային բաշխումը ներառում է Indy v.9-ը կոպեկներով: Հավանաբար, ցանկալի է անմիջապես թարմացնել ավելին նոր տարբերակ(օրինակ, ես հիմա ունեմ 10.0.76, բայց կան նաև ավելի ուշ):

Կան հաճախորդի և սերվերի բաղադրիչներ՝ նույն արձանագրությունների հետ աշխատելու համար: Indy-ն իսկապես հեշտացնում է հավելվածների մշակումը, ի տարբերություն վարդակների վրա նույն ֆունկցիոնալությունը մշակելու տարբերակի։ Օրինակ, սերվերին միանալու համար պարզապես անհրաժեշտ է զանգահարել Connect մեթոդը: Հաջողակ կապի հաստատումը կնշվի մեթոդից վերադարձով` առանց բացառության բարձրացման: Եթե ​​կապը հաստատված չէ, բացառություն կկատարվի:

«Ակադեմիական» օրինակ (կոդը չի աշխատում, մի գործարկեք :)):

IndyClient-ի միջոցով
սկսել
Հոսթ:= «test.com»;
Նավահանգիստ:= 2000;
միացնել;
փորձել
// աշխատել տվյալների հետ (կարդալ, գրել...)
վերջապես
Անջատել;
վերջ;
վերջ;

Հոսթն ու պորտը կարող են սահմանվել օբյեկտի տեսուչում կամ գործարկման ժամանակ:

Ինչի՞ համար կարող են օգտագործվել Indy բաղադրիչները վերլուծության առաջադրանքներում: Դիմումը բազմազան է! Ամենապարզը էջի բովանդակությունը ստանալն է (բոլորը հավանաբար արդեն հանդիպել են դրան) օգտագործելով IdHTTP բաղադրիչը.

Վար
rcvdata:TMemoryStream;
idHttp1: TidHttp;
սկսել
idHttp1:= TidHttp.Create(nil);
rcvdata:= TMemoryStream.Create;
idHttp1.Request.UserAgent:= "Mozilla/4.0 (համատեղելի; MSIE 5.5; Windows 98)";
idHttp1.Request.AcceptLanguage:= «en»;
idHttp1.Response.KeepAlive:= ճշմարիտ;
idHttp1.HandleRedirects:= ճշմարիտ;
փորձել
idHttp1.Get (Edit1.Text, rcvdata);
վերջապես
idHttp1.Free;
վերջ;
եթե rcvrdata.Size > 0, ապա սկսեք
ShowMessage ("Ստացված" + inttostr(rcvrdata.Size));
rcvrdata.SaveToFile ("c:\111.tmp");
վերջ;
rcvrdata.Free;
վերջ;

Ինչպես տեսնում եք, դուք կարող եք ոչ միայն ստանալ էջի բովանդակությունը, այլև մոդելավորել փաստաթղթի բեռնումը կոնկրետ հաճախորդից: Indy բաղադրիչներընդհանուր առմամբ հարմար են վերնագրերի և POST հարցումների ձևավորման համար: Այս մասին ավելի շատ հաջորդ անգամ օրինակներով:

Բլոգի թարմացումներին արդի մնալու համար կարող եք

Ներածություն Indy

Ներածություն Indy
Հեղինակ՝ Chad Z. Hower
Գլխավոր էջ՝ http://www.atozedsoftware.com
Թարգմանություն՝ Անատոլի Պոդգորեցկի
ներածություն
Ես գրել եմ այս հոդվածը, երբ ներկայիս տարբերակը Indy 8.0-ն էր: Այս հոդվածի մեծ մասը կիրառելի է և շատ օգտակար Indy-ի հետագա տարբերակներում: Եթե ​​ձեզ դուր եկավ այս հոդվածը և ցանկանում եք կարդալ ավելի մանրամասն հոդվածներ, ապա դիտեք Indy in Depth գիրքը:
Indy-ն աշխատում է արգելափակման ռեժիմում
Indy-ն օգտագործում է արգելափակող վարդակներ: Արգելափակման ռեժիմը նման է ֆայլ կարդալ-գրելուն: Տվյալները կարդալիս կամ գրելիս գործառույթը չի վերադարձնում կառավարումը մինչև գործողության ավարտը: Ֆայլերի հետ աշխատելու տարբերությունն այն է, որ զանգը կարող է ավելի երկար լինել, քանի որ պահանջվող տվյալները դեռ հասանելի չեն, դա կախված է ձեր ցանցի կամ մոդեմի աշխատանքի արագությունից:
Օրինակ, պարզապես մեթոդական զանգ կատարեք և սպասեք, մինչև վերահսկողությունը վերադարձվի զանգահարողին: Եթե ​​զանգը հաջող էր, ապա վերահսկումը կվերադարձվի մեթոդից, սխալի դեպքում բացառություն կբարձրացվի:
Արգելափակման ռեժիմը մահացու չէ
Արգելափակման ռեժիմի պատճառով մենք բազմիցս ծեծի ենք ենթարկվել մեր հակառակորդների կողմից, բայց արգելափակման ռեժիմը սատանան չէ:
Խնդիրն առաջացել է Winsock-ը Windows-ում տեղափոխելուց հետո: Unix-ում խնդիրը սովորաբար լուծվում էր պատառաքաղով (նման է բազմաթելային, բայց հաշվին անհատական ​​գործընթացներհոսքերի փոխարեն): Unix-ի հաճախորդները և դևերը պետք է գործարկեին գործընթացները և օգտագործեին արգելափակման ռեժիմը: Windows 3.x-ը չկարողացավ զուգահեռականացնել և չէր աջակցում բազմաշերտ: Արգելափակող ինտերֆեյսի օգտագործումը սառեցրեց օգտատիրոջ միջերեսը և չպատասխանեց ծրագրերին: Ուստի WinSock-ին ավելացվեցին չարգելափակող ռեժիմներ՝ թույլ տալով Windows 3.x-ին՝ իր սահմանափակումներով, օգտագործել Winsock-ը՝ առանց արգելափակելու հիմնական և միակ ծրագրի շարանը։ Սա պահանջում էր տարբեր ծրագրավորում, Microsoft-ը և մյուսները խստորեն դատապարտում էին արգելափակման ռեժիմները թաքցնելու համար Windows-ի թերությունները 3.x.
Այնուհետև եկավ Win32-ը, որն ի վիճակի էր աջակցել բազմաշերտ թրեյդինգին: Բայց այս պահին ուղեղներն արդեն փոշիացել էին (այսինքն՝ ծրագրավորողները վարդակների արգելափակումը համարում էին սատանայի արդյունք), և արդեն դժվար էր փոխել իրենց արածը։ Հետևաբար, արգելափակող ռեժիմների հայհոյանքը շարունակվում է։
Իրականում Unix-ն ունի միայն արգելափակող վարդակներ: Արգելափակող վարդակները նույնպես ունեն իրենց առավելությունները, և դրանք շատ ավելի լավն են՝ շատ թելերի, անվտանգության և այլ ասպեկտների համար: Որոշ ընդլայնումներ ավելացվել են նաև Unix-ին՝ չարգելափակող վարդակների համար: Այնուամենայնիվ, նրանք աշխատում են շատ այլ կերպ, քան Windows-ում: Նրանք նույնպես ոչ ստանդարտ են և ոչ շատ տարածված: Unix-ում արգելափակող վարդակները օգտագործվում են գրեթե բոլոր դեպքերում և կշարունակվեն օգտագործվել:
Արգելափակման ռեժիմի առավելությունները Ավելի հեշտ է ծրագրավորել - Արգելափակման ռեժիմներն ավելի հեշտ են ծրագրավորվում: Օգտագործողի բոլոր ծածկագրերը կարող են լինել մեկ տեղում և գործարկվել բնական, հաջորդական կարգով: Ավելի հեշտ տեղափոխում Unix - Քանի որ Unix-ն օգտագործում է արգելափակող վարդակներ, շարժական կոդը պետք է գրվի այս դեպքըավելի հեշտ. Indy-ն օգտագործում է այս փաստը՝ հետևողական կոդ գրելու համար: · Թելերի հետ աշխատելու համար ավելի հարմար - Քանի որ արգելափակող վարդակները ունեն ժառանգականությամբ ձեռք բերված հաջորդականություն, ուստի դրանք շատ հեշտ են օգտագործել թելերում:
Արգելափակման ռեժիմի թերությունները UI-ն սառեցնում է հաճախորդների մեջ - Արգելափակող վարդակից զանգը չի վերադառնում, քանի դեռ չի կատարել իր առաջադրանքը: Երբ նման զանգ է կատարվում հավելվածի հիմնական թեմայում, հավելվածը չի կարող մշակել օգտվողի հաղորդագրությունները: Այդ պատճառով օգտատիրոջ միջերեսը սառեցված է, պատուհանները չեն թարմացվում, և այլ հաղորդագրությունները չեն կարող մշակվել, քանի դեռ վերահսկողությունը չի վերադարձվել արգելափակող վարդակից:
TIdAntiFreeze բաղադրիչ
Indy-ն ունի հատուկ բաղադրիչ, որը լուծում է սառեցման խնդիրը օգտագործողի ինտերֆեյս. Պարզապես ավելացրեք մեկ TIdAntiFreeze բաղադրիչ ձեր հավելվածի ցանկացած վայրում, և դուք կարող եք արգելափակող զանգեր կատարել՝ առանց օգտագործողի միջերեսը սառեցնելու:
TIdAntiFreeze-ն աշխատում է զանգերի կույտից դուրս գտնվող ներքին ժամանակաչափով և կանչում է Application.ProcessMessages, երբ ժամկետը լրանում է: Արտաքին զանգերը դեպի Indy շարունակում են արգելափակվել և, հետևաբար, աշխատում են ճիշտ այնպես, ինչպես առանց TIdAntiFreeze բաղադրիչի օգտագործման: TIdAntiFreeze-ի օգտագործումը թույլ է տալիս ստանալ վարդակների արգելափակման բոլոր առավելությունները՝ առանց թերությունների:
Կոդի հոսքեր (Threading)
Արգելափակող վարդակները գրեթե միշտ օգտագործում են կոդերի հոսքեր: Չարգելափակող վարդակները կարող են նաև օգտագործել հոսքեր, սակայն դա պահանջում է որոշակի լրացուցիչ մշակում, և դրանց առավելություններն այս դեպքում կորչում են՝ համեմատած արգելափակող վարդակների հետ:
Թելերի առավելությունները · Առաջնահերթությունների սահմանում - Առանձին թելերի առաջնահերթությունները կարող են կազմաձևվել: Սա թույլ է տալիս CPU-ի քիչ թե շատ ժամանակ հատկացնել առանձին առաջադրանքներին: · Էկապսուլյացիա - Յուրաքանչյուր միացում կարող է պարունակել ինտերֆեյսի որոշակի տեսք մեկ այլ կապի հետ: · Անվտանգություն – Յուրաքանչյուր թեմա կարող է ունենալ անվտանգության տարբեր հատկանիշներ: · Բազմաթիվ պրոցեսորներ - առավելություն է տալիս բազմաթիվ պրոցեսորներով համակարգերին: · Սերիալացման կարիք չկա - ապահովում է ամբողջական համաժամանակություն: Առանց շատ թելերի, բոլոր հարցումները պետք է մշակվեն մեկ թեմայում: Հետևաբար, յուրաքանչյուր առաջադրանք պետք է բաժանվի փոքր կտորների, որպեսզի այն կարողանա արագ աշխատել: Մինչ մեկ բլոկը կատարվում է, մնացած բոլորը ստիպված են սպասել դրա ավարտին: Մեկ բլոկի վերջում կատարվում է հաջորդ բլոկը և այլն։ Multithreading-ի միջոցով յուրաքանչյուր առաջադրանք կարող է ծրագրավորվել որպես մեկ և օպերացիոն համակարգժամանակ է բաշխում բոլոր առաջադրանքների միջև:
Թեմայի հարցում
Թելերի ստեղծումն ու ոչնչացումը շատ ռեսուրսներ են պահանջում: Սա հատկապես դժվար խնդիր է սերվերների համար, որոնք ունեն կարճատև կապեր: Յուրաքանչյուր սերվեր ստեղծում է թեմա, օգտագործում այն կարճ ժամանակիսկ հետո ոչնչացնում է: Սա հանգեցնում է թեմաների շատ հաճախակի ստեղծման և ջնջման: Դրա օրինակն է վեբ սերվերը: Մեկ հարցում է ուղարկվում, և պարզ պատասխանը վերադարձվում է: Հարյուրավոր միացումներ և անջատումներ կարող են առաջանալ վեբ կայք զննարկելիս զննարկիչ օգտագործելիս:
Հարցումների թեմաները կարող են շտկել այս իրավիճակը: Ըստ պահանջի թելեր ստեղծելու և ոչնչացնելու փոխարեն, թելերն ընտրվում են չօգտագործված, բայց արդեն ստեղծված թելերի ցանկից՝ լողավազանից: Երբ թելն այլևս անհրաժեշտ չէ, այն ոչնչացվելու փոխարեն վերադարձվում է լողավազան։ Լողավազանի թելերը նշված են որպես չօգտագործված և, հետևաբար, դրանք չեն ծախսում պրոցեսորի ժամանակ: Ավելին ավելի շատ բարելավումհոսքերը կարող են դինամիկ կերպով հարմարվել համակարգի ընթացիկ կարիքներին:
Indy-ն աջակցում է թեմայի հարցում: The Thread Pool-ը Indy-ում հասանելի է TIdThreadMgrPool բաղադրիչի միջոցով:
Բազմաթիվ Թելեր
Խիստ բեռնված սերվերը կարող է պահանջել հարյուրավոր կամ նույնիսկ հազարավոր թեմաներ: Ընդհանուր համոզմունք կա, որ հարյուրավոր և հազարավոր թելերը կարող են սպանել ձեր համակարգը: Սա սխալ համոզմունք է։
Սերվերների մեծ մասում շղթաները սպասում են տվյալների: Արգելափակող զանգի սպասելիս շարանը անգործուն է: 500 շղթա ունեցող սերվերում միայն 50-ը կարող է միաժամանակ ակտիվ լինել։
Ձեր համակարգում աշխատող թեմաների քանակը կարող է ձեզ զարմացնել: ժամը նվազագույն քանակաշխատող սերվերները և նշված գործող հավելվածները, իմ համակարգում ստեղծվել է 333 թեմա, նույնիսկ 333 թելերով, պրոցեսորը բեռնված է ընդամենը 1%-ով: Խիստ բեռնված IIS սերվեր ( Microsoft ինտերնետՏեղեկատվական սերվեր) կարող է ստեղծել հարյուրավոր կամ հազարավոր թեմաներ:
Թեմաներ և գլոբալ բաժիններ
Բազմաթիվ թելերով դուք պետք է ապահովեք տվյալների ամբողջականությունը դրանց մուտք գործելիս: Սա կարող է դժվար լինել ոչ թելիկ ծրագրավորողների համար: Բայց, որպես կանոն, սերվերների մեծամասնության համար անհրաժեշտ չէ օգտագործել գլոբալ տվյալներ։ Սերվերների մեծ մասը կատարում է մեկուսացված գործառույթներ: Յուրաքանչյուր շարանը կատարում է իր առանձին առաջադրանքը: Համաշխարհային ընթերցման/գրելու բաժինները շատ բազմաթելային հավելվածների հատկանիշն են, սակայն բնորոշ չեն սերվերներին:
Մեթոդաբանություն Indy
Indy-ն տարբերվում է Winsock-ի այլ բաղադրիչներից, որոնց դուք սովոր եք: Եթե ​​դուք աշխատել եք այլ բաղադրիչների հետ, ապա լավագույն լուծումըկմոռանա, թե ինչպես են նրանք աշխատում: Շատ այլ բաղադրիչներ օգտագործում են ոչ արգելափակող (ասինխրոն) զանգեր և գործում են ասինխրոն: Նրանք պետք է արձագանքեն իրադարձություններին, ստեղծեն պետական ​​մեքենա և հաճախակի սպասման օղակներ կատարեն:
Օրինակ, այլ բաղադրիչների դեպքում, երբ զանգում եք միացում, դուք կամ պետք է սպասեք միացման իրադարձության գործարկմանը, կամ պտտեք հատկությունը՝ ցույց տալու, որ կապը տեղի է ունեցել: Indy-ի հետ դուք կարող եք զանգահարել Connect մեթոդը և ակնկալել, որ այն կվերադառնա: Վերադարձը կկատարվի, եթե կապը հաջող է, կամ եթե բացառություն է արվում, եթե խնդիր կա: Հետևաբար, Indy-ի հետ աշխատելը շատ նման է ֆայլերի հետ աշխատելուն: Indy-ն թույլ է տալիս տեղադրել ձեր ամբողջ կոդը մեկ տեղում՝ այն ամբողջ տարածքով տարածելու փոխարեն տարբեր միջոցառումներ. Բացի այդ, Indy-ն շատ պարզ է և ամենահարմարը թելերի հետ աշխատելիս։
Որքան տարբեր է Ինդին
Համառոտ ակնարկ · Օգտագործում է արգելափակող զանգեր · Իրադարձություններին ուղղված չէ. իրադարձությունները առկա են, բայց դրանք օգտագործվում են տեղեկատվական նպատակներով և իրականում պարտադիր չեն: ·Նախատեսված է թելերի համար - Indy-ն նախատեսված է թելերի համար, սակայն այն կարող է օգտագործվել առանց թելերի: Հաջորդական ծրագրավորում
Մանրամասն դիտարկում
Indy-ն ոչ միայն օգտագործում է արգելափակող զանգեր (սինխրոն), այլ նաև աշխատում է այսպես. Ինդիում տիպիկ նստաշրջանն այսպիսի տեսք ունի.
IndyClient-ով սկսվում է
միացնել; փորձել
// Այստեղ արեք ձեր գործերը
վերջապես Անջատել; վերջ;
վերջ;
Այլ բաղադրիչների հետ այն ունի հետևյալ տեսքը.
ընթացակարգ TFormMain.TestOnClick(Ուղարկող՝ TComponent);
սկսել
SocketComponent-ով սկսվում է
միացնել; փորձել
Մինչ Միացված չէ, սկսվում է
եթե IsError, ապա սկսեք
աբորտ;
վերջ;

OutData: = «Տվյալներ ուղարկելու համար»;
Մինչդեռ երկարությունը (OutData) > 0 սկսվում է
Application.ProcessMessages;
վերջ;
վերջապես Անջատել; վերջ;
վերջ;
վերջ;
ընթացակարգ TFormMain.OnConnectError;
սկսել
IsError:= Ճշմարիտ;
վերջ;
ընթացակարգ TFormMain.OnRead;
var
i: Ամբողջ թիվ;
սկսել
i:= SocketComponent.Send(OutData);
OutData:= Պատճենել (OutData, i + 1, MaxInt);
վերջ;
Բազմաթիվ բաղադրիչներ այնքան էլ լավ չեն կատարում ծրագրավորողին կույտից մեկուսացնելու հարցում: Բազմաթիվ բաղադրիչներ, օգտագործողին կույտի բարդություններից մեկուսացնելու փոխարեն, պարզապես թողնում են օգտատիրոջը դրա հետ մենակ կամ ապահովում են փաթաթան կույտի վրա:
Ինդիի հատուկ ուղին
Indy-ն նախագծված է ի սկզբանե բազմաթելային լինելու համար: Indy-ում սերվերների և հաճախորդների կառուցումը նման է Unix-ում սերվերների և հաճախորդների կառուցմանը: Unix հավելվածները սովորաբար զանգում են ստեկը ուղղակիորեն քիչ կամ առանց աբստրակցիոն շերտի:
Սովորաբար, Unix սերվերներն ունեն մեկ կամ մի քանի լսողի գործընթացներ, որոնք լսում են մուտքային հաճախորդի հարցումները: Յուրաքանչյուր հաճախորդի համար, որը պետք է սպասարկվի, ա նոր գործընթաց. Սա հեշտացնում է ծրագրավորումը, յուրաքանչյուր գործընթաց նախատեսված է միայն մեկ հաճախորդի համար: Յուրաքանչյուր գործընթաց սկսվում է յուրովի սեփական համատեքստանվտանգություն, որը տրվում է լսելու գործընթացի կամ գոյություն ունեցող իրավունքների, ինքնության կամ այլ բաների վրա հիմնված գործընթացի միջոցով:
Indy սերվերներն աշխատում են մոտավորապես նույն կերպ. Windows-ը, ի տարբերություն Unix-ի, չի կարող լավ տարածել պրոցեսները, բայց այն լավ է աշխատում թելերի հետ։ Indy սերվերները ստեղծում են առանձին թեմա յուրաքանչյուր հաճախորդի կապի համար:
Indy սերվերները նշանակում են ունկնդրման թեմա, որը առանձին է ծրագրի հիմնական կոդի հոսքից: Լսողական շարանը լսում է հաճախորդների մուտքային հարցումները: Յուրաքանչյուր հաճախորդի համար այն պատասխանում է՝ ա նոր թեմահաճախորդների սպասարկման համար: Այնուհետեւ համապատասխան իրադարձությունները սպասարկվում են այդ թեմայի համատեքստում:
Indy հաճախորդների ակնարկ
Indy-ն նախատեսված է ապահովելու համար շատ բարձր մակարդակաբստրակցիա։ TCP/IP փաթեթի բարդությունն ու մանրամասնությունը թաքնված են ծրագրավորողից: Indy-ում հաճախորդի տիպիկ նստաշրջանը սովորաբար այսպիսի տեսք ունի.
IndyClient-ով սկսվում է
Հյուրընկալ:= "zip.pbe.com"; // հյուրընկալող զանգելու համար
Նավահանգիստ:= 6000; // Միացք՝ սերվերը միացնելու համար
միացնել; փորձել
// Այստեղ արեք ձեր գործերը
վերջապես Անջատել; վերջ;
վերջ;
Indy սերվերների ակնարկ
Indy սերվերի բաղադրիչները ստեղծում են լսող շարանը, որը մեկուսացված է ծրագրի հիմնական կոդի շղթայից: Լսողական շարանը լսում է հաճախորդների մուտքային հարցումները: Յուրաքանչյուր հաճախորդի համար, որին նա պատասխանում է, նոր թեմա է ստեղծվում հաճախորդին սպասարկելու համար: Այնուհետեւ համապատասխան իրադարձությունները սպասարկվում են այդ թեմայի համատեքստում:

Գործնական օրինակներ
Հետևյալ օրինակները պետք է օգնեն ձեզ սկսելու համար բաղադրիչները հեշտ օգտագործումը, սակայն ցույց տալու համար օրինակներն արված են որպես պարզ հավելվածներ. Որոշ նախագծեր պատրաստված են ցուցադրելու համար տարբեր իրավիճակներ. Այս օրինակները հասանելի են նաև ներբեռնման համար որպես zip ֆայլեր:
Նշում թարգմանիչից. կայքի հղումը չի աշխատում:
Օրինակ 1 - Ինդեքսների ստուգում
Առաջին նախագիծը կատարվում է հնարավորինս պարզ: Փնտրեք փոստային ինդեքսով, հաճախորդը հարցնում է սերվերին, թե որ քաղաքին և նահանգին է պատկանում նշված փոստային կոդը:
Նրանց համար, ովքեր ապրում են ԱՄՆ-ից դուրս և չգիտեն, թե ինչ է փոստային կոդը, սա փոստային ինդեքս է, որը ցույց է տալիս առաքման վայրը: Փոստային ինդեքսները բաղկացած են 5 նիշից:
Արձանագրություն
Սերվերի և հաճախորդի կառուցման առաջին քայլը արձանագրության մշակումն է: Ստանդարտ արձանագրությունների համար դա սահմանվում է համապատասխան RFC-ով: Փոստային կոդի համար արձանագրությունը սահմանվում է ստորև:
Փոխանակման արձանագրությունների մեծ մասը աշխատում է տեքստային ռեժիմում: Փոխանակումը նշանակում է, որ հրաման է ուղարկվում, և պատասխանը վիճակ է և, հնարավոր է, տվյալներ: Արձանագրությունները չեն սահմանափակվում միայն փոխանակմամբ, բայց պարզ տեքստը դեռ օգտագործվում է: Փոստային ինդեքսը որոշելու արձանագրությունը նույնպես տեքստային է։ Պարզ տեքստը հեշտացնում է արձանագրությունների վրիպազերծումը և թույլ է տալիս հաղորդակցվել տարբեր լեզուներովծրագրավորում և օպերացիոն համակարգեր.
Միանալուց հետո սերվերը ողջույնի հաղորդագրություն է ուղարկում, այնուհետև ընդունում է հրամանը: Այս հրամանը կարող է լինել «ZipCode x» (որտեղ x-ը փոստային կոդը) կամ «Quit»: Ի պատասխան ZipCode հրամանի, պատասխանն ուղարկվում է որպես մեկ տող՝ պատասխանի հետ միասին, կամ դատարկ տող, եթե կոդը չի գտնվել: Quit հրամանը ստիպում է սերվերին անջատել կապը: Սերվերը կարող է ընդունել մի քանի հրամաններ՝ նախքան Quit հրամանը ուղարկելը:
Սերվերի աղբյուրի կոդը

unitServerMain;

ինտերֆեյս

օգտագործում է

տիպ

TformMain = դաս (TForm)

IdTCPServer1. TIdTCPServer;

ընթացակարգ FormCreate(Ուղարկող՝ TObject);

ընթացակարգ FormDestroy(Ուղարկող՝ TObject);

ընթացակարգ IdTCPServer1Connect (AThread: TIdPeerThread);

մասնավոր

ZipCodeList՝ TStrings;

հանրային

վերջ ;

FormMain՝ TformMain;

իրականացումը

(R*.DFM)

ընթացակարգ TformMain.IdTCPServer1Connect (AThread: TIdPeerThread) ;

սկսել

AThread.Connection .WriteLn("Indy Zip Code Server Ready.") ;

վերջ ;

SC Հրաման՝ string ;

սկսել

SCCommand:= ReadLn;

վերջ ;

վերջ ;

վերջ ;

ընթացակարգ TformMain.FormCreate (Ուղարկող՝ TObject) ;

սկսել

ZipCodeList:= TStringList.Create;

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

վերջ ;

ընթացակարգ TformMain.FormDestroy (Ուղարկող՝ TObject);

սկսել

ZipCodeList.Free;

վերջ ;

վերջ.

Ծրագրի միակ Indy-ին հատուկ մասերն են IdTCPServer1 բաղադրիչը, IdTCPServer1Connect և IdTCPServer1Execute մեթոդները:
Ձևը պարունակում է TIdTCPServer տեսակի IdTCPServer1 բաղադրիչ: Հետևյալ հատկությունները փոխվել են. · Active = True - Հավելվածի մեկնարկից հետո սերվերը լսում է: ·DefaultPort = 6000 - Port արժեքը համար այս նախագիծը. Սերվերը լսում է հաճախորդի հարցումները այս նավահանգստում:
IdTCPServer1Execute մեթոդը կապված է սերվերի OnExecute իրադարձության հետ: OnExecute իրադարձությունը գործարկվում է հաճախորդի կապն ընդունելուց հետո: OnExecute իրադարձությունը տարբերվում է ձեզ հայտնի այլ իրադարձություններից: OneExecute-ը կատարվում է թեմայի համատեքստում: Թեմայի իրադարձությունը գործարկվում է և փոխանցվում է մեթոդին փոխանցված AThread արգումենտը: Սա կարևոր է, քանի որ մի քանի OneExecute իրադարձություններ կարող են միաժամանակ իրականացվել: Դա արվում է, որպեսզի սերվերը կարողանա աշխատել առանց նոր բաղադրիչ ստեղծելու: Կան նաև մեթոդներ, որոնք կարող են անտեսվել ժառանգներ կառուցելիս:
OnConnect միջոցառումը գործարկվում է այն բանից հետո, երբ միացումն ընդունվել է, և դրա համար թեմա է ստեղծվել: Այս սերվերն օգտագործում է սա հաճախորդին բարևի հաղորդագրություն ուղարկելու համար: Ցանկության դեպքում դա կարելի է անել նաև OnExecute իրադարձության մեջ:
OnExecute իրադարձությունը կարող է մի քանի անգամ գործարկել, մինչև կապն անջատվի կամ չկորչի: Սա վերացնում է իրադարձության շրջանակում կապի անջատման կամ կորստի համար կապը ստուգելու անհրաժեշտությունը:
IdTCPServer1Execute-ն օգտագործում է երկու հիմնական ֆունկցիա՝ ReadLn և WriteLn: ReadLn-ը միացումից տող է կարդում, իսկ WriteLn-ն ուղարկում է միացում:
sCommand:= ReadLn;
Վերոնշյալ կոդը հաճախորդից վերցնում է տող և տեղադրում sCommand տեղական տող փոփոխականի մեջ:

եթե SameText (sCommand, «QUIT»), ապա սկսեք

end else if SameText (Copy (sCommand, 1 , 8 ), «ZipCode» ), ապա սկսեք

WriteLn (ZipCodeList.Values ​​[Պատճեն (sCommand, 9, MaxInt)]);

վերջ ;


Հաջորդը, sCommand-ը ստուգվում է վավեր հրամանների համար:
Եթե ​​հրամանը «Դուրս գալ» է, ապա կատարվում է Անջատում: Անջատումից հետո չի թույլատրվում կարդալ կամ գրել: Միջոցառման ավարտից հետո լսող շարանը այլևս չի կանչում այն, այլ մաքրում է շարանը և դադարեցնում կապը:
Եթե ​​հրամանը «ZipCode»-ն է, ապա հրամանից հետո պարամետրը հանվում է, և աղյուսակը որոնվում է քաղաքի և նահանգի առկայության համար: Այնուհետև քաղաքը և նահանգը փոխանցվում են հաճախորդին, կամ դատարկ տող է փոխանցվում, եթե համընկնում չկա:
Այնուհետև մեթոդը դուրս է գալիս: Սերվերը կրկին կփորձի իրադարձության զանգը հենց այն ժամանելուն պես: նոր թիմ, որը թույլ է տալիս հաճախորդին ուղարկել բազմաթիվ հրամաններ:
Հաճախորդի աղբյուրի կոդը

unitClientMain;

ինտերֆեյս

օգտագործում է

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ExtCtrls, IdAntiFreezeBase,

IdAntiFreeze, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;

տիպ

TformMain = դաս (TForm)

Հաճախորդ՝ TIdTCPClient;

IdAntiFreeze1. TIdAntiFreeze;

Վահանակ 1. TPanel;

Panel2. TPanel;

MemoInput:TMemo;

LboxResults՝ TListBox;

Panel3. TPanel;

Կոճակ 1. TButton;

Կոճակ 2. TButton;

Պիտակ 1. T Label;

ընթացակարգ Button2Click(Ուղարկող՝ TObject);

ընթացակարգը Button1Click(Ուղարկող՝ TObject);

մասնավոր

հանրային

վերջ ;

FormMain՝ TformMain;

իրականացումը

(R*.DFM)

ընթացակարգ TformMain.Button2Click (Ուղարկող՝ TObject) ;

սկսել

MemoInput.Clear;

LboxResults.Clear;

վերջ ;

ընթացակարգ TformMain.Button1Click (Ուղարկող՝ TObject) ;

I: ամբողջ թիվ;

S: լար

սկսել

ButnLookup.Enabled := true; փորձել

LboxResults.Clear;

Հաճախորդի հետ սկսել

միացնել; փորձել

LboxResults.Items .Ավելացնել (ReadLn) ;

i:= 0-ի համար memoInput.Lines .Count - 1-ը սկսվում է

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

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

S:= ReadLn;

եթե s = "" ապա սկսեք

S:= «-- Այս փոստային ինդեքսը մուտքագրված չէ»:;

վերջ ;

LboxResults.Items .Ավելացնել(ներ) ;

LboxResults.Items .Ավելացնել ("");

վերջ ;

WriteLn («Դուրս գալ»);

վերջապես Անջատել; վերջ ;

վերջ ;

վերջապես butnLookup.Enabled := true; վերջ ;

վերջ ;

վերջ.


Հաճախորդի բաղադրիչին բնորոշ միակ մասերը Button1Click մեթոդն է:
Հաճախորդ բաղադրիչը TIdTCPClient տեսակի է և տեղադրված է ձևաթղթի վրա: Հետևյալ հատկությունները փոխվել են. Host = 127.0.0.1 - Սերվերը գտնվում է հաճախորդի հետ նույն մեքենայի վրա: Պորտ = 6000 - Սերվերի նավահանգիստ
Button1Click մեթոդը կապված է Button1 բաղադրիչի OnClick իրադարձության հետ: Երբ կոճակը սեղմվում է, այս մեթոդը կոչվում է: Այս մեթոդի Indy մասը կարող է կրճատվել հետևյալով. 1. Միացում սերվերին (Connect;) 1. Սերվերից բարևի ընթերցում: 1. TMemo-ում օգտագործողի կողմից մուտքագրված յուրաքանչյուր տողի համար. 1. հարցում ուղարկել սերվերին (WriteLn("ZipCode" + memoInput. Lines[i]);) 1. Սերվերի պատասխանի ընթերցում (s:= ReadLn; ) 1. Ուղարկելով Quit հրամանը (WriteLn("Quit");) 1. Անջատել (Անջատել;)
Փորձարկում
Այս օրինակը փորձարկվել է և աշխատում է տեղադրված TCP/IP-ի հետ: Դուք կարող եք փոխել այն, որպեսզի աշխատի ցանցով մեկ համակարգչից մյուսը: Մեկ այլ համակարգչի վրա սերվերը գործարկելու և հաճախորդի վրա սերվերի անունը կամ IP-ն փոխելով:
Նախագծերը փորձարկելու համար կազմեք և գործարկեք սերվերը: Այնուհետև կազմեք և գործարկեք հաճախորդը: Հուշագրության դաշտում մուտքագրեք փոստային կոդը և սեղմեք որոնման ստեղնը:
Վրիպազերծում
Տեքստային արձանագրությունները շատ հեշտ է կարգաբերել, քանի որ դրանք կարող են ստուգվել Telnet-ի միջոցով: Դա անելու համար բավական է իմանալ սերվերի պորտը: Zip Code Lookup Server-ը լսում է 6000 նավահանգիստում:
Կրկին գործարկեք փոստային կոդի որոնման սերվերը: Այնուհետև բացեք վահանակ (օրինակ, Dos պատուհան): Այժմ մուտքագրեք.
տելնետ 127.0.0.1 6000
Դուք այժմ միացված եք սերվերին: Որոշ սերվերներ նաև ողջույնի հաղորդագրություն են ուղարկում: Ոմանք չեն անում: Դուք չեք տեսնի ձեր մուտքագրած տողերը: Սերվերների մեծ մասը չի արձագանքում երթևեկությունը խնայելու համար: Այնուամենայնիվ, դուք կարող եք փոխել telnet-ի կարգավորումները՝ սահմանելով «Echo On» տարբերակը: Տարբեր telnet-հաճախորդներում դա արվում է տարբեր ձևերով, և նրանցից մի քանիսն ընդհանրապես նման հնարավորություն չունեն։ Այժմ մուտքագրեք.
Փոստային ինդեքս՝ 37642
Դուք կտեսնեք սերվերի պատասխանը.
ԵԿԵՂԵՑԻ ԲԼՈՒՐ, TN
Սերվերից անջատվելու համար մուտքագրեք՝
թողնել
Օրինակ 2 - տվյալների բազայի հասանելիություն
Այս օրինակը նմանակում է սերվերին, որը պետք է կատարի արգելափակման այլ առաջադրանքներ, բացի վարդակից զանգերից: Շատ սերվերներ ստիպված են աշխատել նման պայմաններում։ Սերվերները, որոնց անհրաժեշտ է տվյալների բազայի հասանելիություն, արտաքին ընթացակարգային զանգեր կամ հաշվարկներ, հաճախ չեն կարող ընդհատել այդ զանգերը, քանի որ դրանք արտաքին զանգեր են կամ դրա բարդության պատճառով: Հիմնական զանգը չի կարող բաժանվել փոքր կտորների, և մշակողը պետք է սպասի բազային գործողությունների ավարտին: Սա ոչ միայն տվյալների բազայի հասանելիության առանձնահատկությունն է, այլ նաև այլ գործողությունների, ինչպիսիք են սեղմումը, հաշվարկները և նույն տեսակի այլ մշակումները:
Ցուցադրման նպատակով, ենթադրենք, որ սերվերը կատարում է տվյալների բազայի զանգ, որի ավարտը տևում է 5 վայրկյան: Պարզեցնելու համար եկեք դա անենք ընդամենը դադարով, դրա համար օգտագործենք Sleep(5000) ֆունկցիան, իրականում զանգելու փոխարեն:
Այս օրինակը նույնպես պահանջում է ավելի քիչ մանրամասներ, քան նախորդ օրինակը, քանի որ հասկացություններից շատերը դեռ չեն հասկացել:
Աղբյուր

միավորի հիմնական;

ինտերֆեյս

օգտագործում է

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

IdBaseComponent, IdComponent, IdTCPServer;

տիպ

TformMain = դաս (TForm)

IdTCPServer1. TIdTCPServer;

ընթացակարգ IdTCPServer1Execute (AThread: TIdPeerThread) ;

մասնավոր

հանրային

վերջ ;

FormMain՝ TformMain;

իրականացումը

(R*.DFM)

ընթացակարգ TformMain.IdTCPServer1Execute (AThread: TIdPeerThread) ;

I: ամբողջ թիվ;

սկսել

AThread-ի հետ: Միացումը սկսվում է

WriteLn («Բարև. DB սերվերը պատրաստ է»: );

I:= StrToIntDef (ReadLn, 0);

// Երազը փոխարինվում է երկար DB-ով կամ այլ զանգով

Քնել (5000);

WriteLn (IntToStr (i * 7) );

վերջ ;

վերջ ;

վերջ.

Քանի որ Execute իրադարձությունը տեղի է ունենում շարանի համատեքստում, մշակման կոդը կարող է լինել ցանկացած երկարության: Յուրաքանչյուր հաճախորդ ունի իր սեփական շարանը և չի արգելափակում մյուս հաճախորդներին:
Փորձարկում
DB սերվերը փորձարկելու համար կազմեք և գործարկեք այն: Միացեք դրան՝ օգտագործելով Telnet-ը 6001 նավահանգստի վրա: Սերվերը կպատասխանի ողջույնի հաղորդագրությամբ: Մուտքագրեք թիվ: Սերվերը «կմշակի» ձեր հարցումը և կպատասխանի 5 վայրկյանում։

Բարեւ բոլորին!

Հաջորդ վեբ նախագիծը մշակելիս խնդիր առաջացավ՝ Delphi-ում ներդնել հաճախորդի ծրագրակազմ, որը տվյալները կփոխանցեր սերվերին՝ օգտագործելով POST մեթոդը: Հավելվածը պետք է փոխանցի տեքստ և ֆայլեր վերբեռնի վեբ սերվեր:

Նման տվյալների ուղարկման իրականացումը սերվերի կողմից վեբ մշակման լեզուների միջոցով (օրինակ՝ PHP) բավականին պարզ է, բայց եթե Ձեզ անհրաժեշտ է գրել հավելված, բազմաբնակարան ծրագրակազմ, որը փոխազդում է սերվերի հետ, ապա դա արդեն մի փոքր ավելի բարդ է։ . Տվյալների բազայի և FTP-ի միջոցով Delphi-ից սերվերին ուղիղ միացման եղանակը բացառվում է: այն անվտանգ չէ, վստահելի չէ (գաղտնաբառերի փոփոխություն, կապի տվյալներ և այլն) և ստեղծում է լրացուցիչ: ծրագրային ապահովման համատեղելիության խնդիրներ հաճախորդի կողմից: Խնդիրը լուծելու համար ես որոշեցի PHP-ով (սերվերի մաս) գրել սկրիպտներ, որոնք կմշակեն մուտքային POST հարցումները և արդյունքը կվերադարձնեն հաճախորդին (Delphi հավելված)։ Այս մոտեցման առավելություններն այն են, որ բոլոր կապերն ու տվյալների մշակումը տեղի են ունենում սերվերի վրա, ինչը շատ ավելի ապահով է, քան ուղղակի «միացումը»:

Սկսելով «գուգլել» շատ տարաբնույթ տեղեկություններ տարածվեցին, հիմնականում դրանք ֆորումներ էին, բայց բոլորը կտորներ էին: Մի բան որոշեց, թե կոնկրետ ինչ է օգտագործելու Indy-ն, այն է՝ IdHTTP բաղադրիչը՝ ներդրված POST մեթոդով: Իրականում ամեն ինչ պարզ է, այս մեթոդը վերցնում է ռեսուրսի երկու պարամետր Url և DataStream (տվյալների հոսք), ի պատասխան այն տալիս է արդյունքը տեքստային ձևով (դա կարող է լինել նաև էջի HTML կոդը): Գլխավորն այն էր ճիշտ ձևավորում DataStream (փոխանցված տվյալների հոսք), բայց ճանապարհին ի հայտ եկան լրացուցիչ որոգայթներ, մասնավորապես ռուսական կոդավորումը (անկախ նրանից, թե դա լավ չէ): Այստեղից սկսվեց զվարճանքը ցանցի բաց տարածություններում մի քանի ժամ թափառելու համար: Ընդհանրապես, բավական է շաղակրատել, անցնենք ծրագրային ապահովման պրակտիկային ու ներդրմանը։

Այսպիսով, ծրագիրը պարզ է. Այն պետք է տվյալներ ուղարկի սերվեր՝ օգտագործելով POST մեթոդը, տվյալները պարունակում են « վերնագիր «(տող),» Նկարագրություն » (բազմագիծ տեքստ) և գրաֆիկական ֆայլ(jpg, png, gif-երկուական տվյալներ): Սերվերը պետք է ընդունի այս տվյալները, մշակի դրանք, պահի գրաֆիկական ֆայլը սերվերում և վերադարձնի պատասխան: Որպես պատասխան՝ մենք Delphi-ին կվերադարձնենք հավելված, նույն տեքստը միայն պիտակների ավելացմամբ և ներբեռնված ֆայլի հղումով: Ոչ մի ուրիշ բան.

Սկսենք սերվերի մասի ներդրումից (նման է կայքի API-ին): Բացեք ցանկացած տեքստային խմբագրիչ (նոթատետր) և դրանում գրեք հետևյալ կոդը.

"; ) else ( արձագանքում է «Վերնագիր. բացակայում է»:
"; ) //Ստուգեք մուտքային տվյալները "բովանդակության" դաշտի տվյալների առկայության համար, if (!empty($_POST["content"]))( echo "Content: ".$_POST["content"]."
"; ) else ( արձագանքում է «Բովանդակություն. չկա»:
"; ) //Ստուգեք մուտքային տվյալները կցված ֆայլի «ֆայլի» առկայության համար, եթե (!empty($_FILES["file"])) ($finfo = pathinfo($_FILES["file"]["name" ]); / /ստացեք տեղեկատվություն ֆայլի մասին (անուն, ընդլայնում և այլն) //Ստուգեք ֆայլի տեսակը թույլատրելի տեսակների ցանկում (IMPROVISATION:)) if (stripos("jpgpnggif",$finfo["extension"] )==0)( echo ">>>>>>>Ֆայլի անվավեր տեսակ<<<<<<<<"; 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

Դասավորությունը օգտագործում է հետևյալ բաղադրիչները՝ Label, Button(2pcs), Edit(2pcs), Memo(2pcs), CheckBox, OpenDialog, IdHTTP: Անվանեք հետևյալ բաղադրիչները (հատկություն « Անուն”):

  1. Խմբագրել (վերնագիր) - անուն = կոչում;
  2. Խմբագրել (ուղի դեպի ֆայլ) անուն = imgfile;
  3. Հուշագիր (բովանդակություն)անուն = բովանդակություն;
  4. Հուշագիր (արդյունք) - անուն = պատասխան;
  5. Կոճակ (...) - Անուն = chkfile;
  6. Կոճակ (POST) Անուն = ՓոստԲայց;
  7. OpenDialog (Ֆայլի ընտրության երկխոսություն) – Անուն = PictDialog;

IdHTTP1-ը և CheckBox1-ը կթողնենք անփոփոխ (հոգնած :)))):

Որպեսզի պատահաբար չլինի խմբագրել» ճանապարհ դեպի խմբագրում ( imgfile), սահմանեք նրա ReadOnly հատկությունը True: Նմանապես, ժամը imgfileԵվ chkfileՍահմանեք Enabled հատկությունը false-ի: Մենք դրանք կակտիվացնենք CheckBox-ի միջոցով, այսինքն. Եկեք հնարավորություն տանք ընտրելու՝ վերբեռնել նկար, թե ոչ։

OpenDialog-ի համար ( PictDialog) դուք պետք է սահմանեք զտիչը (Filter հատկությունը) հետևյալ կերպ.

Իրականում տեսողական պատրաստումն ավարտված է: Եկեք սկսենք կոդավորումը:

Նախագծում մենք կձևավորենք տվյալների հոսք՝ օգտագործելով Indy-ի հետ բերվող տեսակը. TidMultiPartFormDataStream.Թեև ես հանդիպեցի TStream-ի իրականացման տարբերակներին, բայց աշխատելով TidMultiPartFormDataStream -ավելի հեշտ!

Այս տեսակը մեր նախագծին հասանելի դարձնելու համար մենք պետք է օգտագործենք հետևյալ գրադարանը. IdMultipartFormData.

CheckBox1-ի համար ստեղծեք OnClick իրադարձություն (կրկնակի սեղմելով օբյեկտի վրա) և ավելացրեք հետևյալ կոդը այս իրադարձությանը.

Ընթացակարգ TForm1.CheckBox1Click(Ուղարկող՝ TObject); սկսել //կատարել ֆայլի ուղու ակտիվ կամ ոչ ակտիվ տարրեր և երկխոսության կոճակներ imgfile.Enabled:=CheckBox1.Checked; chkfile.Enabled:=CheckBox1.Checked; վերջ;

Այստեղ մենք ակտիվացնում ենք օբյեկտները imgfile Եվchkfileկախված նշանի առկայությունից (եթե վանդակը նշված է, ապա օբյեկտները դառնում են ակտիվ):

Հիմա եկեք կազմակերպենք պատկերի ընտրությունը։ Դա անելու համար կոճակի վրա ստեղծեք OnClick իրադարձություն chkfile(նաև կրկնակի սեղմելով օբյեկտի վրա) և գրեք հետևյալը.

Ընթացակարգ TForm1.chkfileClick(Sender: TObject); սկսել //բացել երկխոսությունը և մուտքագրել ֆայլի ամբողջական ուղին imgfile(TEdit), եթե PictDialog.Execute, ապա imgfile.Text:= PictDialog.FileName; վերջ;

Այս իրադարձությունը կգործարկի պատկերի ընտրության երկխոսություն, և եթե օգտագործողը սեղմի « Բաց», ապա այս ֆայլի ուղին կավելացվի imgfile.

Եվ հիմա մենք հասնում ենք վերջնական «POST» կոճակին: Ստեղծեք OnClick իրադարձություն այս կոճակի համար և ավելացրեք հետևյալ կոդը.

Ընթացակարգ TForm1.PostButClick(Sender: TObject); var dataPost:TIdMultiPartFormDataStream; սկսել dataPost:=TIdMultiPartFormDataStream.Create; dataPost.AddFormField("title",title.Text,"utf-8").ContentTransfer:= "8bit"; dataPost.AddFormField("content",content.Text,"utf-8").ContentTransfer:= "8bit"; if CheckBox1.Checked and (trim(imgfile.Text)="") then //ստուգեք՝ ընտրված է ֆայլը, թե ոչ սկսել ShowMessage(«Դուք պետք է ընտրեք գրաֆիկական ֆայլ»); ելք; վերջ; եթե CheckBox1.Checked ապա dataPost.AddFile("file",imgfile.Text,""); //ավելացնել դաշտ ֆայլի պատասխանով:Text:= StringReplace(idHTTP1.Post("http://api..php",dataPost)"
",#13#10,); տվյալների փոստ: Անվճար; վերջ;

Այսպիսով, հերթականությամբ (թեև կան մեկնաբանություններ).

Datapost - տիպի օբյեկտ TIdMultiPartFormDataStream. Թույլ է տալիս ստեղծել POST հարցման կառուցվածք, որը բաղկացած է տարբեր տեսակի դաշտերից:

dataPost . AddFormField (" կոչում ", կոչում . Տեքստ ," utf -8 "). բովանդակության փոխանցում := " 8 քիչ "; – DataPost-ին ավելացնում է «title» անունով դաշտ, արժեքը «title.Text»-ից, փոխանցում փոխանցված տվյալների կոդավորումը սահմանում է «utf-8» (պարամետրը պարտադիր չէ, բայց առանց դրա հստակ նշման՝ կիրիլիցա այբուբենը: փոխանցվում է «?» հարցական նշաններով) և շատ կարևոր մեթոդով «Բովանդակության փոխանցում»: Առանց այս մեթոդի տվյալները ուղարկվում են սերվեր: abracadabra«. Խնդրում ենք նկատի ունենալ, որ հաղորդող կողմում գտնվող դաշտի անվանումը («վերնագիր») պետք է համապատասխանի սկրիպտում նշված անվանմանը. $_POST[«title»]:

Նմանապես, տվյալները փոխանցվում են «բովանդակություն» դաշտում:

dataPost . addfile (" ֆայլ ", imgfile . Տեքստ ,"") - այս տողով մենք հոսք ենք կազմում ֆայլից ստացված տվյալների հետ:

Ամեն ինչ, տվյալները ստեղծվում են, մնում է այն փոխանցել սերվերի սցենարին և ստանալ պատասխան.

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

որովհետեւ TMemo-ն չի հասկանում տողերի ընդմիջման պիտակը
», մենք կօգտագործենք « » ֆունկցիան՝ այն փոխարինելու հասկանալի տողերի ընդմիջման «#13#10» նիշերով։

Ամեն ինչ ավարտելուց հետո մենք մաքրում ենք հիշողությունը DataPost օբյեկտից տողով.

datapost.Free;

Թեև մեր օրինակում դա տեղի կունենա ավտոմատ կերպով ընթացակարգի ավարտին, բայց դեռ ...

Իրականում ծրագրի արդյունքը էկրանին.

Այսպիսով, մենք կարող ենք ցանկացած տվյալներ, ֆայլեր ուղարկել սերվեր, մշակել այս տվյալները սերվերի վրա և ի պատասխան ծրագրին հայտնել սցենարի կատարման արդյունքը: Դա նույնիսկ կարող է լինել ընդամենը 0 կամ 1, ինչը ազդարարում է դիմումին հետագա արձագանքելու համար:

Բոլորը. Հաջողություն բոլորին: Հուսով եմ, որ տեղեկատվությունը օգտակար էր, և դուք այն օգտակար կգտնեք:

Պատրաստ օրինակ և սցենար, որը կարող եք ներբեռնել:

Ամբողջական մոդուլի կոդը.

Unit PostUnit; Ինտերֆեյսը օգտագործում է 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; տեսակ TForm1 = դաս (TForm) IdHTTP1: TIdHTTP; վերնագիր՝ TEdit; բովանդակությունը՝ TMemo; PostBut: TButton; պատասխան՝ TMemo; Պիտակ 1. T Label; Պիտակ 2. T Label; Label3. T Label; imgfile: TEdit; chkfile: TButton; Label4. T Label; CheckBox1. TCcheckBox; PictDialog՝ TOpenDialog; ընթացակարգ PostButClick (Ուղարկող՝ TObject); ընթացակարգը chkfileClick(Ուղարկող՝ TObject); ընթացակարգ CheckBox1Click(Ուղարկող՝ TObject); private ( Private declarations ) public ( Public declarations ) end; var Form1: TForm1; իրականացման ($R *.dfm) ընթացակարգ TForm1.CheckBox1Click(Sender: TObject); սկսել //կատարել ֆայլի ուղու ակտիվ կամ ոչ ակտիվ տարրեր և երկխոսության կոճակներ imgfile.Enabled:=CheckBox1.Checked; chkfile.Enabled:=CheckBox1.Checked; վերջ; ընթացակարգ TForm1.chkfileClick(Ուղարկող՝ TObject); սկսել //բացել երկխոսությունը և մուտքագրել ֆայլի ամբողջական ուղին imgfile(TEdit), եթե PictDialog.Execute, ապա imgfile.Text:= PictDialog.FileName; վերջ; ընթացակարգ TForm1.PostButClick(Ուղարկող՝ TObject); var dataPost:TIdMultiPartFormDataStream; սկսել dataPost:=TIdMultiPartFormDataStream.Create; dataPost.AddFormField("title",title.Text,"utf-8").ContentTransfer:= "8bit"; dataPost.AddFormField("content",content.Text,"utf-8").ContentTransfer:= "8bit"; if CheckBox1.Checked and (trim(imgfile.Text)="") then //ստուգեք՝ ընտրված է ֆայլը, թե ոչ սկսել ShowMessage(«Դուք պետք է ընտրեք գրաֆիկական ֆայլ»); ելք; վերջ; եթե CheckBox1.Checked ապա dataPost.AddFile("file",imgfile.Text,""); //ավելացնել դաշտ ֆայլի պատասխանով:Text:= StringReplace(idHTTP1.Post("http://api..php",dataPost)"
",#13#10,); տվյալների փոստ: Անվճար; վերջ; վերջ:

Indy-ն բաղադրիչների բավականին հզոր փաթեթ է, որը թույլ է տալիս մշակել տարբեր ցանցային հավելվածներ: Այս ձեռնարկում ես ձեզ ցույց կտամ, թե ինչպես կարող եք ստեղծել հաճախորդ-սերվեր հավելվածներ՝ օգտագործելով TIdTCPClient և TIdTCPServer բաղադրիչները:

Նախ և առաջ ես կցանկանայի նշել այս բաղադրիչների երկու կարևոր առավելությունները. Դրանցից ամենակարևորը բազմաթելային է, ինչը նշանակում է, որ սերվերը յուրաքանչյուր հաճախորդի համար ստեղծում է առանձին թեմա, և դա, անշուշտ, ազդում է բազմամիջուկ պրոցեսոր ունեցող համակարգիչների վրա սերվերի ծրագրի աշխատանքի վրա: Երկրորդ առավելությունը օգտագործման հեշտությունն է: 10-20 տող կոդ բավական է պարզ հաճախորդ-սերվեր հավելված գրելու համար։ Բաղադրիչների այս փաթեթը առկա է ստանդարտ Delphi հավաքույթներում:

Եկեք գրենք մի պարզ ծրագիր, որը թույլ է տալիս տեքստային հաղորդագրություն ուղարկել հաճախորդից սերվեր: Եկեք սկսենք ստեղծել սերվեր:
Տեղադրեք IdTCPServer բաղադրիչը Indy Servers ներդիրի ձևի վրա: Մենք կկատարենք այս բաղադրիչի բոլոր կարգավորումները գործարկման ժամանակ՝ OnCreate ձևի իրադարձությունում՝
IdTCPServer1.DefaultPort:= 12345;
IdTCPServer1.Active:= ճշմարիտ;
Այստեղ ամեն ինչ պարզ է. մենք նշում ենք այն նավահանգիստը, որի վրա սերվերը կաշխատի և ինքն է ակտիվացնում սերվերը:

Հաճախորդից սերվերի վրա տվյալներ ստանալու համար կա «OnExecute» հատուկ իրադարձություն: Այս իրադարձությունն այսպիսի տեսք ունի.

սկսել
վերջ;

Միջոցառման բովանդակությունը խմբագրենք հետեւյալ կերպ.
ընթացակարգ TForm3.IdTCPServer1Execute (AContext: TIdContext);
var
l:string; // տողային փոփոխական, որի մեջ մենք կստանանք
սկսել
l:= AContext.Connection.IOHandler.ReadLn();
Memo1.Lines.Add(l);
վերջ;

Այժմ, հենց որ հաղորդագրությունը հասնի սերվերին, մենք այն կգրենք l տողային փոփոխականի վրա և կցուցադրենք բազմագիծ տեքստային դաշտում։

Դրա վրա, քանի որ զարմանալի չէ, սերվերի ստեղծումն ավարտվում է։ Մնացած ամեն ինչ Ինդին կանի մեզ համար: Սկսենք հաճախորդի ծրագրից: Այն կմիանա սերվերին, հաղորդագրություն կուղարկի նրան և կանջատվի սերվերից:

Եկեք ստեղծենք նոր նախագիծ, տեղադրենք IdTCPClient բաղադրիչը ձևաթղթի վրա, որը կարելի է գտնել «Indy Clients» ներդիրում։ Մենք նաև կտեղադրենք պարզ Խմբագրում և կոճակ: Եկեք կոճակի համար ստեղծենք OnClick իրադարձությունների մշակիչ, որի ներսում կգրենք.
IdTCPClient1.Port:= 12345;
IdTCPClient1.Host:= '127.0.0.1';
IdTCPClient1.Connect;
IdTCPClient1.IOHandler.WriteLn(Edit1.Text);
IdTCPClient1.Անջատել;

Պարտադիր չէ, որ այս կոդը տեղադրվի OnCreate միջոցառման մեջ: Դուք կարող եք տեղադրել այս կոդը ցանկացած վայրում, որտեղ ցանկանում եք:
Առաջին տողում մենք նշանակում ենք մի նավահանգիստ, և մենք պետք է նշենք նույն պորտը, որը նշել ենք սերվերի ծրագրում, հակառակ դեպքում հաճախորդը պարզապես չի գտնի սերվերը: Այնուհետև մուտքագրեք սերվերի IP հասցեն: Սերվերն ինքնին կարող է տեղակայվել ինչպես տեղական ցանցում, այնպես էլ հեռակա կարգով: Վերջին դեպքում կապը կկատարվի ինտերնետի միջոցով, և դուք պետք է ինտերնետում նշեք IP հասցեն:

Ես նշել եմ «127.0.0.1» հասցեն, որը ցույց է տալիս, որ սերվերը այն համակարգիչն է, որի վրա աշխատում է հաճախորդը: Այս մեթոդը շատ հարմար է ցանցային հավելվածների փորձարկման համար։
Այնուհետև մենք միանում ենք, ուղարկում ենք հաղորդագրություն և անջատում: Ինչպես նաև հաղորդագրությունն ինքնին, կարող եք նաև IP հասցեն վերցնել Edit-ից կամ ցանկացած տողային փոփոխականից:

Ավարտված է նաև հաճախորդի ծրագրի վրա աշխատանքը: Ինչպես տեսնում եք, Ինդին մեզ համար հսկայական աշխատանք է կատարում, ինչը հնարավորություն է տալիս նույնիսկ անփորձ ծրագրավորողի համար ստեղծել իր սեփական ցանցային հավելվածը:

Նոր տեղում

>

Ամենահայտնի