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 10027×

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ů

14.11.2017 16:56 /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 – tradičně první čtvrtek před třetím pátkem v měsíci: 16. listopadu od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

12.11.2017 11:06 /Redakce Linuxsoft.cz
PR: 4. ročník odborné IT konference na téma Datová centra pro business proběhne již ve čtvrtek 23. listopadu 2017 v konferenčním centru Vavruška, v paláci Charitas, Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00. Konference o návrhu, budování, správě a efektivním využívání datových center nabídne odpovědi na aktuální a často řešené otázky, např Jaké jsou aktuální trendy v oblasti datových center a jak je využít pro vlastní prospěch? Jak zajistit pro firmu či jinou organizaci odpovídající služby datových center? Podle jakých kritérií vybrat dodavatele služeb? Jak volit součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně spravovat datové centrum? Jak eliminovat možná rizika? apod.
Přidat komentář

13.9.2017 8:00 /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 – tentokrát netradičně v pondělí: 18. září od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

3.9.2017 20:45 /Redakce Linuxsoft.cz
PR: Dne 21. září 2017 proběhne v Praze konference "Mobilní řešení pro business". Hlavní tématy konference budou: nejnovější trendy v oblasti mobilních řešení pro firmy, efektivní využití mobilních zařízení, bezpečnostní rizika a řešení pro jejich omezení, správa mobilních zařízení ve firmách a další.
Přidat komentář

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ář

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

> Poslední diskuze

5.12.2017 11:50 / Thomas
kitchen renovations

18.9.2017 14:37 / Rojas
high security vault

15.9.2017 7:33 / Wilson
new zealand childcare jobs

31.8.2017 12:11 / Jaromir Obr
Re: ukůládání dat ze souboru

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

Více ...

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