Báječný svět počítačových sítí
Část XIII: Aplikačně orientované vrstvy
Jedním z významných rozdílů mezi Referenčním modelem ISO/OSI a TCP/IP je i počet "nejvyšších" vrstev. Zatímco referenční model ISO/OSI má samostatnou prezentační a relační vrstvu, v TCP/IP je nenajdeme. Pokud jsou jejich funkce zapotřební, jsou implementovány až v samotné aplikační vrstvě. Tu samozřejmě najdeme jak u RM ISO/OSI, tak i u TCP/IP. Ovšem představa, že do aplikační vrstvy spadají celé aplikace, používané koncovými uživateli, není zcela správná.V našem putování vrstvami Referenčního modelu ISO/OSI, směrem "zdola nahoru", jsme se dostali až k nejvyšším vrstvám, označovaným jako "aplikačně orientované". Jsou to vrstvy, nacházející se nad vrstvou transportní, kterou jsme se zabývali minule. Jak vidíme na dnešním prvním obrázku, počet těchto vrstev se v ISO/OSI a TCP/IP výrazně liší - a to si určitě zaslouží vysvětlení. Takže proč tomu tak je?
Odpověď je taková, že autoři obou architektur přemýšleli o tom, zda a jak často budou aplikace potřebovat určité funkce (prezentační a relační funkce, viz dále). No a autoři RM ISO/OSI dospěli k závěru, že spíše častěji - a tak považovali za správné poskytnout tyto funkce všem aplikacím, právě formou samostatné prezentační a relační vrstvy. Naopak autoři TCP/IP dospěli při svých výchozích úvahách k závěru, že využití těchto funkcí nebude až tak časté, a tak se nevyplatí vnucovat je každému (ve formě samostatných vrstev). A pokud je některá aplikace potřebovat bude, ať si je raději zajistí (implementuje) sama, podle svých vlastní představ, ale hlavně ve vlastní režii.
Právě režie je totiž faktorem, který v uvedených úvahách sehrál významnou roli. Každá vrstva už svou samotnou existencí představuje určitou režii, vynakládanou na to, aby data "prošla" skrze takovouto vrstvu. No a pokud by ve většině případů takováto vrstva vlastně s daty nic nedělala, pak by režie na průchod vrstvou byla úplně zbytečná. Proto autoři TCP/IP raději příslušné vrstvy nezařadili do svého vrstevnatého modelu (když usoudili, že funkce těchto vrstev nebudou příliš často využívány). Naopak autorům RM ISO/OSI vyšlo, že když bude příslušné funkce využívat většina aplikací, režie na existenci samostatných vrstev bude účelně vynaložená.
Abychom různá rozhodnutí autorů RM ISO/OSI a TCP/IP mohli plně docenit, pojďme si nyní naznačit trochu podrobněji, v čem vlastně spočívají prezentační a relační služby.
Relační vrstva a relační služby
Relační vrstva je v ISO/OSI asi nejvíce kritizovanou vrstvou, kvůli tomu, že toho má relativně nejméně na práci. Původní představa autorů zřejmě byla taková, že v této vrstvě budou soustředěny takové funkce, které usnadňují a podporují vzájemnou interakci komunikujících stran (tzv. relace, anglicky: sessions). Například ve smyslu zajištění bezpečnosti takovéto interakce. Nebo ve smyslu podpory transakčního zpracování, kde je důležité, aby se žádná transakce neprovedla "jen tak napůl", ale vždy jen úplně celá (nebo se naopak neprovedlo vůbec nic). Příkladem může být nějaká finanční transakce, spočívající v odepsání určité částky z jednoho účtu, a připsání téže částky na jiný účet. Tady by skutečně nebylo korektní, aby proběhla jen jedna část transakce (odepsání částky z jednoho účtu), ale už se neprovedly ostatní části transakce (připsání na jiný účet).
Již na tomto prvním příkladu je dobře patrné hlavní dilema: mají být takovéto věci, jako je podpora transakcí, řešeny samostatně, na úrovni relační vrstvy, a tudíž pro všechny aplikace stejně? Nebo je vhodnější, aby si je aplikace řešily samy, podle svých vlastních představa? Tady je vhodné si uvědomit, že třeba bankovní aplikace asi budou mít podstatně přísnější požadavky na "kvalitu" zajištění transakcí, než nějaké jednodušší databázové aplikace, kde nehrozí tak velké následky při nekorektním provedení transakce. I v tomto ohledu zřejmě autoři TCP/IP usoudili, že je lepší, když si podporu transakcí udělá každá aplikace sama, podle svého (hlavně podle svých nároků a požadavků), zatímco autoři RM ISO/OSI byli opačného názoru. Současná praxe dává celkem jednoznačně za pravdu autorům TCP/IP.
Původně uvažované úkoly relační vrstvy samozřejmě nekončily u již zmiňované bezpečnosti a transakčního zpracování. Zahrnovaly například podporu vzájemné synchronizace komunikujících stran (ovšem v jiném smyslu, než jak jsme mluvili o synchronizaci na úrovni fyzické vrstvy). Zde jde kupř. o to, že když při nějakém přenosu většího objemu dat mezi dvěma stranami dojde k výpadku spojení, musí se začít úplně odznova: navázat nové spojení a přenášet data od začátku. Relační vrstva však může nabízet výhodnější možnost: vrátit se k určitému "kontrolnímu bodu" a pokračovat od něj a nikoli od začátku. Takovýchto kontrolních bodů může existovat více, a v přerušené relaci pak lze pokračovat od kteréhokoli z nich. Vlastně ne nutně od kteréhokoli, protože to by bylo moc drahé. Jednotlivé kontrolní body jsou totiž jakési body zotavení, v rámci kterých je uschován celý stav právě probíhající relace (včetně dosud přenesených dat). A to představuje dost velkou režii, kvůli které se starší kontrolní body již mohou "uvolňovat" a není možné se k nim vracet. Situaci naznačuje následující obrázek, s vedlejšími a hlavním kontrolním bodem (hlavní je ten kontrolní bod, přes který se již nelze vrátit hlouběji do historie relace, ke starším vedlejším bodům).
Do relační vrstvy by nejspíše patřily i takové služby, jaké dnes v rámci TCP/IP zajišťuje protokol SIP. Ten má podporu relací dokonce ve svém názvu, protože jeho jméno je zkratkou od Session Initiation Protocol (doslova: podpora navazování relací). Je z oblasti internetové telefonie, a službám na bázi VOIP slouží k navazování telefonických hovorů. Řeší zejména takové věci, jako je vyhledání volaného (podle telefonního čísla), tak aby k němu mohlo být navázáno transportní spojení a následně veden hlasový hovor. Příznačné ovšem je, že v rámci TCP/IP jde o aplikační protokol - protože, jak již víme, TCP/IP nemá samostatnou relační vrstvu. A docela dobře se bez ní obejde.
Prezentační služby: hlavně konverze
Zatímco u relační vrstvy není úplně snadné vysvětlit, co by vlastně měla mít na starosti, v případě prezentační vrstvy je to naštěstí snazší. Stačí vyjít z následující úvahy: všechny nižší vrstvy (pod prezentační vrstvou) se snaží přenášet data tak jak "stojí a leží", aniž by se jakkoli změnila. Můžeme si to představit také tak, že přenáší skupiny bitů a snaží se, aby se při přenosu nezměnil ani jeden bit. Jenže to nemusí být vždy správné! Proč?
Třeba proto, že ona data mají určitý význam. Může to být například text, mohou to být čísla, nebo nějaké obecnější datové struktury, od jednoduchých vícerozměrných polí až po struktury provázané pointry. Ovšem na různých platformách mohou být stejné texty, stejná čísla, či stejné datové struktury reprezentovány úplně jinak. Třeba jen u textů může být rozdíl v tom, zda jsou jednotlivé znaky kódovány v kódu ASCII, v kódu EBCDIC, nebo v nějakém úplně jiném kódu (Unicode atd.). Nehledě již na různé národní znakové sady (CP xy atd.). Asi není těžké nahlédnout, že v takovém případě musí být přenášené texty vhodně překódovány (obecně: konvertovány, pomocí vhodné konverze). A právě to má na starosti vrstva prezentační: stará se o to, aby přenášená data měla stejný význam pro obě komunikující strany.
Pro dokreslení celé problematiky konverzí se zmiňme ještě o jednom "ještě základnějším" rozdílu, než jakým je kódování jednotlivých znaků v textech. Jde o pořadí bytů (tzv. byte order), přesněji o způsob umisťování vícebytových položek do paměti. Pro jednoduchost si to představme na dvoubytovém slově (tj. na dvou bytech, tvořící jednu položku). Máme-li nějakou dvoubytovou hodnotu, například 1234H (hexadecimálně), můžeme ji uložit do dvou paměťových míst (každém o velikosti jednoho bytu) dvěma různými způsoby:
- vyšší polovinu bitů (12H) do paměťového místa na vyšší adrese (např. na adrese 1), a nižší polovinu bitů (34H) do paměťového místa na nižší adrese (např. 0), nebo
- vyšší polovinu bitů (12H) vložíme do paměťového místa na nižší adrese (0), a nižší polovinu bitů (34H) do paměťového místa na vyšší adrese (1).
Obě možnosti jsou stejně smysluplné, a žádná z nich není výhodnější než ta druhá. Pro jejich označení se používají termíny, převzaté z angličtiny: Little Endian, resp. Big Endian. Proč, stojí za malou vsuvku, kterou si můžete přečíst v samostatném boxu (… prosím dát vhodný odkaz na následující text, který tvoří tělo boxu). V běžné praxi jsou obě varianty rozloženy víceméně rovnoměrně: například procesory Intel používají konvenci Little Endian, zatímco procesory Motorola konvenci Big Endian. Variantu Big Endian používají také protokoly TCP/IP.
Tlustokoncoví proti tenkokoncovým, aneb: proč říše Lilliput bojuje proti říši BlefuscuO komplikovanějších věcech se lidé obvykle dohodnou relativně snadno. Ale běda, jak přijde na přetřes něco jednoduchého, až přímo banálního. Něco, čemu rozumí každý. Pak se snad vždy najdou lidé, kteří se potřebují vypovídat - a hlavně vehementně prosazovat to či ono stanovisko (lhostejno které). Někdy jakoby platila nepřímá úměra: čím banálnější je celá kauza, tím větší vášně provází volbu jedné z možných variant. V dnešní době Internetu z toho bývají nekonečné flamewars ("psané" slovní přestřelky), které si v ničem nezadají s dřívějšími formami lidských hádek. Lidská tendence k hádavosti, i nad největšími banalitami, je nejspíše tak stará, jak lidstvo samo. Celý tento nešvar již v 18. století hezky zparodoval Jonathan Switft, ve svých známých Gulliverovách cestách. To když popisoval, jak se jeho hlavní hrdina dostal do říše Blefuscu, která byla právě ve válce s říší Liliput ohledně toho, zda se mají vajíčka rozbíjet na tenčím konci, nebo naopak na tlustším konci. V anglickém originále to je "at the little end" (na užším konci), resp. "at the big end" (na tlustším konci). Proto také Switft ve svém díle označil znesvářené strany jako "Little Endians" a "Big Endians" (v českém překladu jako "tenkokoncoví" a "tlustokoncoví"). Původní inspirací Jonathana Swifta přitom byly náboženské spory mezi Anglií a Francií, přesněji mezi anglikánskou církví a katolickou církví ve Francii, a ve svých Gulliverových cestách chtěl upozornit na malichernost jejich podstaty. Na způsob, jakým Swift zasadil svou kritiku malicherných sporů zasadil do svého literárního díla, si v roce 1980 vzpomněl pan Danny Cohen, když psal odborný text pojednávající o problému kolem pořadí bytů. I on chtěl nějak vyřešit vlekoucí se učené disputace ohledně toho, které pořadí bytů je správné (která varianta ukládání vícebitových položek do paměti je vhodnější). A aby zdůraznil malichernost těchto sporů, které jakoby nebraly konce, vypůjčil si Swiftovu terminologii, a poprvé pojmenoval obě varianty jako "Little Endian" a "Big Endian". Celý svůj text pak nazval velmi příznačně: "On Holy Wars and a Plea for Peace" (O svatých válkách a volání po míru). Napsal to tak hezky a od srdce, že se jím navržená terminologie ujala a používá dodnes. Tlustokoncoví však nabyli na dvoře císaře blefuskuánského tolik vážnosti a zde doma jim jejich strana tajně poskytuje tolik soukromé podpory a tak je podněcuje, že obě říše vedou posledních šestatřicet měsíců se střídavým štěstím krvavou válku. Za tu dobu jsme přišli o čtyřicet znamenitých lodí a mnohem více menších plavidel s třiceti tisíci nejlepších námořníků a vojáků. Počítá se, že nepřítel utrpěl o něco větší škodu než my." Jonathan Switft, Gulliverovy cesty: |
Linearizace a ASN.1 místo XML
Pořadí bytů, alias volba mezi Big Endian a Big Endian, je samozřejmě jen jednou drobnou kapkou do celkové mozaiky toho, co zajišťuje prezentační vrstva. Abychom správně docenili její význam a princip fungování, řekněme si ještě o jedné důležité věci: když má prezentační vrstva přenést nějaká konkrétní data "na druhou stranu", musí je nejprve "zlinearizovat". Tedy převést do takového tvaru, aby mohla být přenesena po lineární (jednorozměrné) přenosové cestě. Například u dvourozměrných polí si to lze představit docela snadno: vezmou s postupně jednotlivé sloupce (nebo naopak řádky), které už lineární jsou, a ty se posílají. Viz obrázek č. 4.
V případě vícerozměrných polí je řešení prakticky stejně snadné, byť jen trochu náročnější na představivost. Složitější to ale může být u obecnějších datových struktur. A zdaleka nejsložitější je to pak u datových struktur, provázaných ukazateli (tzv. pointry). Ukazatele totiž nelze přenést vůbec, protože mají pouze "místní význam" u odesilatele. Místo toho je nutné příslušnou datovou strukturu nahradit nějakým ekvivalentem, který již ukazatele (pointry) neobsahuje. To je obvykle možné, ale podtrhuje to význam dalšího úkolu, který musí prezentační vrstva řešit. Tímto úkolem je popsat data, přenášená skrze přenosový kanál, takovým způsobem, aby je příjemce dokázal zase "vrátit do původní podoby". Tedy rekonstruovat je tak, aby pro něj měly stejný význam, jako pro odesilatele.
S určitým zjednodušení si můžeme představit, že prezentační vrstva se tohoto úkolu dokáže zhostit tak, že k přenášeným datům přibalí jakousi "průvodku". Tedy popis toho, co se vlastně přenáší, aby to příjemce dokázal správně "vybalit" a následně "poskládat". Samozřejmě tak musí činit způsobem, který bude předem dohodnutý a známý oběma stranám (jinak by příjemce nerozuměl ani samotné průvodce).
Ve světě ISO/OSI, kde existuje samostatná prezentační vrstva, se za tímto účelem dokonce navrhl samostatný (a tedy vlastně umělý) jazyk, pojmenovaný ASN.1 (Abstrakt Syntax Notation, verze 1). Lze si jej představit jako programovací jazyk, ovšem bez výkonných příkazů, pouze s deklaracemi. Stalo se tak v době, kdy svět ještě neznal jazyk XML, který by se k tomu velmi dobře hodil. Ale je otázkou, zda by jej ve světě spojů použili, i když by býval již existoval. Filosofie autorů Referenčního modelu ISO/OSI totiž byla taková, že všechno museli vymyslet sami. V lepším případě, když už něco šikovného vymyslel někdo jiný, alespoň to potřebovali "posoudit" a vydat jako svůj vlastní standard. Tušili jste, že třeba takový Ethernet, standardizovaný společností IEEE jako standard (řady) IEEE 802.3, existuje i jako standard ISO/OSI, konkrétně ISO 8803?
"Pseudovrstvy" v TCP/IP
Jak jsme si již uvedli výše, samostatná relační a prezentační vrstva je pouze v Referenčním modelu ISO/OSI, ale v TCP/IP nikoli. Zde se předpokládá, že ta aplikace, která relační či prezentační služby potřebuje, si je zajistí sama, ve vlastní režii. O důvodech jsme se také již zmiňovali (jde hlavně o úsporu režie na samostatné vrstvy). Přesto ale i v TCP/IP existuje jakési alternativní řešení, které velmi připomíná rčení o "zlaté střední cestě" mezi dvěma extrémy (existencí samostatných vrstev a jejich úplnou absencí).
Jde o řešení, vzniklé v souvislosti s protokolem NFS (Network File System), který v rámci TCP/IP slouží ke sdílení souborů. Pochází pod firmy Sun Microsystems, a bylo to vlastně úplně první řešení, které vzniklo u komerční firmy (tj. jako její vlastní, tj. "proprietární"), ale pak bylo otevřeno a mohlo se stát otevřeným internetovým standardem. Hlavně ale: i tato aplikace potřebovala zajistit určité relační a prezentační funkce - a tak si je, v duchu koncepce TCP/IP, musela zajistit sama. Ale když už tak udělala, učinila tak způsobem, který je využitelný i jinými aplikacemi, tak aby tyto již nemusely znovu "vynalézat kolo" a znovu si vyvíjet vlastní prezentační a relační funkce.
Autoři NFS totiž navrhli vše tak, že samotný protokol NFS je "čistě aplikační", a má " k ruce" dva další samostatné protokoly, které pro něj zajišťují prezentační a relační funkce. Konkrétně jde o protokoly XDR (eXternal Data Representation), a RPC (Remote Procedure Call). Tyto protokoly jsou koncipovány tak, aby mohly být řešeny jako knihovní moduly, které si ostatní aplikace přilinkují, pokud je chtějí využívat - ale pokud je využívat nechtějí, nenesou režii spojenou s jejich existencí (v podobě samostatné vrstvy).
Celý efekt naznačuje následující obrázek č. 6: vůči těm protokolům, které protokoly XDR a RPC využívají, se tyto chovají obdobně jako samostatné vrstvy. Ovšem ostatní aplikace jimi neprochází, a tím ani nenesou režii, která by s tím byla spojena.
Aplikace: v aplikační vrstvě?
Původní představa autorů Referenčního modelu ISO/OSI možná byla taková, že aplikační vrstva bude sloužit k tomu, aby v ní byly provozovány jednotlivé aplikace. Na první pohled to vypadá velmi logicky, ale přináší to jeden zásadní problém: pokud by tomu tak bylo, pak by i všechny aplikace musely být standardizovány, a tudíž všechny podřízeny stejným pravidlům, které by definovaly nejen jejich činnost, ale i vše co s tím souvisí. Ale to by nebylo dobře. Proč?
I aplikace určitě musí respektovat určité konvence, a musí se jim důsledně přizpůsobovat. Třeba aplikace, které se účastní práce s elektronickou poštou, musí dodržovat formátování jednotlivých zpráv, musí používat stejně koncipované adresy, stejné mechanismy přenosu zpráv atd. Ale proč by současně měly nabízet jednotné (rozuměj: úplně stejné) uživatelské rozhraní? Proč by měly svým uživatelům vnucovat vždy přesně stejný (standardizovaný) repertoár funkcí? V čem by se pak lišily? Nebo jinak, z opačného pohledu: má smysl standardizovat vzhled uživatelského rozhraní, a předepisovat autorům poštovních klientů, jak mají jejich produkty vypadat? Jaká mají používat okénka, jaké barvy, písma, repertoáry funkcí atd.? Určitě ne.
Takže původní představa, o tom že v aplikační vrstvě budou "umístěny" celé aplikace, vzala brzy za své. Místo toho došlo k jakémusi "roztržení" aplikací na dvě části:
- na část, které musí být standardizována, proto aby si rozuměla s dalšími aplikacemi, resp. instancemi stejné aplikace (např. s poštovními servery atd.)
- na část, kterou nemá smysl standardizovat (typicky jde o uživatelské rozhraní aplikace).
Jak také naznačuje následující obrázek č. 7, v aplikační vrstvě nakonec zůstala jen první z obou výše uvedených částí, zatímco ta druhá již byla "vytlačena" nad aplikační vrstvu, a tím i z dosahu standardizace a jakéhokoli "sešňerovávání". Díky tomu si dnes může každý vybrat například takového poštovního klienta, jaký vyhovuje jeho potřebám - s maximálním komfortem nebo naopak jednoduchého, s grafickým uživatelským rozhraním nebo v řádkovém režimu atd.