Vyšlo v týdeníku Computerworld č. 13/93 v roce 1993
Vytištěno z adresy: http://www.earchiv.cz/a93/a313c110.php3

Transportní rozhraní

V minulých dílech našeho seriálu jsme se podrobněji zabývali síťovou a transportní vrstvou síťového modelu TCP/IP. Dříve, než se budeme věnovat aplikační vrstvě a jednotlivým aplikacím, se musíme ještě zmínit o jedné důležité věci: o vazbě mezi transportní vrstvou a aplikačními programy. Tedy o tom, jaké mechanismy a jaké postupy mohou, resp. musí aplikační programy používat, chtějí-li získat přístup ke službám transportní vrstvy.

Ještě dříve si ale musíme uvědomit jednu významnou skutečnost: implementace nejnižších vrstev určitého síťového modelu je vždy součástí operačního systému počítače, zatímco nejvyšší vrstva (aplikační) již součástí operačního systému není. O přesné hranici, tedy o tom, která vrstva ještě je součástí operačního systému a která již ne, pak rozhoduje především samotný síťový model a jeho představa o tom, jak má být síťový software členěn na vrstvy. V případě síťového modelu TCP/IP je za součást operačního systému považována ještě transportní vrstva, zatímco vrstva aplikační již stojí nad operačním systémem.

To má ale jeden velmi závažný důsledek: přístup ke službám transportní vrstvy TCP/IP zprostředkovává aplikacím operační systém. Způsob, jakým se tak děje - tedy jednotlivé mechanismy a postupy - jsou pak dány konkrétním operačním systémem a jeho celkovou koncepcí. Proto je dobré rozlišit dvě věci: protokoly, používané na úrovni transportní vrstvy, a rozhraní transportní vrstvy směrem k vrstvě aplikační (tzv. transportní rozhraní). Transportní protokoly musí být na všech vzájemně komunikujících počítačích stejné, a proto mohou být v rámci síťového modelu TCP/IP standardizovány. Transportní rozhraní je ale závislé na konkrétním operačním systému, a na různých počítačích tedy může být různé. Proto dost dobře nemůže být v rámci síťového modelu TCP/IP jakkoli standardizováno.

V této souvislosti je vhodné si znovu zdůraznit, že TCP/IP rozhodně není to samé, co Unix. Unix je jeden z mnoha operačních systémů, a TCP/IP je jedna z mnoha soustav protokolů a názorů na to, jak mají vypadat a fungovat počítačové sítě (tedy to, co zde označujeme jako síťový model). Tvůrci operačního systému Unix si síťový model TCP/IP oblíbili natolik, že pro potřeby propojování svých počítačů do sítí již nepoužívají nic jiného. To ale rozhodně neznamená, že by v prostředí Unixu nemohly být implementovány jiné síťové modely resp. architektury. Stejně tak to rozhodně neznamená, že by síťový model TCP/IP nemohl být implementován i v prostředí jiných operačních systémů. Dnes také skutečně existují implementace TCP/IP snad pro každý existující operační systém, od MS DOSu pro počítače PC až po operační systém VM/CMS střediskových počítačů firmy IBM. Je zde však přeci jen určitá odlišnost, která svádí ke ztotožňování TCP/IP s Unixem: implementace protokolů TCP/IP je dnes již považovaná za standardní součást Unixu, tj. je přímou součástí dodávky tohoto operačního systému. V případě ostatních operačních systémů je však pouze jedním z mnoha doplňkových produktů, které si uživatel dokupuje zvlášť (a často si také může vybrat z širší nabídky různých implementací).

Jestliže tedy mohou být protokoly TCP/IP implementovány v prostředí různých operačních systémů, znamená to současně, že v každém z nich budou služby transportní vrstvy přístupné jiným způsobem. To je velmi důležité nejen pro samotné aplikace a jejich tvůrce, a také pro způsob, jakým mohou být v rámci síťového modelu TCP/IP standardizovány nejobvyklejší aplikace typu elektronické pošty, přenosu souborů, vzdálených terminálových relací apod. Standardizovat je možné (a nutné) celkovou koncepci těchto aplikací a konkrétní protokoly, prostřednictvím kterých budou spolupracovat (např. předávat si jednotlivé zprávy v rámci elektronické pošty, celé soubory v rámci aplikací pro přenos souborů atd.). Není ale již možné standardizovat přesný způsob, jakým budou tyto aplikace využívat služeb transportní vrstvy.

Budeme-li si dále popisovat konkrétní řešení transportního rozhraní v prostředí Unixu, je dobré mít na paměti, že jde jen o konkrétní příklady možného řešení.

Jak je to v Unixu

Na vznik Unixu měl významný vliv operační systém Multics, který byl vyvíjen v rámci velkého projektu několika významných institucí (MIT, General Electric a Bell Laboratories) jako operační systém pro práci v režimu sdílení času. Celý projekt v podstatě ztroskotal, protože výsledný operační systém postupným zdokonalováním tak nabubřel a zkomplikoval se, že se stal prakticky nepoužitelným. Spíše negativní zkušenosti některých účastníků tohoto projektu se pak staly jednou z hlavních motivací pro vznik Unixu.

Pro nás je zajímavé to, že operační systém Multics jako první sjednotil způsob práce se vstupně/výstupními zařízení - na všechna tato zařízení se díval jako na zvláštní soubory, a pracoval s nimi stylem "otevři - čti - piš - zavři".

Když pak Bellovy laboratoře (Bell Labs, součást tehdy ještě mamutího AT&T) odstoupily od projektu Multics, vznikl na jejich půdě (v roce 1969) operační systém Unix. Jeho autoři (Ken Thompson a jeho spolupracovník Dennis Ritchie) do něj převzali i jednotný pohled na vstupně/výstupní zařízení z původního Multicsu. Unix se tedy již od svého vzniku snažil dívat se na všechna vstupně/výstupní zařízení jako na speciální soubory, a jako s takovými s nimi také pracoval. Na úrovni operačního systému proto nabízel operace typu: open (otevření souboru), read (čtení z již otevřeného souboru), write (zápis do souboru) a close (uzavření dříve otevřeného souboru, signalizující konec práce s ním), pomocí kterých se pak realizovaly veškeré vstupně/výstupní operace. Speciálním souborem, se kterým se přitom pracovalo, byl ve skutečnosti ovladač příslušného zařízení (který se jako soubor pouze "tvářil").

Tento pohled na vstupně/výstupní zařízení a způsob práce s nimi si Unix v podstatě ponechal dodnes, a pro běžná vstupně/výstupní zařízení (terminály, disky apod.) je toto řešení vcelku postačující.

Když se pak v prostředí Unixu začaly implementovat síťové protokoly TCP/IP, bylo vcelku přirozené, že se nejprve použil stejný mechanismus. Síť byla považována za vstupně/výstupní zařízení, a "tvářila" se jako speciální soubor. Příslušné protokoly pak byly implementovány v rámci ovladače příslušného zařízení, který navenek vystupoval právě jako speciální soubor.

Záhy se ale ukázalo, že způsob práce se sítí je přeci jen komplikovanější a náročnější, než způsob práce se skutečnými vstupně/výstupními zařízeními, a že tudíž vyžaduje jiné, obecnější mechanismy. Ukažme si to na příkladu.

Operace open, kterou se v Unixu otevírá soubor, signalizuje operačnímu systému, že daná úloha (proces) chce pracovat s určitým konkrétním souborem - jeho přesná specifikace musí být při volání operace open zadána. V případě, že je operace open provedena nad speciálním souborem, který implementuje příslušné přenosové protokoly, by analogií k otevření skutečného souboru mělo být navázání spojení na úrovni transportní vrstvy, tak aby následné operace read a write již mohly přenášet "užitečná data", a operace close zase mohla spojení zrušit. To by ovšem také znamenalo zadat v okamžiku navazování spojení (volání operace open), s kým má být spojení navázáno (místo specifikace souboru, který má být otevřen). Problém je ale v tom, že některé aplikace nemusí být v okamžiku navazování spojení vůbec schopny určit, s kým má být navázáno (jde-li například o proces, který plní funkci serveru, a bude teprve čekat na to, až mu nějaký klient zavolá). Místo jedné operace open, zajišťující navazování spojení, by bylo zapotřebí rozlišovat operace dvě: tzv. pasivní otevření, které pouze signalizuje operačnímu systému připravenost k přijetí žádosti (přicházející z druhé strany) o navázání spojení, a tzv. aktivní otevření, které spojení skutečně navazuje. To vše by ale platilo zase jen pro spojované transportní služby, realizované protokolem TCP, zatímco pro nespojované transportní služby protokolu UDP (kde se spojení nenavazuje vůbec) by operace open musela fungovat ještě jiným způsobem.

Specifické požadavky práce se sítí by samozřejmě bylo možné řešit úpravou stávajících operací typu open, read, write a close, šitých na míru práci se soubory - například zavedením dalších parametrů. Co by ale například znamenalo pasivní a aktivní otevření souboru? Musela by se při otevírání skutečného souboru uvádět také IP adresa, která je doopravdy potřebná jen při zřizování transportního spojení? Pokud by jedna a tatáž operace (například open) měla v různých kontextech různé vstupní parametry, zase by se tím ztratila výhoda jednotného pohledu na všechna zařízení jako na soubory.

Zavedení obecnějších mechanismů, které by lépe vyhovovaly potřebám přenosových protokolů a umožnily vytvořit dostatečně pružné transportní rozhraní, se tak brzy stalo nezbytností.

Dvě větve Unixu

V době, kdy potřeba obecnějších mechanismů vyvstala, byl již vývoj operačního systému Unix rozdělen do dvou hlavních větví. Jednou z nich byl tzv. BSD Unix (či Berkeley Unix), vyvíjený ve středisku Berkeley Software Distribution na University of California v Berkeley, zatímco druhou větev představoval Unix, vyvíjený firmou AT&T (a v současné době označovaný jako System V).

Jak jsme si již uvedli ve 42. dílu našeho seriálu, byly protokoly TCP/IP poprvé implementovány právě pro BSD Unix, a to firmou BBN (Bolt, Beranek & Newman) na zakázku od vládní agentury DARPA, která také financovala vývoj protokolů TCP jako takových. Pro BSD Unix pak byl vytvořen nový mechanismus na úrovni operačního systému, který aplikačním programům zprostředkovává přístup ke komunikačním protokolům. Je označován jako socket interface (doslova: rozhraní s objímkami, zásuvkami), a příště se mu budeme věnovat podrobněji.

Do AT&T Unixu se protokoly TCP/IP prosadily až o něco později, a pro jejich začlenění do operačního systému byl použit jiný mechanismus, označovaný jako streams (doslova: proudy, toky). Také o něm si povíme podrobněji.