Programování socketů v Delphi. Server

19.08.2023

Tento článek pojednává o základních vlastnostech a funkcích komponent Delphi: TClientSocket a TServerSocket – slouží k práci se sítí pomocí protokolu TCP\IP.

Pozornost! Pokud používáte verzi Delphi vyšší než 6.0, musíte nejprve nainstalovat Sockets Components ve všech verzích Delphi, a to následovně:

  • Přejděte do dialogu Instalovat balíčky...: (Hlavní nabídka) Komponenta -> Instalovat balíčky;
  • Klikněte na tlačítko Přidat…, po kterém najdeme složku Bin vašeho Delphi (například: C:\Program Files\Borland\Delphi 7\bin nebo C:\Program Files\Embarcadero\RAD Studio\7.0\Bin) ;
  • V nalezené složce Bin již hledáme soubor dclsockets [tady jsou čísla].bpl, klepněte na OK;
  • Jsme rádi, protože nyní máme na záložce Internet v panelu komponent dvě skvělé komponenty TServerSocket a TClientSocket.

Při vývoji jakýchkoli síťových aplikací obvykle vývoj vždy začíná na serveru (samozřejmě, pokud máte tým, mohou návrháři rozhraní začít pracovat na klientovi). K implementaci serveru překvapivě potřebujete použít TServerSocket.

Základní vlastnosti:

  • Aktivní– booleovské pole, je-li nastaveno na hodnotu true – server se spustí, můžete jej použít buď přiřazením konkrétních hodnot, nebo voláním funkcí ServerSocket1.Open (... Active:=true;) nebo ServerSocket1.Close (.. Aktivní:=false).
  • Přístav– port, na kterém bude server naslouchat (přijímat klienty), jakákoli hodnota v rozsahu, který není obsazený jinými servery v systému celé číslo.

Hlavní události:

  • OnListen– volá se, když je server nastaven do režimu poslechu, lze jej použít, když potřebujeme zjistit čas skutečného spuštění serveru.
  • OnClientRead– volá se při přijetí dat od klienta.
  • OnClientError
  • OnClientConnect– Volá se, když se k serveru připojí nový klient.
  • OnClientDisconnect– obrácená událost k události, OnClientConnect

každá funkce události má atribut Socket: TCustomWinSocket, je předán ukazatel na objekt soketu, se kterým právě pracujeme, pokud potřebujeme odpovědět nebo udělat něco s klientem, který událost způsobil, musíme použít tento konkrétní objekt, ve všech ostatních případech používáme ServerSocket1.Socket, podobná situace je s klientskou komponentou.

Vlastnosti a funkce pouze pro čtení:

  • – vrací počet aktivních spojení.
  • ServerSocket1.Socket.Connections– pole objektů typu TCustomWinSocket, pole všech objektů spojených s klienty, index počítání začíná od 0, délka pole je ServerSocket1.Socket.ActiveConnections.
  • Funkce a vlastnosti, které se vztahují na prvky pole ServerSocket1.Socket.Connections a atribut Socket předané funkci události serveru:
  • Socket.LocalHost
  • Socket.LocalAddress– vrátí IP serveru.
  • Socket.RemoteHost
  • Socket.RemoteAddress– vrátí IP klienta.
  • Socket.ReceiveText– vrátí textovou zprávu přijatou od klienta, po které vymaže vyrovnávací paměť, lze použít pouze 1krát, na 1 příjem.
  • Socket.SendText(Text)– odešle klientovi textovou zprávu typu Text tětiva.

U komponenty TClientSocket je vše prakticky stejné, pouze obráceně + hlavní vizuální rozdíl mezi serverem a klientem je v tom, že server v systému lze spustit 1 x 1 hodnota portu, počet klientů je omezen pouze RAM .

Základní vlastnosti:

  • Aktivní– booleovské pole, je-li nastaveno na hodnotu true – klient se pokouší připojit k serveru, lze použít buď přiřazením konkrétních hodnot, nebo voláním funkcí ClientSocket1.Open (... Active:=true;) nebo ClientSocket1 .Zavřít (... Aktivní:=false) .
  • Přístav– port, přes který se může klient připojit k serveru, libovolná hodnota v rozsahu celé číslo.
  • Adresa– IPv4 adresa typu serveru tětiva podle šablony 255.255.255.255, se kterou se klient spojí.

Hlavní události:

  • OnRead– volá se při příjmu dat ze severu.
  • OnError– volá se, když dojde k chybě při přenosu dat.
  • OnConnecting– Volá se, když se klient připojí k serveru.
  • OnDisconnect– obrácená událost k události, OnConnecting, volá se, když se klient odpojí od serveru.

Vlastnosti a funkce pouze pro čtení:

  • ClientSocket1.Socket.SendText() tětiva
  • Socket.LocalHost– vrátí online jméno klienta.
  • Socket.LocalAddress– vrátí IP klienta.
  • Socket.RemoteHost– vrátí název serveru v síti.
  • Socket.RemoteAddress– vrátí IP serveru.
  • Socket.ReceiveText– vrátí textovou zprávu přijatou ze serveru, po které vymaže vyrovnávací paměť, lze použít pouze 1x najednou.
  • Socket.SendText(Text)– odešle na server textovou zprávu typu Text tětiva.

Poskytnuté informace jsou dostačující pro implementaci malého chatu na serveru, který vyhovuje Technické specifikace: internet_sockets.doc (Word Doc 97-2003, 26,5 Kb).

Tento článek byl napsán v neděli 10. října 2010 v 1:24 v rubrice. Můžete se přihlásit k odběru aktualizací komentářů k článku -. Můžeš

Úvod

Tento článek je věnován vytváření aplikací architektury klient/server v Borland Delphi založených na soketech („sockety“ - hnízda). Na rozdíl od předchozího článku na téma sockety se zde podíváme na tvorbu serverových aplikací.

Ihned je třeba poznamenat, že pro koexistenci samostatných klientských a serverových aplikací není nutné mít několik počítačů. Stačí mít jen jeden, na kterém můžete současně provozovat server i klienta. V tomto případě musíte jako název počítače, ke kterému se chcete připojit, použít název hostitele localhost nebo IP adresa - 127.0.0.1 .

Začněme tedy teorií. Pokud jste přesvědčený praktik (a nevidíte žádné algoritmy očima), měli byste tuto část přeskočit.

Algoritmus provozu soketového serveru

Co vám soketový server umožňuje?.. Na jakém principu funguje?.. Server založený na soketovém protokolu umožňuje obsluhovat mnoho klientů najednou. Navíc si můžete sami určit limit jejich počtu (nebo tento limit úplně odstranit, jak je standardně provedeno). Pro každého připojeného klienta server otevře samostatný soket, jehož prostřednictvím si můžete vyměňovat data s klientem. Dalším skvělým řešením je vytvoření samostatného procesu (Thread) pro každé připojení.

Podívejme se na diagram podrobněji:

  • Definice vlastností Port a ServerType - aby se klienti mohli normálně připojit k serveru, je nutné, aby port používaný serverem přesně odpovídal portu používanému klientem (a naopak). Vlastnost ServerType určuje typ připojení (další podrobnosti viz níže);
  • Otevření zásuvky - otevření zásuvky a zadaného portu. Zde automaticky začneme čekat na připojení klientů ( Poslouchat);
  • Připojení klienta a výměna dat s ním - zde se klient připojuje a vyměňuje si s ním data. Více o této fázi se dozvíte níže v tomto článku a v článku o socketech (klientská část);
  • Deaktivace klienta - Zde se klient odpojí a jeho soketové spojení se serverem je uzavřeno;
  • Zavření serveru a soketu - Na příkaz administrátora se server vypne, zavře všechny otevřené soketové kanály a přestane čekat na připojení klientů.

Nutno podotknout, že body 3-4 se mnohokrát opakují, tzn. Tyto kroky se provádějí pro každé nové připojení klienta.

Poznámka : V Delphi je v současné době velmi málo dokumentace k socketům, takže pokud chcete toto téma prostudovat co nejhlouběji, doporučuji vám prostudovat si literaturu a elektronickou dokumentaci o systémech Unix/Linux – tam Velmi Teorie práce se zásuvkami je dobře popsána. Kromě toho existuje mnoho příkladů soketových aplikací pro tyto operační systémy (ačkoli většinou v C/C++ a Perlu).

Stručný popis komponenty TServerSocket

Zde se seznámíme s hlavní vlastnosti, metody a události komponenty TServerSocket.

Vlastnosti Metody Události
Zásuvka - třída TServerWinSocket, prostřednictvím které máte přístup k otevřeným soketovým kanálům. Dále se budeme touto vlastností zabývat podrobněji, protože je ve skutečnosti jedním z hlavních. Typ: TServerWinSocket ;
ServerType - typ serveru. Může nabývat jedné ze dvou hodnot: stNonBlocking- synchronní práce s klientskými sokety. S tímto typem serveru můžete pracovat s klienty prostřednictvím událostí OnClientRead A OnClientWrite. stThreadBlocking- asynchronní typ. Pro každý klientský soketový kanál je vytvořen samostatný proces (vlákno). Typ: TServerType ;
ThreadCacheSize - počet klientských procesů (vlákno), které budou ukládány do mezipaměti serveru. Zde musíte vybrat průměrnou hodnotu v závislosti na zatížení vašeho serveru. Ke ukládání do mezipaměti dochází proto, aby se pokaždé nevytvářel samostatný proces a nezabil uzavřený soket, ale aby byly ponechány pro pozdější použití. Typ: Celé číslo ;
Aktivní - indikátor, zda je server v daný okamžik aktivní nebo ne. To je ve skutečnosti hodnota Skutečný označuje, že server běží a je připraven přijímat klienty, a Nepravdivé- server je vypnutý. Chcete-li spustit server, musíte tuto vlastnost jednoduše nastavit na Skutečný. Typ: Boolean ;
Přístav - číslo portu pro navazování spojení s klienty. Porty serveru a klienta musí být stejné. Doporučují se hodnoty od 1025 do 65535, protože od 1 do 1024 - může být obsazeno systémem. Typ: Celé číslo ;
Servis - řetězec definující službu ( ftp, http, pop, atd.), jehož port bude použit. Jedná se o jakýsi adresář čísel portů odpovídajících různým standardním protokolům. Typ: tětiva ;
OTEVŘENO - Spustí server. Tento příkaz je v podstatě identický s přiřazením hodnoty Skutečný vlastnictví Aktivní;
Zavřít - Zastaví server. Tento příkaz je v podstatě identický s přiřazením hodnoty Nepravdivé vlastnictví Aktivní.
OnClientConnect - dochází, když klient navázal soketové připojení a čeká na odpověď ze serveru ( OnAccept);
OnClientDisconnect - Vyskytuje se, když se klient odpojí od soketového kanálu;
OnClientError - nastane, když aktuální operace selže, tzn. Došlo k chybě;
OnClientRead - nastane, když klient předá serveru nějaká data. K těmto datům lze přistupovat prostřednictvím parametru passable Socket: TCustomWinSocket;
OnClientWrite - nastává, když server může odesílat data klientovi přes soket;
OnGetSocket - v handleru této události můžete upravit parametr ClientSocket;
OnGetThread - v handleru této události můžete definovat jedinečný proces (Thread) pro každý jednotlivý klientský kanál přiřazením parametru SocketThread požadovaný dílčí úkol TServerClientThread;
OnThreadStart , OnThreadEnd - nastane, když je spuštěn nebo zastaven dílčí úkol (proces, vlákno);
OnAccept - nastane, když server přijme klienta nebo mu odmítne spojení;
OnListen - nastane, když server přejde do režimu čekání na připojení klientů.

TServerSocket.Socket(TSServerWinSocket)

Jak tedy může server odesílat data klientovi? A co příjem dat? Hlavně pokud pracujete přes události OnClientRead A OnClientWrite, pak můžete komunikovat s klientem prostřednictvím parametru ClientSocket (TCustomWinSocket). O práci s touto třídou si můžete přečíst v článku o klientských soketech, protože odesílání/odesílání dat přes tuto třídu je podobné - metody (Send/Receive)(Text,Buffer,Stream). Totéž platí při práci s TServerSocket.Socket. Nicméně, protože Zde uvažujeme o serveru, měli bychom zdůraznit některé užitečné vlastnosti a metody:

  • Aktivní připojení (Celé číslo) - počet připojených klientů;
  • ActiveThreads (Celé číslo) - počet běžících procesů; Spojení (pole) - pole sestávající ze samostatných tříd TClientWinSocket pro každého připojeného klienta. Například tento příkaz:
    ServerSocket1.Socket.Connections.SendText("Ahoj!");
    odešle zprávu „Ahoj“ prvnímu připojenému klientovi. Příkazy pro práci s prvky tohoto pole - také (Send/Receive)(Text,Buffer, Stream);
  • IdleThreads (Celé číslo) - počet volných procesů. Tyto procesy jsou ukládány do mezipaměti serveru (viz ThreadCacheSize);
  • LocalAddress, LocalHost, LocalPort- respektive - místní IP adresa, název hostitele, port;
  • RemoteAddress, RemoteHost, RemotePort- respektive - vzdálená IP adresa, název hostitele, port;
  • Metody Zámek A Odemknout- respektive blokování a odblokování zásuvky.

Praxe a příklady

Nyní se podívejme na výše uvedené na konkrétním příkladu. Hotové zdroje si můžete stáhnout kliknutím.

Podívejme se tedy na velmi dobrý příklad práce s TServerSocket (tento příklad je nejnázornější pomůckou pro studium této komponenty). Níže uvedené zdroje demonstrují protokolování všech důležitých událostí serveru a navíc možnost přijímat a odesílat textové zprávy:

Příklad 1 Logování a studium provozu serveru, odesílání/příjem zpráv přes sokety.

(...Zde je záhlaví souboru a definice formuláře TForm1 a jeho instance Form1) (Viz celý zdroj) procedure TForm1.Button1Click(Sender: TObject); začít (Určete port a spusťte server) ServerSocket1.Port:= 1025; (Metoda Insert vloží řetězec do pole na zadané pozici) Memo2.Lines.Insert(0,"Server se spouští"); ServerSocket1.Open; konec; procedure TForm1.Button2Click(Sender: TObject); začít (Zastavit server) ServerSocket1.Active:= False; Memo2.Lines.Insert(0,"Server zastaven"); konec; procedure TForm1.ServerSocket1Listen(Sender: TObject; Socket: TCustomWinSocket); začít (Zde server "naslouchá" na soketu pro klienty) Memo2.Lines.Insert(0,"Poslouchání na portu "+IntToStr(ServerSocket1.Port)); konec; procedure TForm1.ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket); začít (Zde server přijímá klienta) Memo2.Lines.Insert(0,"Připojení klienta přijato"); konec; procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); začít (zde se klient připojí) Memo2.Lines.Insert(0,"Klient připojen"); konec; procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); začít (Tady se klient odpojí) Memo2.Lines.Insert(0,"Klient odpojen"); konec; Memo2.Lines.Insert(0,"Nyní lze zapisovat do soketu"); konec; procedure TForm1.ServerSocket1GetSocket(Sender: TObject; Socket: Integer; var ClientSocket: TServerClientWinSocket); begin Memo2.Lines.Insert(0,"Získat zásuvku"); konec; procedure TForm1.ServerSocket1GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread); begin Memo2.Lines.Insert(0,"Získat vlákno"); konec;< "+Edit1.Text); end;

procedure TForm1.ServerSocket1ThreadEnd(Sender: TObject; Thread: TServerClientThread); begin Memo2.Lines.Insert(0,"Konec vlákna"); konec;

procedure TForm1.ServerSocket1ThreadStart(Sender: TObject; Thread: TServerClientThread); begin Memo2.Lines.Insert(0,"Začátek vlákna"); konec;

procedure TForm1.Button3Click(Sender: TObject); var i: celé číslo; začít (Odeslat zprávu VŠEM klientům z Edit1) for i:= 0 to ServerSocket1.Socket.ActiveConnections-1 do begin ServerSocket1.Socket.Connections[i].SendText(Edit1.Text); konec;

Memo1.Lines.Insert(0,"

Techniky pro práci s TServerSocket (a jednoduše se sockety)

Ukládání jedinečných dat pro každého klienta. Jistě, pokud váš server bude obsluhovat mnoho klientů, budete muset uložit nějaké informace pro každého klienta (jméno atd.) a svázat tyto informace se soketem tohoto klienta. V některých případech není toto vše provádět ručně (navázání na úchyt soketu, klientská pole atd.) příliš pohodlné. Proto pro každou zásuvku existuje speciální vlastnost - Data . Data jsou ve skutečnosti jen ukazatelem. Proto při zápisu klientských dat do této vlastnosti buďte opatrní a dodržujte pravidla práce s ukazateli (alokace paměti, definice typu atd.)!)

Odesílání souborů přes socket.

Zde se podíváme na odesílání souborů přes socket (na žádost JINX) :-). Jak tedy odeslat soubor přes soket? Velmi jednoduché! Vše, co musíte udělat, je otevřít tento soubor jako souborový stream (TFileStream) a odeslat jej přes soket (SendStream)! Podívejme se na to na příkladu: Je třeba poznamenat, že metoda! Nejprve je tedy třeba poznamenat, že data odeslaná přes socket lze nejen sloučit do jednoho bloku, ale také rozdělit do několika bloků. Faktem je, že socket je běžný stream, ale na rozdíl, řekněme, souborového streamu (TFileStream), přenáší data pomaleji (rozuměj - síť, omezený provoz, atd.). Proto dva příkazy:
ServerSocket1.Socket.Connections.SendText("Dobrý den, ");
ServerSocket1.Socket.Connections.SendText("svět!");
zcela identické s jedním příkazem:
ServerSocket1.Socket.Connections.SendText("Ahoj, světe!");

A to je důvod, proč, pokud odešlete soubor řekněme 100 KB přes socket, pak osoba, které jste tento blok poslali, obdrží několik bloků o velikostech, které závisí na provozu a přetížení linky. Navíc velikosti nemusí být nutně stejné. Z toho vyplývá, že za účelem přijetí souboru nebo jakýchkoli jiných dat velká velikost Měli byste přijmout bloky dat a poté je spojit do jednoho celku (a uložit jej například do souboru). Vynikajícím řešením tohoto problému je stejný souborový stream - TFileStream (nebo stream v paměti - TMemoryStream). Prostřednictvím události OnRead (OnClientRead) můžete přijímat kousky dat ze soketu pomocí univerzální metody ReceiveBuf. Pomocí metody můžete určit velikost výsledného bloku ReceiveLength. Můžete také použít soketový stream (viz článek o TClientSocket). A zde je malý příklad (přibližný):

Jak monitorovat zásuvku

Tato problematika je složitá a vyžaduje dlouhé zvážení. Prozatím jen poznamenám, že vždy můžete sledovat zásuvku vytvořenou vaším programem :-). Sokety (jako většina objektů ve Windows) mají svůj vlastní popisovač zapsaný ve vlastnosti Handle. Jakmile tedy rozpoznáte tento deskriptor, budete moci volně spravovat jakýkoli soket (dokonce i ten, který vytvořil cizí program)! S největší pravděpodobností však pro sledování soketu někoho jiného budete muset používat výhradně funkce WinAPI Sockets.

Epilog

Tento článek ukazuje základní techniky pro práci s komponentou TServerSocket v Delphi a několik obecných technik pro výměnu dat přes sokety. Pokud máte dotazy, pošlete mi je na e-mail: [e-mail chráněný], a ještě lépe - napište do konference tohoto webu (Delphi. Obecné otázky), aby ostatní uživatelé viděli vaši otázku a pokusili se na ni odpovědět!

Karikh Nikolay ( Nitro). moskevský region, Žukovskij

přidal jsem síťová podpora. To znamená, že vytvořil samostatný server a samostatného klienta. Myšlenka je taková, že aplikační server běží, uživatel spustí klienta a zadá požadavek do uživatele: Moscow Tverskaya 6. Poté server požadavek zpracuje, obdrží výsledky vyhledávání z Yandex.Maps a odešle výsledný obrázek klientovi, pak v klientovi komponenta TMap zobrazí část dané karty, která odpovídá požadavku uživatele. Díky tomu jej může uživatel škálovat, ukládat a podobně.

Proto vám v tomto článku chci říct, jak jsem implementoval klienta a server. Udělal jsem to pomocí TClientSocket a TServerSocket, v tomto článku se podrobně podíváme na metody, které jsem použil ve svém projektu.

Nejprve se podívejme, jak můžete nainstalovat tyto součásti do vašeho IDE. Pokud používáte IDE Delphi 7, pak jsou tyto komponenty ve výchozím nastavení přítomny, ale bohužel nejsou nainstalovány, ale to není problém. Stačí otevřít Delphi a nainstalovat.

Chcete-li to provést, spusťte příkaz Component-Install Packages... a v zobrazeném okně klikněte na tlačítko Přidat. Poté musíte zadat cestu k souboru dclsockets70.bpl, který se obvykle standardně nachází ve složce BIN. Poté musíte kliknout na tlačítko OK. Všechny vaše komponenty by se měly objevit na záložce Internet (TClientSocket a TServerSocket).

V projektu jsem začal veškerou práci s minimálním vývojem serveru. Nejprve jsem na formulář nainstaloval komponentu TServerSocket. A kliknutím na tlačítko Spustit server nastavím počáteční nastavení pro jeho inicializaci:

Server. Port:=Nastavení formuláře. SpinEditPort. Hodnota ; //určete port serveru Server. Aktivní: = Pravda; //aktivujte to Server. OTEVŘENO ; pokud Server. Aktivní, pak začněte//zobrazí zprávu, že server je v provozu konec ;

……..

//zobrazí chybu, pokud se server nespustil

Pro inicializaci serveru na mém počítači jsem pouze určil volný port (který není obsazený jinými aplikacemi) a aktivoval jej.

V zásadě je to vše, k práci mi stačilo, aby server běžel a mohl jsem zpracovávat klientské požadavky, které odesílají. //monitoruje připojení klienta RichEditLog. SelAttributes. Barva:=clZelená; RichEditLog. SelAttributes. Styl: = [fsBold]; CheckListClient. Položky. Add(Socket.RemoteHost); RichEditLog. Čáry. Add ("[" + TimeToStr (Time ) + "] Klient připojen: " + Socket. RemoteHost ) ; //přidat klienta, který se připojil, do seznamu RichEditLog. Provést (WM_VSCROLL, SB_BOTTOM, 0) ; konec ;

To znamená, že přidám do seznamu jména těch klientů, kteří se připojují k serveru, abych o nich dále získal informace.

Můžete například získat podrobné informace o klientovi:

procedura TFormInfoClient. FormShow(Sender: TObject); začít //zobrazí informace o klientovi Titulek: = "Informace o zákazníkovi: "+ FormServer. CheckListClient. Položky[FormServer. CheckListClient. ItemIndex ] ; LocalName. Titulek: = FormServer. Server. Zásuvka. Připojení[FormServer. CheckListClient. ItemIndex] . LocalHost ; LocalHost. Titulek: = FormServer. Server. Zásuvka. Připojení[FormServer. CheckListClient. ItemIndex] . LocalAddress; LocalPort. Caption : = IntToStr ( FormServer . Server . Socket . Připojení [ FormServer . CheckListClient . ItemIndex ] . LocalPort ) ; RemoteName. Titulek: = FormServer. Server. Zásuvka. Připojení[FormServer. CheckListClient. ItemIndex] . RemoteHost ; RemoteHost. Titulek: = FormServer. Server. Zásuvka. Připojení[FormServer. CheckListClient. ItemIndex] . RemoteAddress; RemotePort. Caption: = IntToStr(FormServer. Server. Socket. Připojení[ FormServer. CheckListClient. ItemIndex]. RemotePort); konec ;

Lze získat následující údaje:

  • Místní název
  • Místní adresa
  • Místní přístav
  • Odebráno jméno
  • Vzdálená adresa
  • Vzdálený port

Informace o klientovi dostávám pomocí tohoto kódu, který jsem vybral v seznamu komponenty TCeckListBox.

Jak vidíte, není nic složitého, abyste mohli odeslat zprávu klientovi, můžete použít následující kód:

V hranatých závorkách uvedu, kterému klientovi zprávu pošleme (to se rovná vybranému klientovi v komponentě TCeckListBox), ve zprávě uvedu #message# - což znamená, že se jedná o běžnou zprávu ze serveru, která by měla se jednoduše zobrazí v okně.

Abychom dostali zprávu od klienta na server, budeme potřebovat událost OnClientRead komponenty TServerSocket a textovou proměnnou, do které zaznamenáme požadavek, který klient odešle.

procedura TFormServer. ServerClientRead(Sender: TObject; Socket: TCustomWinSocket) ; var dotaz: String ; začít //přijmout od klienta požadavek na kartu zkuste dotaz: = Socket. ReceiveText ; if pos ("dotaz" , dotaz)<>0 pak začněte //požadavek od Yandex nebo Google souřadnice karty dle požadavku klienta konec ; //pokud je to pouze zpráva od klienta, zobrazte ji if pos ("#zpráva#" , dotaz)<>0 pak začátek konec ; ……

Z tohoto kódu můžete vidět, že klient může odeslat jak běžnou zprávu na server, tak požadavek na obdržení mapy, například: Moskva, Tverskaja, 6.

K tomu potřebuji určit, kde je běžná zpráva a kde přesně je požadavek na přijetí karty, aby jej server mohl následně zpracovat. V tomto případě přidávám do zpráv klienta hned na začátku následující identifikátory:

  • #zpráva#
  • #dotaz#

Pokud je na začátku klientské zprávy přítomen identifikátor #message#, server jej rozpozná jako běžnou zprávu od klienta. Pokud je na začátku zprávy přítomen identifikátor #query#, znamená to, že klient odeslal požadavek na přijetí karty.

Klient se také může kdykoli odpojit od serveru, musíme to také sledovat, abychom jej odstranili z obecného seznamu klientů připojených k serveru. Chcete-li to provést, vyberte komponentu TServerSocket a zapište následující kód do události OnClientDisconnect:

procedura TFormServer. ServerClientDisconnect (Sender: TObject; Socket: TCustomWinSocket) ; var i: integer ; začít zkoušet //sledování odpojení klienta RichEditLog. SelAttributes. Barva:=clRed; RichEditLog. SelAttributes. Styl: = [fsBold]; for i : = 0 na server. Zásuvka. ActiveConnections - 1 začněte, pokud Server. Zásuvka. Připojení[i]. Handle = Server. Zásuvka. Připojení[i]. Handle pak začněte RichEditLog. Čáry. Add ("[" + TimeToStr (Time ) + "] Klient odpojen: " + Socket. RemoteHost ) ; CheckListClient. Položky. Smazat (i); RichEditLog. Provést (WM_VSCROLL, SB_BOTTOM, 0) ; konec ;

konec ;

Začínající programátoři (a já sám, když jsem se začal učit Delphi) si kladu otázku: jak mohu přenést soubor přes sockety, když se kromě tohoto souboru přes socket přenáší i spousta informací!? Zdá se, že problém není tak složitý, ale stále není snadný... Po dlouhém hledání na internetu jsem stále nenašel jediný užitečný článek na toto téma. Rozhodl jsem se tedy tento nedostatek napravit a v tomto článku se pokusím pomoci tento problém vyřešit...

Pojďme napsat program, který umí přenášet soubory přes sockety (klient a server) a navíc další příkazy, například nějakou zprávu! Klient obdrží soubory nebo příkazy a server je odešle. Pokud klient vše zapíše do bufferu, tak kromě souboru bude obsahovat i příkazy a musíme dbát na to, aby se soubory a příkazy za žádných okolností neslučovaly! Musíte také vzít v úvahu, že pokud je soubor velký, bude při přenosu rozřezán na několik paketů, to znamená, že soubor nebude odeslán v jednom paketu, ale v několika a bude volána událost OnClientRead několikrát... To je hlavní problém převodu!

Abychom mohli oddělit příkazy ze souboru, nejprve klientovi pošleme něco jako tento řádek: „soubor#soubor.txt#16“, tedy: příkaz + oddělovač + název souboru + oddělovač + velikost souboru.
Při přijetí tohoto příkazu se klient přepne do režimu příjmu souboru a vše zapíše do vyrovnávací paměti, dokud se velikost souboru nerovná velikosti přijímaných dat. Tímto způsobem klient oddělí příkazy ze souboru!

Začněme tedy psát kód:
Začněme serverem (odešle soubor):

Na formulář umístěte následující komponenty: TServerSocket, TButton, TEdit, TProgressBar a TStatiusBar. Umístěte je tak, jak je znázorněno na obrázku.
Nastavte komponentu TServerSocket na port: 1001.
Nastavte komponentu TStatusBar a proměnnou SimplePanel na hodnotu true.
Do řádku se zadává název přenášeného souboru, k přenosu souboru slouží tlačítko TButton.

Nejprve přidejte vyrovnávací paměť pro soubor do globálních proměnných:

Var Form1: TForm1; MS: TMemoryStream; // Vyrovnávací paměť pro soubor

Nyní se ujistěte, že se při vytváření formuláře otevře soket:

Procedure TForm1.FormCreate(Sender: TObject); begin ServerSocket1.Open; // Otevřete konec soketu;

Když se aplikace ukončí, nezapomeňte zavřít soket:

Procedure TForm1.FormDestroy(Sender: TObject); begin ServerSocket1.Close; // Zavřete konec soketu;

Když kliknete na tlačítko, odešleme soubor:

Procedure TForm1.Button1Click(Sender: TObject); // Přeneste soubor var Size: integer; P: ^Byte; begin MS:= TMemoryStream.Create; // Vytvoří vyrovnávací paměť pro soubor MS.LoadFromFile(Edit1.Text); // Načtení souboru do vyrovnávací paměti // Odeslání informací o souboru (příkaz # název # velikost) ServerSocket1.Socket.Connections.SendText("file#"+Edit1.Text+"#"+IntToStr(MS.Size)+" #"); MS.Poloha:= 0; // Přesune vozík na začátek souboru P:= MS.Memory; // Načtení velikosti souboru do proměnné "P":= ServerSocket1.Socket.Connections.SendBuf(P^, MS.Size); // Odeslání souboru // Zobrazení průběhu ProgressBar1.Position:= Size*100 div MS.Size; StatusBar1.SimpleText:= "Odesláno "+IntToStr(Size)+" z "+IntToStr(MS.Size)+" bajtů"; konec;

V události OnClientRead komponenty TServerSocket zadejte následující kód:

Procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket); begin if Socket.ReceiveText = "end" then // Pokud klient soubor obdržel, pak... begin StatusBar1.SimpleText:= "Klient obdržel soubor"; MS.Free; // Zabijte konec vyrovnávací paměti; konec;

To je nezbytné, aby server ukončil vyrovnávací paměť až poté, co klient soubor přijme. Pokud zabijete buffer ihned po přenosu souboru, klient nestihne obdržet celý soubor! Jakmile klient soubor přijme, odešle serveru příkaz "end", což znamená, že soubor byl přijat a server zruší vyrovnávací paměť.

Nyní necháme náš server zobrazit některé informace o připojení:
V události OnClientConnect komponenty TServerSocket zadejte následující kód:

Procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin StatusBar1.SimpleText:= "Připojení navázáno"; konec;

A na události OnClientDisconnect zadejte:

Procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin StatusBar1.SimpleText:= "Spojení nenavázáno"; konec;

Nyní je server připraven! Nyní přejdeme ke klientovi (přijímá soubor), bude s ním další povyk:

Umístěte komponenty na fórum: TClientSocket, dva TLabely, TProgressBar a TStatusBar.
Nastavte komponentu TClientSocket na port: 1001 (jako server) a proměnnou adresy: 127.0.0.1 (vaše IP).
Nezapomeňte nastavit komponentu TStatusBar a proměnnou SimplePanel na true, aby byl náš text vidět.
V jednom TLabel je zobrazen název souboru, v jiném velikost souboru.
Měli byste skončit s něčím podobným:

Deklarujeme proměnné a jednu proceduru. Zapište proměnné přesně soukromé, jinak nebude fungovat nic:

Postup Zápis(Text: řetězec); // Postup pro zápis dat do bufferu private ( Private deklarace ) Name: string; // Název souboru Velikost: integer; // Velikost souboru Receive: boolean; // Režim MS klienta: TMemoryStream; // Vyrovnávací paměť pro soubor

Při události vytvoření formuláře se připojíme k serveru a čekáme na přenos souboru:

Procedure TForm1.FormCreate(Sender: TObject); begin ClientSocket1.Open; // Otevření soketu Receive:= false; // Klientský režim - příjem příkazů end;

Po ukončení aplikace zavřete soket:

Procedure TForm1.FormDestroy(Sender: TObject); begin ClientSocket1.Close; // Zavřete konec soketu;

Stejně jako u serveru zajistíme, aby klient poskytoval informace o připojení:

Procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); begin StatusBar1.SimpleText:= "Připojení navázáno"; konec; procedure TForm1.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket); begin StatusBar1.SimpleText:= "Spojení nenavázáno"; konec;

Nyní musíme zadat kód do procedury Psaní. Tento postup je nutný pro zápis přijatých dat do souboru. Kód postupu:

Procedure TForm1.Writing(Text: string); začít, pokud MS.Size< Size then // Если принято байт меньше размера файла, то... MS.Write(Text, Length(Text)); // Записываем в буфер // Выводим прогресс закачки файла ProgressBar1.Position:= MS.Size*100 div Size; StatusBar1.SimpleText:= "Принято "+IntToStr(MS.Size)+" из "+IntToStr(Size); if MS.Size = Size then // Если файл принят, то... begin Receive:= false; // Переводим клиента в нормальный режим MS.Position:= 0; // Переводим каретку в начало буфера MS.SaveToFile(Name); // Сохраняем файл ClientSocket1.Socket.SendText("end"); // Посылаем команду "end", то есть файл принят MS.Free; // Убиваем буфер StatusBar1.SimpleText:= "Файл принят"; end; end;

Nyní v události OnClientRead komponenty TClientSocket zadejte následující kód:

Procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var Rtext: řetězec; // Přijatý text begin Rtext:= Socket.ReceiveText; if Receive then // Pokud je klient v režimu příjmu souborů, pak... Writing(RText) // Zapisovat data do vyrovnávací paměti else // Pokud klient není v režimu příjmu souborů, pak... begin if Copy( Rtext, 0, Pos ("#", Rtext) -1) = "soubor" then // Pokud se jedná o soubor, pak... begin MS:= TMemoryStream.Create; // Vytvoří vyrovnávací paměť pro soubor Delete(Rtext, 1, Pos("#", Rtext)); // Určení názvu souboru Name:= Copy(Rtext, 0, Pos("#", Rtext) -1); // Určení názvu souboru Delete(Rtext, 1, Pos("#", Rtext)); // Určení velikosti souboru Size:= StrToInt(Copy(Rtext, 0, Pos("#", Rtext) -1)); // Určení velikosti souboru Delete(Rtext, 1, Pos("#", Rtext)); // Odstraňte poslední oddělovač Label1.Caption:= "Velikost souboru: "+IntToStr(Size)+" bytes"; // Zobrazení velikosti souboru Label2.Caption:= "Název souboru: "+Název; // Tisk názvu souboru Receive:= true; // Přepněte server do režimu příjmu souborů Writing(RText); // Zápis dat na konec vyrovnávací paměti; konec; konec;

Pokud je tedy soubor velký a událost OnClientRead nebude volána jednou, ale několikrát, pak pokud je klient v režimu příjmu souborů, zapíše data do vyrovnávací paměti, ale pokud ne, pak klient určí přijatý příkaz, a pokud se jedná o soubor, pak se přepne do režimu příjmu souboru. Pokud něčemu nerozumíte, tak si přečtěte kód programu, ne nadarmo jsem tam vše odkomentoval :-)

Dobře, teď je po všem...
Klient a server jsou připraveni! Nejprve spusťte server a poté klienta a zkuste přenést soubory o velikosti několika megabajtů :-) Bez problémů jsem po síti posílal soubory o velikosti 10-12 MB.

Bavte se svým programováním!

Úvod

Tento článek je věnován vytváření aplikací architektury klient/server v Borland Delphi založených na soketech („sockety“). A tento článek jsem napsal z nějakého důvodu, ale protože Nedávno Tato otázka se stala předmětem zájmu mnoha lidí. Prozatím se dotkneme pouze vytvoření klientské části aplikace socket.
Se zásuvkami jsem se poprvé seznámil, pokud se nepletu, před rokem nebo rokem a půl. Poté bylo úkolem vyvinout aplikační protokol, který by přenesl požadavek na serverový stroj (běžící na OS Unix/Linux) a přijal odpověď přes soketový kanál. Je třeba poznamenat, že na rozdíl od jiných protokolů (FTP, POP, SMTP, HTTP atd.) jsou základem těchto protokolů sockety. Pomocí soketů si tedy můžete sami vytvořit (simulovat) FTP, POP a jakýkoli jiný protokol, a ne nutně již vytvořený, ale dokonce i svůj vlastní!

Začněme tedy teorií. Pokud jste přesvědčený praktik (a nevidíte žádné algoritmy očima), měli byste tuto část přeskočit.

Algoritmus pro práci se socketovými protokoly

Co nám tedy zásuvky umožňují?... Ano, cokoliv! A to je jedna z hlavních výhod tohoto způsobu výměny dat v síti. Faktem je, že při práci se socketem jednoduše odešlete sekvenci znaků do jiného počítače. Takže s touto metodou můžete posílat jak jednoduché zprávy, tak celé soubory! Navíc nemusíte kontrolovat správnost přenosu (jako tomu bylo při práci s COM porty)!
Níže je ukázkové schéma práce se sockety v aplikacích Delphi:

Definování vlastností hostitele a portu >>> Spuštění soketu (ClientSocket1.Open) >>> Autorizace >>> Odesílání/příjem dat >>> Uzavření soketu

Podívejme se na diagram podrobněji:
Definování vlastností Host a Port - pro úspěšné navázání připojení je třeba přiřadit požadované hodnoty vlastnostem Host a Port komponenty TClientSocket. Host je název hostitele (například: nitro.borland.com) nebo adresa IP (například: 192.168.0.88) počítače, ke kterému se chcete připojit. Port – číslo portu (od 1 do 65535) pro navázání spojení. Čísla portů se obvykle berou od 1001 - protože čísla menší než 1000 mohou být obsazena systémovými službami (například POP - 110). Další podrobnosti o praktické části viz níže;
Otevření soketu - po přiřazení příslušných hodnot vlastnostem Host a Port můžete přejít přímo k otevření soketu (za soket je zde považována fronta, která obsahuje znaky přenášené z jednoho počítače na druhý). Chcete-li to provést, můžete zavolat metodu Open komponenty TClientSocket nebo nastavit vlastnost Active na hodnotu True. Zde je užitečné nainstalovat obslužnou rutinu výjimky pro případ, že se připojení nezdaří. Více si o tom můžete přečíst níže, v praktické části;
Autorizace - tuto položku lze přeskočit, pokud server nevyžaduje zadání přihlašovacích údajů a/nebo hesel. V této fázi zašlete serveru své přihlašovací jméno (uživatelské jméno) a heslo. Mechanismus autorizace však závisí na konkrétním serveru;
Odesílání/příjem dat je ve skutečnosti to, pro co bylo soketové spojení otevřeno. Komunikační protokol také závisí na serveru;
Zavření soketu - po dokončení všech operací je nutné zavřít soket pomocí metody Close komponenty TClientSocket (nebo nastavit vlastnost Active na False).

Popis vlastností a metod komponenty TClientSocket

Zde se seznámíme s hlavními vlastnostmi, metodami a událostmi komponenty TClientSocket.

Vlastnosti
Aktivní - zobrazuje, zda je zásuvka otevřená nebo ne. Typ: Boolean. V souladu s tím je True otevřeno a False je uzavřeno. Tato vlastnost je zapisovatelná;
Host – řetězec (Typ: string) označující název hostitele počítače, ke kterému se chcete připojit;
Adresa – řetězec (Typ: řetězec) označující IP adresu počítače, ke kterému se chcete připojit. Na rozdíl od Host může obsahovat pouze IP. Rozdíl je v tom, že pokud v Hostitel zadáte symbolický název počítače, bude IP adresa odpovídající tomuto názvu požadována od DNS;
Port – číslo portu (Typ: Integer (Word)), ke kterému se chcete připojit. Platné hodnoty jsou od 1 do 65535;
Služba – řetězec (Typ: řetězec) definující službu (ftp, http, pop, atd.), na který port bude spojení navázáno. Jedná se o jakýsi adresář čísel portů odpovídajících různým standardním protokolům;
ClientType - typ připojení. ctNonBlocking - asynchronní přenos dat, tzn. Můžete odesílat a přijímat data přes soket současně pomocí OnRead a OnWrite. ctBlocking - synchronní přenos dat. Události OnRead a OnWrite nefungují. Tento typ připojení je užitečný pro organizování výměny dat pomocí proudů (to znamená práci se soketem jako souborem);

Metody
Open - otevření soketu (podobně jako přiřazení hodnoty True vlastnosti Active);
Close - uzavření soketu (podobně jako přiřazení hodnoty False vlastnosti Active);

Zde jsou všechny metody komponenty TClientSocket vyčerpány. A ptáte se: „Jak pracovat se socketem, jak potom odesílat data? O tom se dozvíte o něco dále.

Praxe a příklady

Nejjednodušší (a nejužitečnější) způsob, jak se naučit jakoukoli metodu programování, je její procvičování. Níže jsou proto uvedeny příklady s několika komentáři:

Příklad 1. Nejjednodušší soketový program

(Do formuláře musíte umístit tlačítko TButton a dva TEdits. Když na tlačítko kliknete, zavolá se obsluha události OnClick - Button1Click. Předtím musíte zadat název hostitele do prvního z TEditů a přístav ve druhém vzdálený počítač. NEZAPOMEŇTE VLOŽIT KOMPONENTU TClientSocket DO FORMULÁŘE !}


začít
(Přiřaďte vlastnostem Host a Port požadované hodnoty)
ClientSocket1.Host:= Edit1.Text;
ClientSocket1.Port:= StrToInt(Edit2.Text);
(Snažíme se otevřít zásuvku a navázat spojení)
ClientSocket1.Open;
konec;


začít
(Jakmile dojde ke spojení, zavřete zásuvku a přerušte spojení)
ClientSocket1.Close;
konec;

Pokud si myslíte, že tento ukázkový program je zcela zbytečný a nemůže přinést žádný užitek, pak se hluboce mýlíte. Daný kód je nejjednodušší příklad skener portů (PortScanner). Podstatou takové utility je kontrola, zda je zadaný port povolen a zda je připraven přijímat/vysílat data. Na tomto principu je založen PortScanner z programu NetTools Pro.

Příklad 2. Odesílání/příjem textových zpráv přes zásuvky

(Do formuláře musíte umístit dva TButtony a tři TEdits. Když kliknete na první tlačítko, zavolá se obsluha události OnClick - Button1Click. Předtím musíte zadat název hostitele do prvního z TEditů a port vzdáleného počítače ve druhém Po navázání spojení můžete odeslat textové zprávy zadáním textu do třetího TEdit a kliknutím na druhé TButton. Chcete-li se odpojit, musíte znovu stisknout první TButton. Dále musíme přidat TListBox, do kterého budeme umisťovat přijaté a odeslané zprávy. NEZAPOMEŇTE VLOŽIT KOMPONENTU TClientSocket DO FORMULÁŘE !}

procedure Button1Click(Sender: TObject);
začít
(Pokud již bylo spojení navázáno, přerušte jej.)
pokud ClientSocket1.Active, pak začněte
ClientSocket1.Close;
Výstup; (...a opustit obsluhu)
konec;
(Přiřaďte vlastnostem Host a Port požadované hodnoty)
ClientSocket1.Host:= Edit1.Text;
ClientSocket1.Port:= StrToInt(Edit2.Text);
(Snažíme se otevřít zásuvku a navázat spojení)
ClientSocket1.Open;
konec;


začít
(Jakmile dojde ke spojení, pošleme pozdrav)
Socket.SendText(′Ahoj!′);
ListBox1.Items.Add(′< Hello!′);
konec;

procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
začít
(Pokud přišla zpráva, přidejte ji do ListBoxu)
ListBox1.Items.Add(′> ′+Socket.ReceiveText);
konec;

procedure Button2Click(Sender: TObject);
začít
(Tlačítko stisknuto - odeslat text ze třetího TEditu)
ClientSocket1.Socket.SendText(Edit3.Text);
ListBox1.Items.Add(′< ′+Edit3.Text);
konec;

POZNÁMKA: V některých případech (v závislosti na serveru) je nutné odeslat řádek po každé zprávě:
ClientSocket1.Socket.SendText(Edit3.Text+#10);

Práce se soketovým proudem

"Jak jinak můžete pracovat se zásuvkou?" Výše uvedená metoda samozřejmě není nejlepším řešením. Existuje spousta metod pro organizaci práce se zásuvkami. Dám ještě jeden dodatečný - práci přes stream. Mnoho z vás už jistě má zkušenosti s prací, když ne se streamy, tak určitě se soubory. Pro ty, kteří nevědí, stream je kanál pro výměnu dat, práce s ním je podobná práci s běžným souborem. Následující příklad ukazuje, jak uspořádat vlákno pro práci se socketem:

Příklad 3. Závit pro práci s paticí

procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
var c: Char;
MySocket: TWinSocketStream;
začít
(Jakmile dojde ke spojení, vytvoříme vlákno a přiřadíme ho k soketu (60000 - časový limit v ms))
MySocket:= TWinSocketStream.Create(Socket,60000);
(Operátor WaitForData čeká na data ze streamu po zadanou dobu v ms (v tomto příkladu 100) a vrátí True, pokud byl přijat alespoň jeden bajt dat, False, pokud ze streamu nejsou žádná data.)
zatímco ne MySocket.WaitForData(100).
Application.ProcessMessages;
(Application.ProcessMessages umožňuje systému Windows překreslit potřebné prvky okna a dává čas dalším programům. Pokud by toto prohlášení nebylo přítomno a data nepřicházela poměrně dlouho, systém by mírně zamrzl.)
MySocket.Read(c,1);
(Operátor čtení přečte zadaný počet bajtů z proudu (v tomto příkladu 1) do zadané proměnné určitý typ(v příkladu - do proměnné c typu Char). Vezměte prosím na vědomí, že Read, na rozdíl od ReadBuffer, nestanovuje striktní limity na množství přijímaných informací. Tito. Čtení čte maximálně n bajtů z proudu (kde n je zadané číslo). Tato funkce vrací počet bajtů přijatých dat.)
MySocket.Write(c,1);
(Příkaz Write je podobný příkazu Read, kromě toho, že Write zapisuje data do proudu.)
MySocket.Free;
(Nezapomeňte uvolnit paměť přidělenou vláknu)
konec;

POZNÁMKA: Chcete-li použít stream, nezapomeňte nastavit vlastnost ClientType na ctBlocking.

Odesílání/příjem komplexních dat

Někdy je potřeba po síti posílat nejen jednoduché textové zprávy, ale i složité struktury (typ záznamu v Pascalu), případně i soubory. A pak je potřeba použít speciální operátory. Některé z nich jsou uvedeny níže:

Metody TClientSocket.Socket (TCustomWinSocket, TClientWinSocket):
SendBuf(var Buf; Count: Integer) - Odeslání vyrovnávací paměti přes soket. Vyrovnávací paměť může být libovolného typu, ať už jde o strukturu (záznam) nebo jednoduché celé číslo. Vyrovnávací paměť je indikována parametrem Buf, druhým parametrem musíte zadat velikost přenášených dat v bytech (Count);
SendText(const S: string) – Odešle textový řetězec přes soket. Tato metoda byla diskutována v příkladu 2 (viz výše);
SendStream(AStream: TSream) – Odešle obsah zadaného streamu přes soket. Přeposílaný stream musí být otevřený. Stream může být libovolného typu – soubor, z RAM atd. Popis práce přímo s vlákny je nad rámec tohoto článku;
Všechny uvedené metody odpovídají Receive... Jejich popis lze nalézt v souboru nápovědy Delphi (VCL help).

Nakonec bych rád uvedl jednoduchý příklad, jak můžete implementovat autorizaci (přihlášení na server). V tomto příkladu je heslo odesláno jako prostý text, takže pokud chcete skutečně bezpečný přihlašovací mechanismus, budete muset provést nějaké změny ve zdrojovém kódu tohoto příkladu. Příklad je implementován jako práce se soketovým proudem.

(V tomto příkladu musíte do formuláře přidat další dva TEdits - Edit3 a Edit4 pro zadání vašeho přihlašovacího jména a hesla)

procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
var c: Char;
MySocket: TWinSocketStream;
login,heslo: string;
začít
MySocket:= TWinSocketStream.Create(Socket,60000);
(K přihlašovacímu jménu a heslu přidáme znak nového řádku, aby server mohl přihlašovací jméno a heslo oddělit.)
login:= Edit3.Text+#10;
heslo:= Edit4.Text+#10;
MySocket.Write(login,Length(Edit3.Text)+1);
MySocket.Write(heslo,Length(Edit4.Text)+1);
zatímco ne MySocket.WaitForData(100).
Application.ProcessMessages;
MySocket.Read(c,1);
(Zde nám server pošle jeden bajt, jehož hodnota 1 odpovídá potvrzení úspěšné autorizace a 0 - chyba (toto je jen příklad). Dále provedeme potřebné akce (příjem/odeslání dat) a zavřeme proud.)
MySocket.Free;
konec