|
[Grafika] [WebTip] [Fotografování] [Galerie] [MujMac] [Printing] | |||||||||
|
||||||||||
|
Dnes se naučíme vytvářet jednoduchého klienta v operačním systému Linux. 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 ú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 celé číslo int. K vytvoření soketu slouží funkce socket. Funkce je deklarována v hlavičkovém souboru sys/socket.h. Jako parametry budeme funkci předávat makra, která jsou v hlavičkovém souboru sys/types.h. Hlavička funkce:
Než začneme navazovat spojení, seznámíme se se strukturou sockaddr_in. 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. 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:
Jedna z možností jak poslat a přijmout data je použít funkce send a recv, které si popíšeme. Jinak ale můžeme použít identifikátor soketu téměř všude, kde je očekáván identifikátor souboru (file descriptor). Můžeme tedy používat funkce read, write. Také je možné například pomocí fdopen vytvořit strukturu FILE a se soketem pracovat pomocí fprintf. Taková možnost v MS Windows® není. Alespoň tedy mě se to nepovedlo. Odeslání datK odeslání dat slouží funkce send. Funkce send je deklarována v hlavičkovém souboru sys/socket.h. Její hlavička je:
K příjmu dat slouží funkce recv. Funkce recv je deklarována v hlavičkovém souboru sys/socket.h. 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 stejně jako soubor. Použijeme funkci close.
|