|
[Grafika] [WebTip] [Fotografování] [Galerie] [MujMac] [Printing] | |||||||||
|
||||||||||
|
Dnes se naučíme vytvářet jednoduchého klienta v operačním systému MS Windows®. Naučíme se jak vytvářet soket, jak navázat spojení se serverem, jak přijmout a odeslat data. Komunikace pomocí TCP/IP probíhá na principu klient - server. Server je program, který čeká na připojení. Klient je program, který spojení navazuje. Klient se mi zdá jednodušší, proto jím začneme. V minulém díle jsme si velice zjednodušeně vysvětlili co je to soket. Pro ty, kteří nečetli minulý článek věnovaný Linuxu to zopakuji. V úvodním díle jsme si popsali službu TCP. Chceme-li komunikovat se vzdáleným počítačem, je třeba vytvořit soket. V úvodním díle jsem napsal, že soket je obecný nástroj pro komunikaci. Lze jej mimo jiné použít i pro komunikaci po síti pomocí protokolů TCP/IP. Co si ale pod pojmem soket blíže představit? Překlad slova socket je objímka, zásuvka, hrdlo(trubky). Máme za úkol pomocí soketu spojit dva počítače. Představme si (samozřejmě velice obrazně :-), že mezi počítačem u kterého sedíme a vzdáleným počítačem, se kterým chceme komunikovat je natažené potrubí. V každém počítači je jeden konec trubky - hrdlo trubky - anglicky socket. Nejprve musíme vytvořit hrdlo trubky (vytvořit soket - funkce socket). Poté musíme druhý konec nasměrovat správným směrem. Tedy zasunout druhý konec roury do vzdáleného počítače (navázat spojení - funkce connect). Máme-li takto vytvořené potrubí, můžeme do našeho konce potrubí (do soketu) něco vložit (poslat data - funkce send). Ono to na druhém konci potrubí "vypadne". Také může něco vypadnout nám na našem konci potrubí (příjem dat - funkce recv). Až nás přestane práce s potrubím bavit, tak náš konec potrubí zahodíme (uzavřeme spojení - funkce close). Na druhé straně potrubí sice bude k dispozici druhý konec trubky, ale nebude už na nic. Protože z něj už nic nevypadne (my tam nemůžeme nic vložit, když nemáme svůj konec) a pokud do něj něco vhodí druhá strana, tak to nikam nedojde (náš konec už není). Je zřejmé, že když navazujeme spojení (dáváme druhý konec potrubí do vzdáleného počítače), musí být na vzdáleném počítači něco, co potrubí uchopí a připraví svůj konec potrubí pro komunikaci. Tedy vzdálený počítač musí být TCP server. TCP serveru se budeme věnovat příští článek.Tolik pro představu pro lidi, kteří o soketech ještě nikdy neslyšeli. Nyní se podrobněji podívejme na jednotlivé funkce. Vytvoření soketuSoket je reprezentován svým identifikátorem, který je typu SOCKET. První malý rozdíl oproti Linuxu. V Linuxu to bylo celé číslo. Je to ale jen takový formální rozdíl, protože typ SOCKET je definován jako u_int. K vytvoření soketu slouží funkce socket. Hlavička funkce:
Než začneme navazovat spojení, seznámíme se se strukturou sockaddr_in. Opět si můžeme všimnout drobných rozdílů oproti linuxové variantě. Instance této struktury přesně charakterizuje místo, kam chceme naši rouru zasunout. Je v ní jak IP adresa (adresa vzdáleného počítače), tak i číslo portu (adresa aplikace na vzdáleném počítači). Pojmy IP adresa a TCP port jsem vysvětlil v úvodním díle seriálu. Atributy struktury:
Další atributy nás nemusí zajímat. Můžeme se setkat s identifikátorem SOCKADDR_IN. Jedná se o další pojmenování (pomocí typedef) struktury sockaddr_in. Strukturu sockaddr_in budeme přetypovávat na strukturu sockaddr. Struktura sockaddr by se nám vyplňovala špatně. Navázání spojeníMáte tedy vytvořen náš konec "hadice" (pomocí funkce socket). Teď by to chtělo vložit druhý konec hadice do nějakého počítače. K tomu slouží funkce conncet. Její hlavička je:
K odeslání dat slouží funkce send. Její hlavička je:
K příjmu dat slouží funkce recv. Její hlavička je:
Když jsme vytvářeli soket, použili jsme makro SOCK_STREAM
a rozhodli se komunikovat pomocí TCP. Tím jsme hlavně rozhodli o
charakteru spojení. Máme garantováno,
že data budou přijímána v pořadí, ve kterém byla odeslána. Data nebudou
poškozena. Budeme je přijímat jako proud bytů. Jestliže nám druhá strana
pomocí jednoho soketu pošle vícekrát data, nebudeme na naší
straně schopni nijak rozpoznat, kde končí jeden odeslaný blok dat a
začíná druhý. Musíme jej sami rozpoznat řídicích bytů, nebo mít pevně
danou délku jednoho záznamu. V tomto smyslu lze přirovnat práci
se soketem typu SOCK_STREAM jako s binárním souborem (posloupnost bytů nebo proud bytů). Zatím jen pro úplnost poznamenám, že zde mluvíme o tak zvaném blokovacím módu. Funkce recv čeká na data. Tedy zablokuje se běh programu, dokud nějaká data nepřijdou. O neblokovacím módu, jak jej udělat a o věcech s tím souvisejících si povíme něco v budoucnu. Blokovací mód nám bude prozatím stačit. Nyní několik článků budu mluvit o blokovacím módu a nebudu to zdůrazňovat. Uzavření spojeníSoket uzavřeme funkcí closesocket. Musím jen zdůraznit, že jej neuzavřeme funkcí close, jak jsme zvyklí z Unixových systémů. Této chyby se lehce dopustí někdo, kdo je zvyklý používat sokety v Linuxu a přechází na MS Windows ®. Je to taková zákeřnost, protože close očekává jako parametr int, takže nás překladač neupozorní na chybu. Je-li někdo zvyklý z Unixových systémů na close, může být velice překvapen. Překladač nic nenahlásí, spojení se neuzavře, ale programátor při ladění intuitivně očekává, že close spojení uzavře. Například při komunikaci pomocí protokolů HTTP má uzavření spojení velký význam. Ukázkový příklad - TCP klient ve WindowsNyní si vytvoříme jednoduchý příklad. Vytvoříme program, který naváže spojení se serverem, odešle mu textový řetězec a přijme jiný textový řetězec. Poté server spojení ukončí. Parametry programu budou adresa vzdáleného počítače (IP adresa nebo doménové jméno) a číslo portu. V příkladu používám šablonu string. Umožňuje v C++ pohodlnější práci s řetězci než pole znaků. Více informací o šabloně je v článku Řetezce v C++.
Tento příklad je možné si stáhnout jako ukázku. Tím máme hotového Windows klienta. Teď by to pro názornou ukázku chtělo mít k dispozici server, ke kterému se klient bude moci připojit. Server si napíšeme v příštích článcích. Věřím, že je mnoho takových, kteří si chtějí vyzkoušet klienta teď hned. Chtělo by to nějaký server na rychlé vyzkoušení. Proč ale server narychlo psát, když na internetu je jich spousta (například WWW servery). Proto druhý příklad ke stažení je příklad, který stáhne WWW stránku (tento článek) a uloží ji na disk. Používám protokol HTTP, což je textový protokol, který běží nad TCP/IP. WWW servery (pokud není uvedeno jinak) očekávají spojení na portu 80. HTTP protokolem se v seriálu zabývat nebudeme. V příštím článku vytvoříme TCP server v Linuxu. V článku, který bude následovat poté vytvoříme TCP server v MS Windows®. |