Indy-komponenter som används i Delphi. Ett exempel på att arbeta med Indy UDP-komponenter (server, klient) i Delphi

I ett nötskal är Indy komponenter för bekvämt arbete med populära Internetprotokoll. Principen för deras funktion är baserad på användningen av uttag i blockeringsläge. Indy är intressant och bekvämt eftersom det är ganska abstrakt. Och programmering i Indy handlar om linjär programmering. Förresten, en översatt artikel är allmänt spridd på Internet, där det finns orden "blockeringsläget är inte djävulen" :)) En gång var jag väldigt road av den här översättningen. Artikeln är en del av boken "Depths of Indy" av Hoover och Hariri. I princip behöver du inte läsa allt för att arbeta med Indy, men jag rekommenderar ändå att du bekantar dig med principerna för hur internetprotokoll fungerar. När det gäller den "djävulska" regimen. Ett blockerande socketanrop ger faktiskt inte tillbaka kontroll förrän det har slutfört sin uppgift. När samtal görs på huvudtråden kan applikationsgränssnittet låsa sig. För att undvika denna obehagliga situation skapade indiska utvecklare komponenten TIDAntiFreeze. Du behöver bara slänga det på formuläret - och användargränssnittet ritas enkelt om samtidigt som du ringer blockerande samtal.

Du har förmodligen redan blivit bekant med innehållet i de olika "Indy (...)"-flikarna i Delphi. Det finns många komponenter där, och var och en av dem kan vara användbar. Jag har själv inte arbetat med alla, för jag ser inte behovet av att studera dem utan en specifik uppgift.

Den grundläggande Delphi-distributionen inkluderar Indy v.9 med pennies. Det skulle förmodligen vara tillrådligt att omedelbart uppgradera till fler ny version(Jag har till exempel för närvarande 10.0.76, men det finns också senare, verkar det som).

Det finns klient- och serverkomponenter för att arbeta med samma protokoll. Indy förenklar verkligen applikationsutveckling, till skillnad från möjligheten att utveckla samma funktionalitet på sockets. Till exempel, för att upprätta en anslutning med servern, bör du helt enkelt anropa Connect-metoden. En lyckad anslutning kommer att markeras av metoden som returnerar utan att orsaka ett undantag. Om anslutningen inte upprättas kommer ett undantag att skapas.

"Akademiskt" exempel (koden fungerar inte, kör den inte :)):

Med IndyClient gör
Börja
Host:= "test.com";
Port:= 2000;
Ansluta;
Prova
// arbeta med data (läs, skriv...)
till sist
Koppla ifrån;
slutet;
slutet;

Värd och port kan ställas in i objektinspektören eller under körning.

Varför kan du använda Indy-komponenter för att analysera uppgifter? Olika användningsområden! Det enklaste är att få fram innehållet på sidan (alla har förmodligen redan stött på detta) med hjälp av IdHTTP-komponenten:

Var
rcvrdata: TMemoryStream;
idHttp1: TidHttp;
Börja
idHttp1:= TidHttp.Create(noll);
rcvrdata:= TMemoryStream.Create;
idHttp1.Request.UserAgent:= "Mozilla/4.0 (kompatibel; MSIE 5.5; Windows 98)";
idHttp1.Request.AcceptLanguage:= "ru";
idHttp1.Response.KeepAlive:= sant;
idHttp1.HandleRedirects:= true;
Prova
idHttp1.Get(Edit1.Text, rcvrdata);
till sist
idHttp1.Free;
slutet;
om rcvrdata.Size > 0 så börja
ShowMessage("Mottagna" + inttostr(rcvrdata.Size));
rcvrdata.SaveToFile("c:\111.tmp");
slutet;
rcvrdata.Free;
slutet;

Som du kan se kan du inte bara få innehållet på sidan, utan också simulera att ladda ett dokument från en specifik klient. Indy-komponenter är i allmänhet användbara för att generera rubriker och POST-förfrågningar. Mer om detta med exempel nästa gång.

För att hålla dig uppdaterad med blogguppdateringar kan du

Indy-komponenter som används i Delphi 6.

Utöver grundläggande internettjänster och protokoll finns det ett brett utbud av tilläggstjänster, vars möjligheter ofta används av internetutvecklare. Dessutom är möjligheten att visa information med en webbläsare inte alltid en acceptabel lösning för internetapplikationer. I det här fallet är det rimligt att använda internetinfrastrukturen för datautbyte och tillhandahålla informationsvisning genom mer komplexa klientapplikationer utvecklade till exempel i Delphi.

Låt oss säga att du behöver implementera specialiserad serverlogik som inte ingår i vanliga webbservrar. För att lösa denna klass av problem inkluderar Delphi Internet Direct (Indy)-biblioteket från Nevrona Designs (http://www.nevrona.com/Indy/). Detta bibliotek, utvecklat specifikt för Borland Delphi, har redan åtta versioner, varav den senaste ingår i den nya versionen av Delphi. Uppsättningen av komponenter är uppdelad i tre grupper: klient (Indy Client), server (Indy Servers) och auxiliary (Indy Misc).

Indy-klienter och Indy-servrar

De flesta Indy Client- och Indy Servers-komponenter är par som motsvarar klient- och serverdelarna av protokollen och tjänsterna (med undantag för vissa, huvudsakligen server, komponenter som TunnelMaster och TunnelSlave), och tillåter användning av protokoll som TCP/IP , UDP, NNTP, SMTP, FTP, HTTP, samt tjänsterna ECHO, FINGER, WHOIS, etc.

Indy-klientkomponenter skrivs med sockets. Klientsidans uttag kräver en anslutning till servern. Om anslutningen upprättas kan klienten och servern börja utbyta meddelanden. Dessa meddelanden är av en annan karaktär, men vanligtvis sker utbytet med ett specifikt protokoll (till exempel HTTP)

TIdTCPClient och TIdTCPServer

Dessa komponenter används för att stödja ett av huvudnätverksprotokollen - TCP (Transmission Control Protocol), och är också basklasserna för TIdSMTP- och TIdFTP-komponenterna. Klassen TIdTCPServer har en ThreadMgr-egenskap som är noll som standard. Om ThreadMgr är noll när TIdTCPServer är aktiverad kommer klassen TIdThreadMgrDeafault att skapas implicit. Annars används den installerade processhanteraren.

TIdUDPClient och TIdUDPServer

Dessa komponenter används för att stödja nätverksprotokoll UDP (User Datagram Protocol) och är också basklasserna för ett antal andra Indy-komponenter.

TIdChargenServer

Komponenten används för att generera slumpmässiga symboler, vanligtvis för teständamål.

TIdDayTime och TIdDayTimeServer

Komponenterna används för att tillhandahålla tidsservice. Klienten begär och servern rapporterar aktuellt datum och tid.

TIdDNSResolver

Detta är en klientkomponent som betjänar förfrågningar från en DNS-server (Domain Name Service). DNS-serverfrågor är utformade för att ersätta en dators namn med dess IP-adress. TIdDNSResolver är en ättling till klassen TIdUDPClient.

TIDDICTServer

En serverkomponent som stöder Dictionary Server Protocol (DICT), en ordbok på serversidan baserad på TCP-protokollet som tillåter en klient att få åtkomst till en ordbok för naturligt språk.

TIdDISCARDServer

Serverkomponenten som stöder postservern. Inspelningarna kan användas som ett felsöknings- och mätverktyg. Registertjänsten lämnar helt enkelt över all data till den som är villig att ta emot den.

TI dEcho och TI deCHOServer

Komponenterna är utformade för att tillhandahålla en svarstjänst, som vanligtvis används för att kontrollera nätverkets tillstånd. Klienten skickar ett textmeddelande till servern, servern returnerar meddelandet till klienten. Om meddelandet är förvanskat fungerar nätverket fel.

TIdFinger och TIdFingerServer

Komponenterna är utformade för att tillhandahålla ett protokoll som tillåter en användare att fråga data angående närvaron av andra användare på systemet. Vissa servrar hanterar sådana klientförfrågningar. Genom att använda detta par av komponenter kan du betjäna klientförfrågningar som bestämmer närvaron av andra användare på systemet.

TIdFTP

Komponenten inkluderar fullt stöd för filöverföringsprotokollet - FTP (File Transfer Protocol). Passiv och aktiv dataöverföring stöds, liksom operationer som GET och PUT, radering av kataloger, erhållande av kvoter, fil- och katalogstorlekar. TI dFTP använder klassen TIdSimpleServer för att fungera. När en FTP-filöverföring pågår öppnas en sekundär TCP-anslutning för dataöverföring och stängs när data har överförts. Denna anslutning kallas en "datalänk", som är unik för varje fil som överförs.

TIdGopher och TIdGopherServer

Dessa komponenter är utformade för att tillhandahålla ett nätverksprotokoll som har ersatts Nyligen från WWW (World Wide Web) HTTP-protokoll. Servern som implementerar detta protokoll tillhandahåller ett hierarkiskt distribuerat dokumentflödesstödsystem. Ett exempel på detta par av komponenter, som finns i katalogerna \demos\indy\GopherClient och \demos\indy\GopherServer, visar hur detta protokoll kan användas för att tillhandahålla lokalt nätverk information om filer som finns på din dator, inklusive stängda.

TIdHostNameServer

En serverkomponent utformad för att skicka det lokala servernamnet till klienter.

TIdHTTP och TIdHTTPServer

Komponenterna används för att tillhandahålla HTTP-nätverksprotokollet (versionerna 1.0 och 1.1 stöds, inklusive GET-, POST- och HEAD-operationer). Dessutom tillhandahålls stöd för autentisering och användning av proxyservrar. Serverkomponenten används för att tillhandahålla tjänster till en annan webbserver som stöder ett givet protokoll. TIdHTTPServer underlättar implementeringen av funktioner som cookies, tillståndshantering etc.

TIdIcmpClient

En klientkomponent utformad för att tillhandahålla Internet Control Message Protocol (ICMP), som används för att utföra ping-operationer och nätverksspårning.

TIdPOP3

En klientkomponent utformad för att tillhandahålla Post Office Protocol (POP), inklusive stöd för MIME-kodning och avkodning, och multibyte-teckenöverföring.

TIdIMAP4Server

En serverkomponent utformad för att stödja IMAP-operationer (Internet Message Access Protocol) på servern. Protokollet låter dig söka efter meddelanden E-post på servern. Skillnaden mellan IMAP- och POP-protokollen är att POP-protokollet kräver extra minne för att lagra data, och IMAP-protokollet kommer åt servern istället för klientmaskinen. IMAP4 skapades för att ersätta POP3, men POP3 är fortfarande en allmänt använd standard till denna dag.

TIdIRCServer

En serverkomponent utformad för att stödja de vanligaste tjänsteoperationerna på Internet, vanligen kallad chatt. Komponenten ger grundläggande byggklossar för IRC-server (Internet Relay Chat).

TIdMappedPortTCP

En serverkomponent utformad för att skapa mappade portar, som ofta används i proxyservrar. Metoderna för den här komponenten låter dig mappa en port till en annan. Till exempel kan port 80 mappas till port 3000, och alla förfrågningar till den första porten (port 80) skulle vidarebefordras till den andra porten (port 3000).

TIdNNTP och TIdNNTPServer

Dessa komponenter krävs för att stödja Network News Transfer Protocol (NNTP) som används i nyhetstjänster. Klientkomponenten inkluderar stöd för MIME-kodning och avkodning, samt stöd för multibyte-tecken och alternativa kodningar. Serverkomponenten låter dig skapa nyhetsservrar. Det är viktigt att notera att TIdNNTPServer inte är en fullfjädrad nyhetsserver, utan en komponent som tillhandahåller den grundläggande funktionaliteten för en sådan server.

TIdQOTD och TIdQOTDServer

Komponenterna används för att tillhandahålla tjänsten Dagens offert. Klientkomponenten ansluter till serverkomponentinstansen för att få den dagliga offerten. Varje serverinstans innehåller en unik referensdatabas.

TIdSMTP

En klientkomponent designad för användning i SMTP-applikationer (Simple Mail Transfer Protocol) som ger stöd för autentisering, MIME-kodning och avkodning och stöd för flerbytetecken.

TIdSNTP

En klientkomponent utformad för att tillhandahålla SNTP (Simple Network Time Protocol) - en tidstjänst. Kan användas för att ansluta till valfri tidstjänst för att fastställa aktuellt datum och tid.

TIdSimpleServer

Serverkomponent som ger en lättviktig TCP-server. Låter dig organisera en punkt-till-punkt-anslutning. Den används för att skapa servrar med en enda användare, det vill säga den kan bara betjäna en anslutning åt gången. Till skillnad från TIdTCPServer-komponenten skapar den inte sekundära processer när man väntar på förfrågningar från klienter och när man bearbetar dessa förfrågningar. Med andra ord, om servern betjänar en begäran från en klient, och vid den tidpunkten en annan klient kontaktar den för att ansluta, kommer den att blockeras till slutet av behandlingen av den första begäran.

TIdTelnet och TIdTelnetServer

Klientkomponenten används för att organisera fjärrsessioner på en annan dator, inklusive konsolförhandlingar och autentisering. Kommunikationsprotokollet förutsätter närvaron av en person som interagerar interaktivt med servern. Klientkomponenten har inte bildskärmsstöd eller terminalemulering, utan tillhandahåller helt enkelt en anslutning till serverdelen. Vanligtvis används TIdTelnetServer-serverprotokollet för att organisera fjärrdatabaser med ett textgränssnitt för interaktiv interaktion med klienter.

TIdTime och TIdTimeServer

Klientkomponenten är ett alternativ till TIdSNTP-komponenten för att bestämma tid. Det är viktigt att notera att formaten för de två protokollen är olika. TIdTime är baserat på RFC 868-formatet (returnerar tiden i den interna UNIX OS-standarden, utför alla nödvändiga konverteringar). Serverkomponenten fungerar likadant som DayTime-servern. Kan användas för att implementera en tidstjänst på lokal dator. Ingen ytterligare kod krävs, skapa bara en instans av TIdTimeServer som returnerar tiden för serverdatorns interna klocka.

TIdTrivialFTP och TIdTrivialFTPServer

Dessa komponenter är nödvändiga för att organisera ett enkelt filöverföringsprotokoll. Klientkomponenten i detta protokoll används för att ansluta till en instans av motsvarande serverkomponent. Protokollet är avsett för privata, lätta, lokala fall av filöverföring, till exempel i lokala nätverk eller för att ladda (ladda upp) routingtabeller till routrar. På grund av de försvagade egenskaperna hos detta protokoll rekommenderas inte användningen av det när du använder autentiseringsalgoritmer eller andra säkerhetsmekanismer. Huvudsyftet med detta protokoll är att överföra filer till en hårdvaruenhet i syfte att modifiera den.

TIdTunnelMaster och TIdTunnelSlave

Servertunnelkomponenter används i proxyservrar för att organisera flera logiska anslutningar över en fysisk (tunnel). Dessa klasser kan användas för olika ändamål, till exempel för att organisera en hemlig anslutning över icke-hemliga kanaler.

TIdWhois och TIdWhoIsServer

Den här klientkomponenten ansluter till vilken standard Whois-server som helst, vilket gör att du kan få information om domäner. Serverkomponenten tillhandahåller de grundläggande funktionerna hos en NIC-server.

Indy Övrigt

Palettsidan Indy Diverse komponenter inkluderar BASE64, UUE, Quoted Printable och andra vanliga e-postkommunikationsformat, kodare (MD2, MD4 och MD5) för kryptografistandarder som används för att lagra lösenord och elektroniska signaturer i en oåterkallelig (svårt att tyda) form, såväl som många andra användbara komponenter och verktyg som ofta används i utvecklingen av internetapplikationer.

TIdAntiFreeze

På grund av de blockbaserade algoritmerna för Indy-komponenter verkar det ofta som att applikationen har fastnat medan anslutningen fungerar. För att eliminera användningen av sekundära processer (trådar) när du organiserar kommunikation för att förhindra att applikationen fryser, räcker det att placera den angivna komponenten på formuläret.

Komponenten fungerar genom att analysera förfrågningar från TCP/IP-protokollstacken och skicka meddelanden till applikationen under fördröjningen när externa anslutningar blockeras, vilket skapar en illusion av att köra kod. Eftersom komponenten endast påverkar blockerade anslutningar för huvudprocessen, krävs inte användning av TIdAntiFreeze i applikationens sekundära processer. Tänk på att TIDAntiFreeze-komponenten saktar ner anslutningarna eftersom huvudprocessen periodvis avbryts för att bearbeta meddelanden. Av detta följer att man måste se till att applikationen som utvecklas inte lägger för mycket tid på att bearbeta meddelanden, inklusive OnClick, OnPaint, OnResize, etc. Till viss del kan detta kontrolleras genom egenskaperna för klassen TIdAntiFreeze. Användningen av denna komponent är inte obligatorisk, men den låter dig lösa problemet med att synkronisera anslutningar med applikationens visuella gränssnitt.

TIdDateTimeStamp

En klass för att utföra matematik för datum och tid relaterad till det faktum att internetprotokoll använder olika datum- och tidsformat; dessutom kan klienter och servrar finnas i olika tidszoner.

TIdIPWatch

Det är en timerbaserad komponent som ständigt övervakar förändringar i datorns IP-adress. Komponenthändelser inträffar när en förändring upptäcks. Denna komponent används vanligtvis för att upptäcka om en dator är ansluten till Internet eller något annat nätverk. Ändringen av IP-adress i den här situationen kan uppstå på grund av att IP-adressen tilldelas av DHCP-servern (Dynamic Host Configuration Protocol) vid anslutning till det nya nätverket.

TIdLogDebug

Syftet med den här komponenten är att fånga upp händelser från vilken klient eller serverkomponent som helst och placera en registrering av händelsen i specificerad fil. Den här komponenten är mycket användbar för att felsöka Indy-komponenter.

TIdMessage

Komponenten används i kombination med andra komponenter för att korrekt dekryptera eller koda meddelanden. Dessa kan vara POP-, SMTP- och NNTP-komponenter. Klassen stöder MIME-kryptering och dekryptering, multibyte-tecken och ISO-kodning.

TIdNetwork Calculator

En av få Indy-komponenter som kan användas när man bygger applikationer. Nätverkskalkylatorn kan användas för att utföra beräkningar på IP-adresser, inklusive nätverksmasker, subnät, nätverksklasser, etc.

TIdThreadMgrDefault

Komponenten ger kontroll över sekundära processer som standard. Skapas när någon Indy-komponent som stöder processhantering inte har en instans av klassen TIdThreadManager definierad. Komponenten ger endast grundläggande funktioner för att hantera sekundära processer: skapa och förstöra dem på begäran.

TIdThreadMgrPool

En mer avancerad processhanteringskomponent än TIdThreadMgrDefault eftersom den slår samman processer snarare än att skapa eller förstöra dem på begäran.

TIdVCard

VCard är den elektroniska motsvarigheten till ett visitkort och kan innehålla ägarens personliga information och grafiska data.

TIdIMFDecoder

Designad för avkodning av Internetmeddelanden. Det är en ättling till TIdCoder-klassen, precis som alla andra kodarkomponenter. Klassen TIdCoder avkodar enligt ARPA Internet textmeddelandeformatstandard RFS-822, som föreslogs i augusti 1982, och USENET meddelandestandard RFC 1036, som föreslogs i december 1987.

Komponenten utökar TIdCoder-klassen för att tillåta detektering av RFS-822-format efter huvudkontext, vilket ger dekryptera-vid-mottagning-läge och MIME-kryptering och dekryptering. TIdIMFDecoder-komponenten används i klassen TIdMessageClient för att avkoda mottagna och sända meddelanden.

TIdQuotedPrintableEncoder

QuotedPrintableEncoder låter dig dekryptera text i det angivna formatet. Kan fungera som en fristående komponent med en specificerad kodningstyp, vilket gör att meddelanden som innehåller en ny kodningstyp kan överföras.

TIdBase64Encoder

Implementerar ytterligare en krypteringsalgoritm som gör det möjligt att överföra icke-utskrivbara tecken.

TIdUUEncoder

Implementerar en av de första krypteringsalgoritmerna, UU-kodning. Används ibland när artiklar skickas till en nyhetstjänst.

TIdXXEncoder

Det är osannolikt att denna krypteringsmetod någonsin kommer att användas. I huvudsak är detta samma UU-kodning, men med en annan krypteringstabell.

TIdCoderMD2

Komponenter med olika typer av MD (Message Digest) krypteringsalgoritm. De är alla shuffle-baserade, enkelriktade och har inga dekrypteringsalgoritmer.

Komponenter av protokollklienter och servrar kan användas för att utveckla server- och klientinternetapplikationer, tillsammans med eller istället för grundläggande (ClientSocket, ServerSocket) och andra komponenter från Internet- och Fastnet-paletten. Indy-komponenter använder inte WebBroker-arkitekturen och implementerar lågnivåstöd för Internetprotokoll och tjänster direkt i källkoden ( källkoderär bifogade).

TIdConnectionInterceptOpenSSL och TIdServerInterceptOpenSSL

SSL-protokollet - Secure Sockets Layer, som säkerställer sekretess och tillförlitlighet för kommunikation mellan två applikationer, har två lager. På den låga nivån av ett flerskiktstransportprotokoll (som TCP) är SSL ett inspelningsprotokoll och används för att kapsla in olika protokoll på högre nivå. Fördelen med SSL är att det är ett oberoende applikationsprotokoll, men ett protokoll på högre nivå kan användas ovanpå SSL.

SSL tillhandahåller kommunikationssäkerhet, som har tre huvudfunktioner: tillhandahålla en konfidentiell anslutning; kryptering med offentlig nyckel(används för att bekräfta adressatens äkthet); stöd för tillförlitlighet i dataöverföring.

  • Symmetrisk kryptografi används för att kryptera data (t.ex. DES, RC4, etc.).
  • Digital signatur tillhandahålls med asymmetrisk kryptering med publik nyckel (till exempel RSA, DSS, etc.).
  • Tillförlitlighet för kommunikation, meddelandetransport inkluderar kontroll av meddelandets integritet genom MAC-korrigeringskoder, säkra hashfunktioner (t.ex. SHA, MD5, etc.) med hjälp av MAC-beräkningar.

I kombination med HTTP och serverautentisering tillhandahåller SSL nödvändiga krypteringsfunktioner och upprätthåller vidare den etablerade anslutningen genom att korskontrollera webbserverns identitet etc. Det är viktigt att förstå att SSL endast skyddar kommunikation under dataöverföring och inte ersätter andra säkerhetsmekanismer.

Komponenterna TIdConnectionInterceptOpenSSL och TIdServerInterceptOpenSSL tillhandahåller anslutningar på både klientsidan och serversidan med SSL-protokollet. Det bör noteras att komponenterna TIdConnectionInterceptOpenSSL och TIdServerInterceptOpenSSL endast är tillgängliga i Delphi 6 och inte i Kylix. Detta beror på komplexiteten i protokollet, som i fallet med en Windows-implementering är baserat på operativsystemets funktioner.

Exempel på användning av Indy-komponenter finns i /Delphi6/Demos/Indy-katalogerna. Totalt innehåller Indy-biblioteket i version 8.0 69 komponenter. Det anges att i version 9.0 kommer det angivna biblioteket att innehålla 86 komponenter. Alla komponenter är enhetliga och ingår i både Delphi 6 och Kylix, vilket gör att de kan användas för att utveckla plattformsoberoende applikationer. Alla Indy-komponenter stöder multithreading.

Indy-komponenterna implementerar nästan all funktionalitet som finns i Internet- och Fastnet-komponenterna, vilket tydligt framgår av tabellen.

Fastn et komponenter Indy komponenter Syfte med komponenter
1 TserverSocket, TClientSocket TIdTCPserverSocket, TIdTCPClientSocket Interaktion mellan två datorer (klient och server) med hjälp av TCP/IP-protokollet
2 TNMDayTime TIdDayTime, TIdDayTimeServer Fråga servern för aktuell tid
3 TNMEcho TIdEcho, TIdEchoServer Används för att kommunicera med svarsservern
4 TNMFinger TIdFinger, TIdFingerServer Används för att hämta information om användaren från en sökserver på Internet
5 TNMFTP TIdFTP, TIdTrivialFTP, TIdTrivialFTPServer Tillhandahåll filöverföring med FTP-protokoll
6 TNMHTTP TIdHTTP, TIdHTTPServer Använd HTTP-protokoll för datautbyte
7 TNMMsgServ, TNMMsg Används för att förmedla enkelt textmeddelanden från klient till server
8 TNMNNTP TIdNNTP, TIdNNTPServer Stöder datautbyte med nyhetsserver
9 TNMPOP3 TIdPOP3 Används för att ta emot e-post från en e-postserver som använder POP3-protokollet
10 TNMSMTP TIdSMTP Används för att skicka e-post via Mejl server Internet
11 TNMSrm, TNMSrmServ Sänder binär data som skrivits till en ström med TCP/IP-protokollet
12 TNMUDP TIdUDP, TIdUDPServer Överför data med UDP-protokollet
13 TpowerSock, TNMGeneralServer Komponentinkapslade klasser som är grunden för att skriva dina egna klienter (Powersock) och servrar (NMGeneralServer)
14 TNMUUPocessor TIdUUEncoder, TIdUUDecoder Utför omkodning binära filer till MIME- eller UUENCODE-format
15 TNMURL Konverterar strängar till HTML-format och utför omvänd konvertering

Undantagen är klasser som TNMMsgServ, TNMMsg, TNMStrm, TNMStrmServ, TpowerSock, TNMGeneralServer, TNMURL, som antingen implementerar föråldrade protokoll eller har funktionalitet implementerad i en stor grupp av alternativa klasser.

Men till skillnad från sina föregångare - Internet- och Fastnet-komponenterna, innehåller Indy rikare serverkomponenter och komponenter för dataomkodning och kryptering, samt autentiseringsstöd (Indy Misc-palett). Som framgår av tabellen ovan tillhandahålls huvudprotokollen och tjänsterna inte bara av klienten utan också av serverkomponenter. Dessa är tidstjänster, svarstjänster, inhämtning av användarinformation, samt HTTP, NNTP, UDP-protokoll och till och med den enklaste versionen av FTP.

Några exempel på användning av Indy-komponenter

I Indy-komponenter som finns i Delphi definieras IP-adressen i Host-egenskapen, vanligtvis endast i klientapplikationer. Serverbaserade komponenter har metoder som gör att du kan starta eller stoppa polling av motsvarande port - till exempel att ändra egenskapen Active för IdTCPServer-komponenten startar eller stoppar polling av motsvarande port. När anslutningen mellan klienten och servern är upprättad kan dataöverföringen börja.

Indy-komponenter lägger stor vikt vid säkerhet och tillförlitlighet vid arbete med data. Till exempel har IdTCPClient-komponenten Connect och Disconnect metoder. Använda en programmeringsteknik som koden nedan från klientsidan:

med TCPClient, börja Connect; försök lstMain.Items.Add(ReadLn); slutligen Koppla bort; slutet; slutet;

och använda egenskapen Connection som skickas som en parameter till AThread-instansen av klassen TIdPeerThread från serversidan:

med AThread.Connection börjar WriteLn("Hej från Basic Indy Server-server."); Koppla ifrån; slutet;

du kan räkna med antingen normal utförande av anslutningen eller korrekt felhantering.

Notera ReadLn- och WriteLn-metoderna för motsvarande klasser - de liknar standard Pascal I/O-satser. Detta är en hyllning till UNIX-programmeringstekniken, där de flesta systemoperationer utförs genom att läsa och skriva till motsvarande filer.

Precis som Fastnet-komponenter har Indy-komponentklasser händelser som kan användas för att tillhandahålla händelsehantering. Du kan till exempel ordna att ett meddelande visas på ett formulär när du ansluter till en klient:

procedur TForm1.IdECHOServer1Connect(AThread: TIdPeerThread); begin lblStatus.caption:= "[ Betjänar klient ]"; slutet;

Indy tillhandahåller komponenter som implementerar protokoll med klient- och serverdelar som är unika för detta bibliotek. Komponenterna TIdGopherServer och TIdGopher, tack vare metoderna GetExtendedMenu, GetFile, GetMenu, GetTextFile på klientsidan och ReturnGopherItem, SendDirectoryEntry på serversidan, hjälper till att visa filer olika typer, inklusive de som är markerade som dolda, såväl som kataloger på fjärrdator(liknar hur kommandot dir *.* gör det i MS-DOS-operativsystemet).

Med hjälp av IdSMTP- och IdMessage-komponenterna kan du enkelt skapa din egen webbapplikation som kan skicka e-post med SMTP-protokollet.

I det här fallet är IdMessage-klassen (en av 23 komponenter från Indy Misc-sidan) ansvarig för att generera meddelandet, som följer av dess namn, och IdSMTP är för att organisera anslutningen till e-postservern.

Tekniken som används i Indy använder låsande läs- och skrivoperationer. Alla Connect-operationer som används i Indy väntar på att anslutningen ska slutföras. När du arbetar med Indy-klientkomponenter behöver du vanligtvis göra följande:

  • begära en anslutning till servern;
  • göra läs- och skrivförfrågningar till servern (beroende på typen av server utförs steget en gång eller upprepas många gånger);
  • avsluta anslutningen till servern och koppla från.

Indy-komponenter är designade för att ge en ultrahög abstraktionsnivå. Invecklarna och detaljerna i TCP/IP-stacken är dolda för programmeraren så att han kan fokusera på uppgiften.

Följande lilla exempel visar en typisk klientbönsession:

med IndyClient börjar Host:= "zip.pbe.com"; // Värd att anropa Port:= 6000; // Port för att anropa servern på Connect; prova // Din kod går här äntligen Koppla bort; slutet; slutet;

I exemplet, även om anslutningen till servern inte upprättas, kommer anslutningen att avslutas på ett elegant sätt på grund av användningen av try-finally-satsen.

Indys serverkomponenter beskriver en mängd olika servermodeller som kan användas beroende på dina behov och det protokoll du använder.

TIdTCPServer är den mest använda serverkomponenten, som skapar en sekundär process oberoende av huvudapplikationsprocessen. Den skapade processen väntar på inkommande förfrågningar från potentiella klienter. En individuell sekundär process skapas för varje klient vars begäran den svarar på. Händelser som inträffar under underhållsprocessen är relaterade till sammanhanget för motsvarande processer.

Med andra ord, för varje klientanslutning använder klassen TIdTCPServer en unik sekundär tråd genom att anropa den trådens OnExecute-händelsehanterare. Den formella parametern för OnExecute-metoden är en referens till en instans av klassen Athread som motsvarar den skapade tråden. Connection-egenskapen för den här klassen är en referens till klassen TIdTCPConnection, vars instans skapas för att bearbeta klientförfrågan. TIdTCPConnection stöder läsning och skrivning över anslutningen, samt upprättande och avslutande av en kommunikationssession.

UDP-protokollet fungerar utan att först upprätta en anslutning till servern (varje skickat paket är en oberoende uppsättning data och inte en del av en större session eller anslutning). Medan TIdTCPServer skapar separata trådar för varje anslutning, använder TIdUDPServer antingen en huvudtråd eller en enda sekundär tråd som hanterar alla UDP-protokollförfrågningar. När TIdUDPServer är aktiv skapas en tråd för att lyssna efter inkommande UDP-paket. För varje paket som tas emot höjs en OnUDPRead-händelse antingen på huvudtråden eller i kontexten av lyssningstråden, beroende på värdet på egenskapen ThreadedEvent. När ThreadedEvent utvärderas till False inträffar händelsen på huvudtråden, annars inträffar den på lyssnartråden. Medan händelsen bearbetas blockeras andra serveroperationer. Därför är det viktigt att se till att OnUDPRead-procedurer körs så snabbt som möjligt.

Om du behöver skapa en ny klientapplikation för en befintlig server med hjälp av ett befintligt protokoll, är ditt jobb enbart att utveckla och felsöka klientapplikationen. Däremot när du ska utveckla både klient och serverapplikation Oavsett om vi använder ett befintligt eller nytt protokoll, står vi inför det klassiska problemet med "kyckling och ägg". Var ska man börja programmera - från klienten eller från servern?

Självklart måste både klienten och servern skapas så småningom. För många applikationer, särskilt de som använder ett textbaserat protokoll (som HTTP), är det lättare att börja bygga applikationen genom att designa servern. Och för felsökning finns det en bekväm klient som redan finns. Detta är en Telnet-konsolapplikation som är tillgänglig på både Windows och UNIX.

Om du skriver konsolen telnet kommando 127.0.0.1 80 med IP-adressen för den lokala datorn och portnummer 80, som används som standard av webbservrar, då kommer applikationen att svara med texten som visas i Fig. 6, för Windows 2000 OS och IIS 5.0.

För att skapa den enklaste servern med Indy-komponenter behöver du:

Om du behöver designa en server som inte bara korrekt informerar sina klienter när anslutningen bryts, utan också ger dem information om felsituationer som har inträffat, använd try-except-satsen istället för try-finally - till exempel som visas i följande exempel:

procedure TDataModule1.IdTCPServer1Execute(AThread: IdPeerThread); var s: Sträng; börja med AThread.Connection försök försök s:= ReadLn; // Utför serverns uppgift här // om inget undantag görs, // skriv ut serverns svar WriteLn(s); förutom på e: Exception do begin WriteLn(e.Message); end; //on end; //försök utom att slutligen Koppla bort; slut; slut;

Detta lilla exempel visar stegen för att skapa en enkel textserver, samt hur man felsöker den.

Servern som beskrivs ovan är ett typiskt exempel på organisationen av modern distribuerad datoranvändning.

Funktioner för att skapa flerskiktsapplikationer

På senare tid har flera servrar använts alltmer för att tillfredsställa klientförfrågningar. En server av denna typ, som har mottagit en klientförfrågan och delvis förberett den för vidare bearbetning, kontaktar en annan server och skickar den eller de transformerade förfrågningarna till den. Den andra klassens server kan i sin tur kommunicera med andra servrar. Således kan vi prata om en serverarkitektur med flera nivåer.

Därefter kommer vi att skapa en dataåtkomstserver vars syfte är att returnera data från databasen. Den här servern läser eller skriver inte direkt till databasfilerna. Istället kommunicerar den med databasservern på jakt efter den data som klienten kräver.

Så vi börjar utveckla en applikation med en arkitektur i tre nivåer. För att skapa en databasserver med Indy-komponenter behöver du:

  1. Skapa ett nytt projekt.
  2. Placera en instans av TIdTCPServer-komponenten från paletten Indy Servers i projektets huvudform.
  3. Ställ in DefaultPort-egenskapen för klassinstansen TIdTCPServer1 till 6001 (det rekommenderas att tilldela stora värden för att undvika duplicering av portnummer över olika applikationer), och ställ in egenskapen Active till true.
  4. Lägg till en ny modul till projektet genom att välja Arkiv | Nytt | Data Module, och placera instanser av SQLConnection- och SQLDataSet-komponenterna på den från fliken dbExpress på komponentpaletten.
  5. Ställ in egenskapen ConnectionName för klassen SQLConnection till IBLocal och LoginPrompt till False. Om du inte har konfigurerat IBLocal på databasen werknemer.gdb, slutför denna procedur först.
  6. Ställ in SQLConnection-egenskapen för SQLDataSet-klassen till SQLConnection1 och tilldela egenskapen till CommandText SQL-sats: välj CUSTOMER, CONTACT_FIRST, CONTACT_LAST från CUSTOMER där CUST_NO = :cust.

Serge Dosyukov Mike Pham

Den här artikeln visar hur du skapar en fristående webbtjänst med Indy-kitet och Delphi 7, och hur du använder Indy-kitet för att stödja Delphi 7 SOAP-baserade webbtjänster. Bakom ytterligare information För information om hur du skapar webbtjänster, se Nick Hodges utmärkta artikel på Borland community-webbplats: Shakespeare on the Web.

Förr eller senare kan du behöva skapa en server som är en fristående HTTP-server och som stöder webbtjänster. Till exempel kanske du vill skapa en SOAP-baserad applikationsserver för en n-tier applikation byggd med Delphi.

Introduktion

Delphis onlinehjälp ger utmärkt sekventiell instruktion om hur man skapar en webbtjänst, MIDAS-server (COM, DCOM-modell), men det finns praktiskt taget ingen information om att skapa en fristående n-tier MIDAS-applikation baserad på SOAP-protokollet.

Tidigare publicerad av Dave Nottage. Den här artikeln beskrev idén om hur man skapar en webbtjänst i Delphi 6 med SOAP-stöd och möjligheten att publicera SOAP-gränssnitt för Datamodulen, det vill säga den här artikeln tillät dig att lära dig hur du skapar din egen n-tier MIDAS-system.

Borlands Delphi 7 och det nya Indy kitet har inbyggt stöd för denna funktionalitet.

Men trots inbyggt stöd är denna funktion inte dokumenterad.

De senaste inläggen på Borland nätverkskonferens och sökning på webben med hjälp av en Google-server har gjort det möjligt för författarna att utveckla ett sätt att konvertera befintlig kod från Delphi 6 till Delphi 7. Men allt har sin tid.

huvudtanken

Den här artikeln är den första delen av en serie i tre delar. Den beskriver de viktigaste bestämmelserna. Den andra och tredje delen kommer att ägnas åt några problem och sätt att lösa dem. Låt oss börja beskriva huvudidén.

  • vara en fristående HTTP-server;
  • använd Indy som plattform;
  • stödja publicering via SOAP-protokoll;
  • kunna publicera SOAP DataModules, vilket gör att du kan skapa din egen n-tier server baserad på SOAP/HTML.

HTTP-server och SOAP

Många känner till Indy och har använt THTTPServer-komponenter tidigare. Det är lätt att lägga in den här komponenten på en ansökningsblankett, men hur får man den att stödja SOAP? I katalogen "C:Program FilesBorlandDelphi7SourceIndy" kan du hitta filen IdHTTPWebBrokerBridge.pas. Det här är precis vad du behöver.

Den här filen är inte en del av Indys körbara fil, så du måste inkludera den i ditt nuvarande projekt som en standardprojektfil. (För att kompilera projektet behöver du också filen IdCompilerDefines.inc.) Dessa filer måste kopieras till den aktuella projektkatalogen. Kodändringar kan behövas för att öka hastigheten, så det är bäst att hålla dessa filer åtskilda från Indy-distributionen.

Följande beskriver implementeringen av en ersättningskomponent från THTTPServer, utökad för att stödja SOAP-paket, kallad TIdHTTPWebBrokerBridge. Den här konstruktionen är en klass som ärver från TCustomHTTPServer och stöder grundläggande begäranbindning.

Eftersom denna klass inte är tillgänglig från paletten, måste du definiera den som ett vanligt objekt när du kör din kod.

Detta objekt kan användas på exakt samma sätt som en vanlig THTTPServer, med undantag för de ytterligare egenskaper som möjliggör drift med SOAP.
Men låt oss först titta på att förbereda den nödvändiga koden.

WebBroker och Indy

För dig som har skapat webbtjänster tidigare vet du att du använder WebBroker. Delphi 7, liksom Delphi 6, använder WebBroker-arkitekturen för att stödja SOAP.

Därför måste du skapa en modul TWebModule och placera följande tre komponenter i den: THTTPSoapDispatcher, THTTPSoapPascalInvoker och TWSDLHTMLPublish. Alla är tillgängliga från fliken WebServices i komponentpaletten. Efter att ha länkat SOAPDispatcher med SOAPPascalInvoker är ansökningsformuläret klart. Slutresultatet bör vara ungefär som det som visas i följande figur:

(modul uWebModule.pas)

Det är bäst att lämna allt som det är, eftersom det inte finns något behov av att ändra eller köra någon anpassad kod för detta formulär.

WebModule och Indy

Låt oss gå vidare till den andra delen av koden som behövs för att implementera HTTP-servern.

Som du kan se har TIdHTTPWebBrokerBridge en RegisterWebModuleClass-metod, som låter dig registrera din egen WebModule och göra den tillgänglig för servern.

Efter att ha skapat fServer-serverobjektet behöver du alltså bara anropa klassen fServer.RegisterWebModuleClass (TwmSOAPIndy).

Notera. I en normal implementering av TIdHTTPWebBrokerBridge kommer ett TwmSOAPIndy-objekt att skapas varje gång en begäran tas emot. Uppenbarligen är detta inte nödvändigt. Därför kan klassen modifieras för att ge permanent skapelse av detta objekt så länge som Server-objektet existerar. Det rekommenderas att du hänvisar till dokumentationen för klassimplementering för mer information.

Är servern klar?

Introduktion till Indy

Introduktion till Indy
Upplagt av Chad Z. Hower
Hemsida: http://www.atozedsoftware.com
Översättning: Anatoly Podgoretsky
introduktion
Jag skrev den här artikeln när aktuell version var Indy 8.0. Mycket av den här artikeln är tillämplig och mycket användbar i framtida versioner av Indy. Om du gillade den här artikeln och vill läsa mer djupgående artiklar, kolla in boken Indy in Depth.
Indy körs i blockeringsläge
Indy använder blockerande uttag. Blockeringsläge liknar fil läs-skriv. Vid läsning eller skrivning av data återställer funktionen inte kontroll förrän operationen är klar. Skillnaden mot att arbeta med filer är att samtalet kan ta längre tid, eftersom de begärda uppgifterna inte finns ännu, detta beror på hastigheten som ditt nätverk eller modem fungerar med.
Till exempel anropas en metod helt enkelt och väntar tills kontroll återgår till larmpunkten. Om samtalet lyckades kommer kontrollen att returneras från metoden, om ett fel uppstår kommer ett undantag att göras.
Lockdown är inte dödlig
På grund av blockeringsläget har vi blivit slagen många gånger av våra motståndare, men blockeringsläget är inte djävulen.
Problemet uppstod efter portering av Winsock till Windows. I Unix löstes problemet vanligtvis genom gaffel (liknande multi-threading, men med separata processer istället för trådar). Unix-klienter och demoner var tvungna att dela processerna som skulle köras och använda blockeringsläge. Windows 3.x kunde inte parallelliseras och stödde inte mycket trådning. Användning av ett blockerande gränssnitt frös användargränssnittet och gjorde att program inte svarade. Därför lades icke-blockerande lägen till i WinSock, vilket gjorde att Windows 3.x med dess begränsningar kunde använda Winsock utan att blockera programmets huvud- och enda tråd. Detta krävde annan programmering, och Microsoft och andra förtalade passionerat blockeringslägen för att dölja bristerna i Windows 3.x.
Sedan kom Win32, som kunde stödja multi-threading. Men vid det här laget var deras hjärnor redan röriga (det vill säga utvecklarna ansåg att blockering av uttag var djävulens skapelse), och det var redan svårt att ändra vad de hade gjort. Därför fortsätter smutskastningen av blockerande regimer.
I verkligheten har Unix bara blockerande uttag. Blockerande uttag har också sina fördelar och är mycket bättre för multi-threading, säkerhet och andra aspekter. Vissa tillägg har lagts till i Unix för icke-blockerande uttag. De fungerar dock väldigt annorlunda än på Windows. De är också icke-standardiserade och inte särskilt vanliga. Blockerande uttag i Unix används i nästan alla fall, och kommer att fortsätta att användas.
Fördelar med blockeringsläge·Lättare att programmera - Blockeringslägen är lättare att programmera. All användarkod kan finnas på ett ställe och exekveras i en naturlig, sekventiell ordning. ·Lättare att porta till Unix - Eftersom Unix använder blockerande uttag är portabel kod lättare att skriva i det här fallet. Indy använder detta faktum för att skriva enhetlig kod. ·Det är bekvämare att arbeta med trådar - Eftersom blockerande uttag har en sekvens förvärvad av ärftlighet, så de är mycket lätta att använda i trådar.
Nackdelar med blockeringsläge · Användargränssnittet fryser i klienter - Ett blockerande socketanrop ger inte tillbaka kontroll förrän det har slutfört sin uppgift. När ett sådant anrop görs på applikationens huvudtråd kan applikationen inte behandla användarmeddelanden. Detta gör att användargränssnittet fryser, att fönster inte uppdateras och inga andra meddelanden bearbetas förrän kontrollen återställs från den blockerande uttaget.
TIDAntiFreeze-komponent
Indy har en speciell komponent som löser problemet med att frysa användargränssnittet. Lägg bara till en TIDAntiFreeze-komponent var som helst i din applikation och du kan ringa blockerande samtal utan att frysa användargränssnittet.
TIDAntiFreeze körs på en intern timer utanför samtalsstacken och anropar Application.ProcessMessages när timeouten går ut. Externa anrop till Indy fortsätter att blockera och fungerar därför precis som utan att använda TIdAntiFreeze-komponenten. Genom att använda TIdAntiFreeze kan du få alla fördelar med att blockera uttag, utan några av nackdelarna.
Kodtrådar (trådning)
Med blockerande uttag används kodströmmar nästan alltid. Icke-blockerande uttag kan också använda gängor, men detta kräver en del ytterligare bearbetning och deras fördelar i detta fall går förlorade jämfört med blockerande uttag.
Fördelar med trådar·Ställa in prioriteringar - Prioriteringarna för enskilda trådar kan konfigureras. Detta gör att enskilda uppgifter kan allokeras mer eller mindre CPU-tid. ·Inkapsling - Varje anslutning kan innehålla något sken av ett gränssnitt med en annan anslutning. ·Säkerhet - Varje tråd kan ha olika säkerhetsattribut. ·Flera processorer - ger en fördel på system med flera processorer. · Inget behov av serialisering - ger full samtidighet. Utan mycket trådning måste alla förfrågningar behandlas i en tråd. Därför måste varje uppgift delas upp i små bitar så att den kan fungera snabbt. Medan ett block körs tvingas alla andra vänta på att det ska slutföra. I slutet av ett block exekveras nästa och så vidare. Med multithreading kan varje uppgift programmeras som en enda enhet och operativ system fördelar tid mellan alla uppgifter.
Omröstningstrådar
Att skapa och förstöra trådar är mycket resurskrävande. Detta är en särskilt svår uppgift för servrar som har kortlivade anslutningar. Varje server skapar en tråd, använder den under en kort tid och förstör den sedan. Detta resulterar i att trådar skapas och tas bort mycket ofta. Ett exempel på detta är en webbserver. En enda begäran skickas och ett enkelt svar returneras. När du använder en webbläsare kan hundratals anslutningar och avbrott inträffa när du tittar på vilken webbplats som helst.
Omröstningstrådar kan korrigera denna situation. Istället för att skapa och förstöra trådar på begäran, väljs trådar från en lista med oanvända men redan skapade trådar från poolen. När en tråd inte längre behövs återförs den till poolen istället för att förstöras. Trådar i poolen är markerade som oanvända och förbrukar därför inte CPU-tid. För ännu större förbättringar kan trådar dynamiskt anpassa sig till systemets nuvarande behov.
Indy stöder trådundersökning. Trådpoolen i Indy är tillgänglig via TIdThreadMgrPool-komponenten.
Många trådar
En tungt laddad server kan kräva hundratals eller till och med tusentals trådar. Det finns en vanlig uppfattning att hundratals och tusentals trådar kan döda ditt system. Detta är en falsk tro.
På de flesta servrar väntar trådar på data. Medan du väntar på ett blockerande samtal är tråden inaktiv. I en server med 500 trådar kan endast 50 vara aktiva samtidigt.
Antalet trådar som körs på ditt system kan överraska dig. Med ett minsta antal körande servrar och de angivna kör applikationer mitt system har skapat 333 trådar, även med 333 trådar är CPU:n bara 1% laddad. Tungt lastad IIS-server(Microsoft Internet Information Server) kan skapa hundratals och tusentals trådar.
Trådar och globala avsnitt
Med flera trådar måste du säkerställa dataintegritet när du kommer åt den. Detta kan vara svårt för programmerare som inte har arbetat med trådar. Men i allmänhet behöver de flesta servrar inte använda global data. De flesta servrar utför isolerade funktioner. Varje tråd utför sin egen isolerade uppgift. Globala läs/skrivsektioner är en funktion i många flertrådade applikationer, men är inte typiska för servrar.
Metodik Indy
Indy skiljer sig från andra Winsock-komponenter du är van vid. Om du har arbetat med andra komponenter, då den bästa lösningen kommer att glömma hur de fungerar. Många andra komponenter använder icke-blockerande (asynkrona) samtal och fungerar asynkront. De måste reagera på händelser, skapa en tillståndsmaskin och köra frekventa vänteloopar.
Till exempel, med andra komponenter, när du anropar en anslutning måste du antingen vänta på att anslutningshändelsen inträffar eller vänta i en slinga på att en egenskap indikerar att anslutningen har inträffat. Med Indy kan du anropa Connect-metoden och vänta tills den kommer tillbaka. En återbetalning kommer att utfärdas om anslutningen lyckas eller om ett undantag görs om det finns ett problem. Att arbeta med Indy är därför mycket likt att arbeta med filer. Indy låter dig lägga all din kod på ett ställe, istället för att sprida den över olika händelser. Dessutom är Indy väldigt enkelt och bekvämast när man arbetar med trådar.
Hur annorlunda är Indy?
Kort översikt · Blockerande samtal används · Ej händelseorienterade - det finns händelser, men de används för informationsbehov och är egentligen inte nödvändiga. · Designad för trådar - Indy är designad för trådar, men kan användas utan trådar. Sekventiell programmering
Detaljerad recension
Indy använder inte bara blockerande samtal (synkront) utan fungerar också så här. En typisk Indy-session ser ut så här:
med IndyClient börjar
Ansluta; Prova
// Gör dina saker här
slutligen Koppla bort; slutet;
slutet;
Med andra komponenter ser det ut så här:
procedur TFormMain.TestOnClick(Avsändare: TComponent);
Börja
med SocketComponent börjar
Ansluta; Prova
medan den inte är ansluten börjar
om IsError börja då
Avbryta;
slutet;

OutData:= "Data att skicka";
medan length(OutData) > 0 börjar
Application.ProcessMessages;
slutet;
slutligen Koppla bort; slutet;
slutet;
slutet;
procedur TFormMain.OnConnectError;
Börja
IsError:= Sant;
slutet;
procedur TFormMain.OnRead;
var
i: heltal;
Börja
i:= SocketComponent.Send(OutData);
OutData:= Copy(OutData, i + 1, MaxInt);
slutet;
Många komponenter gör inte ett särskilt bra jobb med att isolera programmeraren från stacken. Många komponenter, istället för att isolera användaren från stackens komplexitet, lämnar helt enkelt användaren åt det eller tillhandahåller ett omslag över stapeln.
Indy speciellt sätt
Indy är designad från grunden för att vara flertrådig. Att bygga servrar och klienter i Indy liknar att bygga servrar och klienter i Unix. Unix-applikationer anropar vanligtvis stacken direkt med lite eller inget abstraktionslager.
Vanligtvis har Unix-servrar en eller flera lyssningsprocesser som övervakar inkommande klientförfrågningar. För varje kund som behöver betjänas, a ny process. Detta gör programmeringen enkel, varje process för endast en klient. Varje process körs i sitt eget säkerhetssammanhang, som ställs in av lyssningsprocessen eller processen baserat på befintliga rättigheter, identitet eller andra saker.
Indy-servrar fungerar ungefär på samma sätt. Windows, till skillnad från Unix, kan inte multiplicera processer bra, men det fungerar bra med trådar. Indy-servrar skapar en separat tråd för varje klientanslutning.
Indy-servrar tilldelar en lyssningstråd som är skild från programmets huvudkodtråd. Lyssningstråden lyssnar efter inkommande förfrågningar från klienter. För varje klient som den svarar på skapas en ny tråd för att betjäna klienten. Relevanta händelser servas sedan i sitt sammanhang av denna ström.
Indy kundrecension
Indy är designad för att ge en mycket hög abstraktionsnivå. TCP/IP-stackens krånglighet och detaljer är dolda för programmeraren. Vanligtvis ser en typisk klientsession i Indy ut så här:
med IndyClient börjar
Host:= "zip.pbe.com"; // Värd att ringa
Port:= 6000; // Port att anropa servern på
Ansluta; Prova
// Gör dina saker här
slutligen Koppla bort; slutet;
slutet;
Indy serveröversikt
Indy-serverkomponenter skapar en lyssningstråd som är isolerad från huvudprogrammets kodtråd. Lyssningstråden lyssnar efter inkommande förfrågningar från klienter. För varje klient som den svarar på skapas en ny tråd för att betjäna klienten. Motsvarande händelser servas sedan i sammanhanget för den tråden.

Praktiska exempel
Följande exempel bör hjälpa dig att komma igång med komponenter för lätt att använda, men för att visa exempel gjorda som enkla applikationer. Vissa projekt är gjorda för att visa olika situationer. Dessa exempel är också tillgängliga för nedladdning som zip-filer.
Anmärkning från översättaren: länken på webbplatsen fungerar inte.
Exempel 1 - Postnummerverifiering
Det första projektet är gjort så enkelt som möjligt. Sök efter postnummer, klienten frågar servern vilken stad och delstat det angivna postnumret tillhör.
För de som bor utanför USA och inte vet vad ett postnummer är, är det ett postnummer som anger leveransplatsen. Postnummer består av 5 siffror.
Protokoll
Det första steget i att bygga en server och klient är att utveckla ett protokoll. För standardprotokoll definieras detta av motsvarande RFC. För postnummer definieras protokollet nedan.
De flesta kommunikationsprotokoll fungerar i textläge. Exchange innebär att ett kommando sänds och som svar status och eventuellt data. Protokollen är inte begränsade till utbyte utan vanlig text används fortfarande. Även protokollet för att fastställa postnummer är textbaserat. Oformaterad text gör protokoll lätta att felsöka och låter olika programmeringsspråk och operativsystem kommunicera.
Efter anslutning skickar servern ett hejmeddelande och accepterar sedan kommandot. Detta kommando kan vara "Postnummer x" (där x är postnumret) eller "Avsluta". Som svar på ZipCode-kommandot skickas ett svar i form av en enda rad med svaret eller tom rad om koden inte hittas. Kommandot Quit får servern att stänga anslutningen. Servern kan acceptera flera kommandon innan kommandot Quit skickas.
Serverns källkod

enhet ServerMain;

gränssnitt

använder

typ

TformMain = klass(TForm)

IdTCPServer1: TIdTCPServer;

procedure FormCreate(Sender: TObject );

procedure FormDestroy(Avsändare: TObject ) ;

procedure IdTCPServer1Connect(AThread: TIdPeerThread) ;

privat

ZipCodeList: TStrings;

offentlig

slutet ;

FormMain: TformMain;

genomförande

(R*.DFM)

procedur TformMain.IdTCPServer1Connect (AThread: TIdPeerThread) ;

Börja

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

slutet ;

SCommand: sträng ;

Börja

SCommand:= ReadLn ;

slutet ;

slutet ;

slutet ;

procedure TformMain.FormCreate (Avsändare: TObject );

Börja

ZipCodeList:= TStringList.Create ;

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

slutet ;

procedur TformMain.FormDestroy (Avsändare: TObject );

Börja

ZipCodeList.Free ;

slutet ;

slutet.

De enda Indy-specifika delarna i projektet är IdTCPServer1-komponenten, IdTCPServer1Connect och IdTCPServer1Execute-metoderna.
Formuläret innehåller IdTCPServer1-komponenten av typen TIdTCPServer. Följande egenskaper har ändrats: ·Active = True - När programmet startar lyssnar servern. ·DefaultPort = 6000 - Portvärde för detta projekt. Servern lyssnar efter klientförfrågningar på denna port.
Metoden IdTCPServer1Execute är associerad med serverns OnExecute-händelse. OnExecute-händelsen uppstår efter att klientanslutningen har accepterats. OnExecute-händelsen skiljer sig från andra händelser du känner till. OnExecute körs i kontexten av en tråd. Trådhändelsen höjs och ges AThread-argumentet som skickas till metoden. Detta är viktigt eftersom flera OnExecute-händelser kan köras samtidigt. Detta görs för att servern ska kunna fungera utan att skapa en ny komponent. Det finns även metoder som kan åsidosättas vid konstruktion av arvingar.
OnConnect-händelsen aktiveras efter att anslutningen har accepterats och en tråd har skapats för den. I denna server används detta för att skicka ett välkomstmeddelande till klienten. Om så önskas kan detta även göras i OnExecute-händelsen.
OnExecute-händelsen kan avfyras flera gånger tills anslutningen kopplas bort eller förloras. Detta eliminerar behovet av att kontrollera anslutningen för frånkoppling eller förlust i en slinga inom en händelse.
IdTCPServer1Execute använder två grundläggande funktioner, ReadLn och WriteLn. ReadLn läser en sträng från anslutningen och WriteLn skickar en sträng till anslutningen.
sCommand:= ReadLn;
Ovanstående kod tar en sträng från klienten och placerar den i den lokala sCommand-strängvariabeln.

om SameText (sCommand, "QUIT" ) börja sedan

slut annars om SameText (Kopiera (sCommand, 1 , 8 ), "Postkod " ) och börja sedan

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

slutet ;


Därefter kontrolleras sCommand för giltiga kommandon.
Om kommandot är "Avsluta" utförs frånkoppling. Ingen läsning eller skrivning är tillåten efter frånkoppling. Efter att händelsen avslutats anropar den inte längre avlyssningstråden, utan rensar tråden och avslutar anslutningen.
Om kommandot är "ZipCode", så extraheras parametern efter kommandot och tabellen skannas för närvaron av staden och staten. Staden och staten skickas sedan till klienten, eller så skickas en tom sträng om det inte finns någon matchning.
Därefter avslutas metoden. Servern kommer att återuppta händelsen igen så snart ett nytt kommando kommer, vilket gör att klienten kan skicka flera kommandon.
Klientens källkod

enhet ClientMain;

gränssnitt

använder

Windows, meddelanden, SysUtils, klasser, grafik, kontroller, formulär, dialogrutor,

StdCtrls, ExtCtrls, IdAntiFreezeBase,

IdAntiFreeze, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;

typ

TformMain = klass(TForm)

Klient: TIDTCPClient;

IdAntiFreeze1: TIdAntiFreeze;

Panel1: TPanel;

Panel2: TPanel;

MemoInput: TMemo;

LboxResults: TListBox;

Panel3: TPanel;

Knapp1: TBnapp;

Knapp2: TBnapp;

Etikett1: TLabel;

procedure Button2Click(Sender: TObject );

procedure Button1Click(Sender: TObject );

privat

offentlig

slutet ;

FormMain: TformMain;

genomförande

(R*.DFM)

procedure TformMain.Button2Click (Avsändare: TObject );

Börja

MemoInput.Clear ;

LboxResults.Clear ;

slutet ;

procedure TformMain.Button1Click (Avsändare: TObject );

I: heltal ;

S: sträng ;

Börja

ButnLookup.Enabled := true ; Prova

LboxResults.Clear ;

med klienten börjar

Ansluta; Prova

LboxResults.Items.Add(ReadLn);

för i:= 0 till memoInput.Lines .Count - 1 börjar

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

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

S:= ReadLn ;

om s = "" börja då

S:= "-- Ingen post hittades för detta postnummer.";

slutet ;

LboxResults.Items.Add(s);

LboxResults.Items.Add("");

slutet ;

WriteLn("Avsluta");

slutligen Koppla bort; slutet ;

slutet ;

slutligen butnLookup.Enabled := true ; slutet ;

slutet ;

slutet.


De enda delarna som är specifika för klientkomponenten är Button1Click-metoden.
Klientkomponenten är av typen TIdTCPClient och placeras på formuläret. Följande egenskaper har ändrats: ·Host = 127.0.0.1 - Servern finns på samma maskin som klienten. ·Port = 6000 - Serverport
Button1Click-metoden är associerad med OnClick-händelsen för Button1-komponenten. När knappen klickas anropas denna metod. Indy-delen av denna metod kan reduceras till följande: 1.Anslut till servern (Anslut;) 1.Läs hälsningen från servern. 1. För varje rad som användaren anger i TMemo: 1. Skicka en begäran till servern (WriteLn("Postkod " + memoInput.Lines[i]);) 1. Läsa ett svar från servern (s:= ReadLn; ) 1. Skickar kommandot Quit (WriteLn("Avsluta");) 1.Koppla bort (Koppla bort;)
Testning
Det här exemplet har testats och fungerar med TCP/IP installerat. Du kan ändra den så att den fungerar över ett nätverk från en dator till en annan. Genom att starta servern på en annan dator och ändra namn eller IP på servern på klienten.
För att testa projekt, kompilera och kör servern. Kompilera och kör sedan klienten. Ange ditt postnummer i memofältet och tryck på uppslagstangenten.
Felsökning
Textprotokoll är mycket lätta att felsöka eftersom de kan testas med Telnet. För att göra detta räcker det att känna till serverporten. ZIP Code Lookup Server lyssnar på port 6000.
Starta ZIP Code Lookup Server igen. Öppna sedan en konsol (t.ex. ett Dos-fönster). Ange nu:
telnet 127.0.0.1 6000
Du är nu ansluten till servern. Vissa servrar skickar också ett välkomstmeddelande. Vissa gör det inte. Du kommer inte att se raderna du anger. De flesta servrar ekar inte för att spara trafik. Du kan dock ändra telnet-inställningarna genom att ställa in alternativet "Echo On". Detta görs olika i olika telnet-klienter, och vissa har inte den här funktionen alls. Ange nu:
postnummer 37642
Du kommer att se serverns svar:
CHURCH HILL, TN
För att koppla från servern anger du:
sluta
Exempel 2 - databasåtkomst
Det här exemplet emulerar en server som måste utföra andra blockeringsuppgifter än socket-anrop. Många servrar tvingas arbeta under sådana förhållanden. Servrar som behöver komma åt databasen, anropa externa procedurer eller beräkningar kan ofta inte avbryta dessa samtal, eftersom de är externa samtal eller på grund av komplexiteten i detta. Åtkomst till databasen kan inte delas upp i små bitar och utvecklaren måste vänta på slutet av operationen med databasen. Detta är en funktion inte bara för databasanrop, utan också för andra operationer såsom komprimering, beräkningar och annan bearbetning av samma slag.
För demonstrationsändamål, låt oss föreställa oss att servern gör ett databasanrop som tar 5 sekunder att slutföra. För att förenkla, låt oss göra detta helt enkelt med en paus, använd Sleep(5000)-funktionen för detta, istället för att faktiskt ringa.
Det här exemplet kräver också mindre detaljer än det föregående exemplet eftersom många av begreppen ännu inte är förstått.
Källa

huvudenhet;

gränssnitt

använder

Windows, meddelanden, SysUtils, klasser, grafik, kontroller, formulär, dialogrutor,

IdBaseComponent, IdComponent, IdTCPServer;

typ

TformMain = klass(TForm)

IdTCPServer1: TIdTCPServer;

procedure IdTCPServer1Execute(AThread: TIdPeerThread) ;

privat

offentlig

slutet ;

FormMain: TformMain;

genomförande

(R*.DFM)

procedure TformMain.IdTCPServer1Execute (AThread: TIdPeerThread) ;

I: heltal ;

Börja

med AThread.Connection börjar

WriteLn("Hej. DB-server redo." );

I:= StrToIntDef(ReadLn, 0);

// Sleep ersätter ett långt DB eller annat samtal

Sömn(5000);

WriteLn(IntToStr(i * 7));

slutet ;

slutet ;

slutet.

Eftersom Execute-händelsen inträffar i kontexten av en tråd, kan bearbetningskoden vara av valfri längd. Varje klient har sin egen tråd och blockerar inte andra klienter.
Testning
För att testa DB-servern, kompilera och kör den. Anslut till den med Telnet till port 6001. Servern kommer att svara med ett välkomstmeddelande. Skriv in nummer. Servern kommer att "behandla" din förfrågan och svara inom 5 sekunder.

UDP-protokollet är ganska bra för att överföra textmeddelanden, det vill säga du kan organisera lokala chattar och liknande. Jag bestämde mig för att ge ett exempel på det enklaste arbetet med UDP i Delphi.

Steg-för-steg-instruktion:

Jag gav ett exempel, men förlåt mig, jag skrev inte ner varje rad, för... Jag ser inget komplicerat och vem som helst kan lista ut det.

Om något är oklart kan du faktiskt ställa en fråga till mig. Och här är den faktiska koden:

använder
Windows, meddelanden, SysUtils, varianter, klasser, grafik, kontroller, formulär,
Dialoger, StdCtrls, IdUDPServer, IdBaseComponent, IdComponent, IdUDPBase,
IdUDPClient, IdSocketHandle;

typ
TForm1 = klass(TForm)
IdUDPClient1: TIdUDPClient;
IdUDPServer1: TIdUDPServer;
Knapp1: TBnapp;
Etikett1: TLabel;
procedure FormCreate(Avsändare: TObject);
procedure FormClose(Avsändare: TObject; var Action: TCloseAction);
procedure Button1Click(Avsändare: TObject);
procedur IdUDPServer1UDPRead(ATråd: TIdUDPListenerThread; AData: TBytes;
ABinding: TIdSocketHandle);
privat
(Privata deklarationer)
offentlig
(Offentliga deklarationer)
slutet;

var
Form1: TForm1;

($R *.dfm)
[b]//Procedur för att skicka ett meddelande
procedure TForm1.Button1Click(Avsändare: TObject);
Börja
Prova
IdUDPClient1.Active:= Sant;
IdUDPClient1.Host:= "localhost";
IdUDPClient1.Connect;
om IdUDPClient1.Connected då
Börja
IdUDPClient1.Send(TimeToStr(Time));
Label1.Caption:= "ok";
slutet;
IdUDPClient1.Active:= False;
Beep;Beep;Beep;
bortsett från
MessageDlg("Något gick fel =(", mtError, , 0);
slutet;
slutet;
[b]
//På av. UDP-server vid start och stängning av formuläret
procedure TForm1.FormClose(Avsändare: TObject; var Action: TCloseAction);
Börja
IdUDPServer1.Active:= Falskt;
slutet;

procedur TForm1.FormCreate(Avsändare: TObject);
Börja
IdUDPServer1.Active:= Sant;
slutet;

[b]//Serverreaktionsprocedur vid mottagning av data
procedur TForm1.IdUDPServer1UDPRead(ATråd: TIdUDPListenerThread;
AData: TBytes; ABinding: TIdSocketHandle);
Var
i: Heltal;
s:Sträng;
Börja
s:= "";
Prova
i:= 0;
medan (AData[i] 0) gör
Börja
s:= s + chr(AData[i]);
i:= i + 1;
slutet;
till sist
Label1.Caption:= s;
slutet;
slutet;