LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Free Pascal (4) - Sockety (dokončení)

Minule jsme si ukázali server komunikující s klienty v rámci jednoho unixového stroje, dnes si tedy ukážeme odpovidající klientský program a také se koukneme na to, jak tuto ukázku upravit, aby používala TCP/IP.

5.5.2004 08:00 | Aleš Hakl | Články autora | přečteno 9843×

Náš klient bude ještě jednodušší než server. Jednoduše se připojí k serveru a pak střídavě čte řádky ze standardního vstupu a socketu a vypisuje je do socketu respektive na standardní výstup. Pokud se na standardním vstupu objeví prázdný řádek, klient spojení uzavře a skončí.

Stejně jako v případě serveru začínáme vytvořením socketu:

s:=socket(AF_UNIX,SOCK_STREAM,PF_UNIX);
if s=-1 then begin
  halt(1);
end;

Voláme naprosto stejnou funkci socket(2), která naprosto stejně buďto vrací deskriptor socketu nebo -1 v případě chyby.

Nyní vytvoříme spojení:

if not connect(s,fileName,sin,sout) then halt(2);

Funkce connect(2) vytvoří proudové spojení k jinému programu resp. počítači (kdo by to byl řekl, že? ^_~). Opět voláme formu specifickou pro Free Pascal, jenž přijímá jako adresu rovnou cestu ve filesystému a v posledních dvou parametrech vrací pascalské "soubory" pro náš socket.

Dále se "soubory" sin a sout naprosto běžně pracujeme a nakonec je zavřeme funkcí close.

Ukažme si, jak může vypadat použití naší jednoduché ukázky použití socketů:

$ ./unix-server &
[1] 21522
$ ./unix-client
Server: prichozi spojeni od:
Mnauu
foobar
raboof
quux
xuuq

$ ps
  PID TTY       TIME CMD
21110 pts/6 00:00:00 bash
21522 pts/6 00:00:00 unix-server
21524 pts/6 00:00:00 unix-server <defunct>
21550 pts/6 00:00:00 ps
$ killall unix-server
[1]+ Terminated ./unix-server
$

Nejprve jsem pomocí shellového operátoru &, který způsobí start procesu na pozadí, spustil server. Dále jsem spustil klienta, ten se připojil k serveru a vypsal první řádek,který od něho přišel (Mnauu). Poté jsem zadal dvě řádky (foobar a quux) a od serveru přišly odpovídající odpovědi, které klient vypsal (raboof a xuuq). Všimněte si ve výstupu příkazu ps procesu s číslem 21524, jedná se o proces zombie, o němž jsme mluvili ve druhém dílu. Vzniká tak, že proces, který obsluhoval klienta, sice skončil, ale jeho rodičovský proces(21522) si nevyzvedl jeho návratovou hodnotu.


Protokol TCP/IP se po stránce obsluhy socketů příliš neliší od Unix Domain Sockets, jediným rozdílem je, že musíme řešit převod adres a čísel portů do tzv. síťového pořadí bytů (tj. big-endian, zatímco procesory x86 používají little-endian). Také je nanejvýše vhodné umožnit uživateli zadávat adresy jako jména počítačů a nikoli jejich číselné adresy. Oba tyto problémy řeší jednotka inet.

Tato jednotka obaluje většinu funkcí specifických pro sockety v doméně AF_INET. Tedy funkce pro převod jmen počítačů na adresy a naopak, funkce pro převod názvů služeb na čísla portů a naopak a také funkce pro převod pořadí bytů mezi tzv. hostitelským(tj. takovým, které používá cílová platforma) a výše zmíněným síťovým pořadím.

O TCP/IP a socketech v doméně INET by se dalo teoretizovat jistě ještě dlouho, ale vrhněme se na vlastní přepis pro použití TCP/IP. Provedl jsem několik úprav předchozího příkladu. Forma patche nám umožní si jednoduše ukázat změny oproti variantě s Unix Domain Sockets.

Změny proběhly logicky v obou částech našeho programu. Pro komunikaci nejdůležitější části kódu jsou ovšem víceméně duplikovány jak v serverové tak klientské části. Protože klient je jednodušší, začnu popis úprav tam:

s:=socket(AF_UNIX,SOCK_STREAM,PF_UNIX);
if paramcount<>1 then begin
  writeln('Usage: ',paramstr(0),' <address>');
  halt(4)
end;
s:=socket(AF_INET,SOCK_STREAM,0);

Na začátku programu si pro jistotu zkontrolujeme, jestli uživatel zadal právě jeden parametr a případně uživatele poučíme, že chceme jeden parametr. Poté vytvoříme socket v doméně AF_INET, což není nic jiného než IPv4, konkrétně v případě SOCK_STREAM protokol TCP.

Nyní ještě musíme zpracovar vstup od uživatele, tj. převést jméno počítače na jeho číselnou adresu. A poté vytvoříme spojení.

if not connect(s,fileName,sin,sout) then halt(2);
host.NameLookup(paramstr(1));
addr.family:=AF_INET;
addr.port:=ShortHostToNet(port);
addr.addr:=HostToNet(LongInt(host.IPAddress));
host.done;
if not connect(s,addr,sin,sout) then halt(2);

V jednotce inet je definováno několik objektů, jež obalují funkce pro převod jmen na adresy a naopak, čísel portů na názvy služeb a podobně. Zde právě vytváříme voláním konstruktoru NameLookup instanci objektu (úmyslně neříkám třídy, jedná se totiž o datový typ object) THost tak, že zadáme jméno počítače, který nás zajímá. Samozdřejmě je možno použít i IP adresu. Dále vyplníme strukturu TInetSockAddr, což je stejná struktura jako sockaddr_in v C. Zadáme tedy adresní doménu (AF_INET) a adresu a port protější strany v síťovém pořadí bytů. Poté tuto instanci opět zrušíme destruktorem done. A dále opět použití pro Free Pascal specifické varianty funkce connect(2), tentokráte pro datový typ TInetSockAddr.

A další kód klienta je naprosto identický jako v předchozí variantě, myslím, že na tom je krásně vidět o čem sockety vlastně jsou: ve skutečnosti jsme změnili dvě volání funkcí a máme fungující TCP klient. Zbytek úprav je zejména pro pohodlí uživatelů (převod jmen na adresy) a lepší přenositelnost našeho programu(převod na síťové pořadí bytů, to by totiž bylo možné implementovat aritmetickými operacemi a nebo dokonce ponechat na uživateli).

V serverové části již nebudu popisovat všechny úpravy, pouze se zaměřím na některé zajímavé:

function getName(addr :longint ):string;
var
  h : THost;
  a : longint;
begin
  a:=NetToHost(addr);
  h.AddressLookup(THostAddr(a));
  getName:=h.Name;
  h.done;
end;

Tato funkce slouží k převodu IP adresy příchozího spojení na jméno připojujícího se počítače. Jedná se vlastně o inverzi toho, co s instancí objektu THost děláme v klientské části.

addr.addr:=0;
if not bind(s,addr,sizeof(addr)) then halt(1);

Zde vyplňjeme položku addr naší vlastní IP adresou na, které chceme naslouchat klientům, speciální hodnota 0.0.0.0 (0 bez oddělení jednotlivých byte, vcelku nezávisle na jejich pořadí ^_~) znamená, že chceme použít všechny adresy rozhraní daného počítače.

Ostatní úpravy jsou většinou pouze o záměnách proměnných, a proto nepovažuji za nutné, je nějak dále rozebírat. Po upgradu na fpc 1.0.10 jsem na dvouch počítačích narazil na to, že program používající jednotku inet nešel zkompilovat a dostal jsem chybové hlášení linkeru o neexistenci proměnné h_errno. FPC 1.0.10 nainstalovaný apt-getem na debian unstable to nedělá, ale na gentoo instalované fpc z binárního balíčku to dělá. Není mě jasné co přesně toto chování způsobuje. Jednoduchým (a poněkud diskutabilním) řešením je ve zdrojovém kódu jednotky inet odstranit z definice promšnné GetDNSError část external name 'h_errno';, toto řešení ma ovšem ten důsledek, že poznáme že nastala chyba, nikoli už jaká.. Tím bych i uzavřel téma socketů a pomalu se přesuneme od obalů kolem knihovny jazyka C k programování v Pascalu.

Screenshot

Příště bych rád začal s knihovnou FCL, která ač je zatím neuplná a nedokončená, již nyní obsahuje mnoho zajímavých a užitečných tříd.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

15.5.2017 23:50 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 18. května od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

12.5.2017 16:42 /Honza Javorek
PyCon CZ, česká konference o programovacím jazyce Python, se po dvou úspěšných ročnících v Brně bude letos konat v Praze, a to 8. až 10. června. Na konferenci letos zavítá např. i Armin Ronacher, známý především jako autor frameworku Flask, šablon Jinja2/Twig, a dalších projektů. Těšit se můžete na přednášky o datové analytice, tvorbě webu, testování, tvorbě API, učení a mentorování programování, přednášky o rozvoji komunity, o použití Pythonu ve vědě nebo k ovládání nejrůznějších zařízení (MicroPython). Na vlastní prsty si můžete na workshopech vyzkoušet postavit Pythonem ovládaného robota, naučit se učit šestileté děti programovat, efektivně testovat nebo si v Pythonu pohrát s kartografickým materiálem. Kupujte lístky, dokud jsou.
Přidat komentář

2.5.2017 9:20 /Eva Rázgová
Putovní konference československé Drupal komunity "DrupalCamp Československo" se tentokrát koná 27. 5.2017 na VUT FIT v Brně. Můžete načerpat a vyměnit si zkušenosti z oblasti Drupalu 7 a 8, UX, SEO, managementu týmového vývoje, využití Dockeru pro Drupal a dalších. Vítáni jsou nováčci i experti. Akci pořádají Slovenská Drupal Asociácia a česká Asociace pro Drupal. Registrace na webu .
Přidat komentář

1.5.2017 20:31 /Pavel `Goldenfish' Kysilka
PR: 25.5.2017 proběhne v Praze konference na téma Firemní informační systémy. Hlavními tématy jsou: Informační systémy s vlastní inteligencí, efektivní práce s dokumenty, mobilní přístup k datům nebo využívání cloudu.
Přidat komentář

15.4.2017 15:20 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě IoT a radiokomunikace? Přijď na sraz spolku OpenAlt, který se bude konat ve středu 19. dubna od 18:30 v Šenkovně (Sokolská 60, Praha 2).
Přidat komentář

5.3.2017 19:12 /Redakce Linuxsoft.cz
PR: 23. března proběhne v Praze konferenci na téma Cloud computing v praxi. Hlavními tématy jsou: Nejžhavější trendy v oblasti cloudu a cloudových řešení, Moderní cloudové služby, Infrastruktura současných cloudů, Efektivní využití cloudu, Nástrahy cloudových řešení a jak se jim vyhnout.
Přidat komentář

27.2.2017 22:12 /František Kučera
Pozvánka na 137. sraz OpenAlt – Praha: Tentokrát jsme si pro vás připravili neobvyklou akci. Ve středu 1.3. v 17:30 nás přivítá sdružení CZ.NIC ve svých prostorách v Milešovské ulici číslo 5 na Praze 3, kde si pro nás připravili krátkou prezentaci jejich činnosti. Následně navštívíme jejich datacentrum pod Žižkovskou věží. Provedou nás prostory, které jsou běžnému smrtelníkovi nedostupné!
Po ukončení prohlídky se všchni odebereme do hostince U vodoucha, Jagelonská 21, Praha 3 pochutnat si na některém z vybraných piv či dát si něco na zub. Rezervaci máme od 19:30, heslo je OpenAlt.
Ale pozor! Do prostor datového centra máme omezený přístup, dostane se tam pouze 10 lidí! Takže kdo přijde dříve, ten má přednost, a občanky s sebou! Kdo nebude chtít na prohlídku datového centra, může se pomalu přesunout do hostince U vodoucha a u nepřeberné nabídky piv počkat na ostatní.
Přidat komentář

18.1.2017 0:49 /František Kučera
Členové a příznivci spolku OpenAlt se pravidelně schází v Praze a Brně. Fotky z pražských srazů za uplynulý rok si můžete prohlédnout na stránkách spolku. Příští sraz se koná už 19. ledna – tentokrát je tématem ergonomie ovládání počítače – tzn. klávesnice, myši a další zařízení. Také budete mít příležitost si prohlédnout pražský hackerspace Brmlab.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

1.8.2017 7:32 / Cassidy
structural consultants

30.7.2017 11:12 / Jaromir Obr
Národní znaky

27.7.2017 12:24 / Jaromir Obr
Cteni/zapis

26.7.2017 21:12 / Jaromir Obr
Podminka

15.6.2017 9:34 / Ondřej Havlas
php,

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2017) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze