VyÜlo v t²denφku: | COMPUTERWORLD |
╚φslo: | 15/93 |
RoΦnφk: | 1993 |
Rubrika/kategorie: | Co je Φφm ... v poΦφtaΦov²ch sφtφch |
Dφl: | 62 |
LidΘ, kte°φ dostali za ·kol vyvinout novΘ mechanismy pro zp°φstupn∞nφ protokol∙ TCP/IP v prost°edφ BSD Unixu, si sv∙j p∙vodnφ ·kol pon∞kud rozÜφ°ili: rozhodli se vytvo°it takov² prost°edek, kter² by nebyl "Üit na mφru" jednΘ konkrΘtnφ soustav∞ protokol∙, tj. TCP/IP, ale byl pou₧iteln² obecn∞ pro jakoukoli soustavu protokol∙, a dokonce i pro vφce soustav protokol∙ souΦasn∞. V dob∞, kdy si protokoly TCP/IP v prost°edφ Unixu teprve hledaly svΘ mφsto, to bylo rozhodnutφ vcelku logickΘ. V souΦasnΘ dob∞, kdy TCP/IP protokoly Unix zcela ovlßdly, nenφ tato mo₧nost p°φliÜ vyu₧φvßna. Do budoucna by se ale zmφn∞nΘ rozhodnutφ mohlo ukßzat jako velmi prozφravΘ. Pokud se toti₧ referenΦnφ model ISO/OSI opravdu prosadφ do ₧ivota, nebo se alespo≥ stane skuteΦnou konkurencφ pro sφ¥ov² model TCP/IP, bude zaΦlen∞nφ ISO protokol∙ do BSD Unixu velmi jednoduchΘ.
V∞tÜφ obecnost nov∞ vytvo°enΘho mechanismu, umo₧≥ujφcφ zp°φstupnit aplikacφm p°enosovΘ slu₧by r∙zn²ch soustav protokol∙, vÜak nenφ zcela zadarmo. Cenou za tuto v∞tÜφ obecnost je samoz°ejm∞ pon∞kud v∞tÜφ komplikovanost pou₧itφ. Kdyby Ülo o mechanismus, urΦen² pouze pro protokoly TCP/IP, mohl by nap°φklad v₧dy sßm p°edpoklßdat, ₧e kdykoli se mu zadß n∞jakß adresa, jde o tzv. IP adresu (viz 44. dφl serißlu). Takto je nutnΘ mu to explicitn∞ sd∞lit.
Abychom si ale mohli ukßzat, v Φem toto zobecn∞nφ spoΦφvß, musφme se jeÜt∞ vrßtit k soubor∙m a zp∙sobu prßce s nimi.
Kdy₧ se n∞jak² proces rozhodne pracovat s urΦit²m souborem, musφ jej nejprve otev°φt. Vlastnφ otev°enφ vÜak zajiÜ¥uje operaΦnφ systΘm, a proto si provedenφ pot°ebnΘ operace (operace open) proces vy₧ßdß na operaΦnφm systΘmu. KonkrΘtnφ forma je takovß, ₧e proces pou₧ije tzv. systΘmovΘ volßnφ (system call), neboli spustφ podprogram, kter² je souΦßstφ operaΦnφho systΘmu. Sv∙j konkrΘtnφ po₧adavek (kter² soubor mß b²t otev°en, jak²m zp∙sobem atd.) proces specifikuje prost°ednictvφm parametr∙ tohoto volßnφ. Vlastnφ otev°enφ souboru pak probφhß pln∞ v re₧ii operaΦnφho systΘmu, kter² si za tφmto ·Φelem zalo₧φ vhodnou datovou strukturu, a v nφ si udr₧uje vÜe, co k prßci se souborem pot°ebuje.
Proces, kter² si otev°enφ souboru vy₧ßdal, pak jeÜt∞ musφ mφt k dispozici prost°edek, pomocφ kterΘho p°i vÜech nßsledn²ch operacφch nad ji₧ otev°en²m souborem (tj. operacφch read, write a close atd.) urΦφ, kterΘho souboru se po₧adovanΘ operace t²kajφ. NejlΘpe by se k tomuto ·Φelu hodila zmφn∞nß datovß struktura, ale ta je zcela ve sprßv∞ operaΦnφho systΘmu, kter² ji aplikaΦnφm proces∙m nezve°ej≥uje. P°esto ale umo₧≥uje aplikaΦnφm proces∙m odkazovat se na tuto strukturu, a to prost°ednictvφm nep°φmΘho ukazatele (kter² je ve skuteΦnosti cel²m Φφslem bez znamΘnka, a lze si jej p°edstavit jako index do tabulky, obsahujφcφ ukazatele na zmφn∞nΘ datovΘ struktury). Operace open proto vracφ jako sv∙j v²sledek celΘ Φφslo (tzv. deskriptor souboru, file descriptor), a ten pak pou₧φvajφ operace read, write a close k urΦenφ souboru, ze kterΘho se mß Φφst, do kterΘho se mß zapisovat, resp. kter² mß b²t uzav°en.
Nynφ si ji₧ m∙₧eme snadno naznaΦit, co je podstatou novΘho mechanismu "socket interface". Samotn² socket nenφ nic jinΘho, ne₧ jinß varianta v²Üe popsanΘ datovΘ struktury, ve kterΘ si operaΦnφ systΘm uchovßvß r∙znΘ ·daje (tentokrßte pro pot°eby komunikace v sφti). Socket op∞t nenφ p°φmo p°φstupn², ale aplikaΦnφ procesy se na n∞j mohou odkazovat p°esn∞ stejn²m zp∙sobem, jako na zmφn∞nou datovou strukturu p°i prßci se soubory - tedy nep°φmo, prost°ednictvφm celΘho Φφsla. To se nynφ oznaΦuje jako deskriptor socketu (socket descriptor), ale sv²m datov²m typem je toto₧nΘ s deskriptorem souboru (jde o celΘ Φφslo bez znamΘnka).
Stejn² je takΘ zp∙sob prßce se sockety - prost°ednictvφm systΘmov²ch volßnφ. Samotn² repertoßr systΘmov²ch volßnφ pro prßci se sockety je vÜak samoz°ejm∞ jin², ne₧ pro prßci se soubory. BSD Unix se vÜak sna₧φ zachovßvat maximßlnφ mo₧nou sluΦitelnost obou mechanism∙, tak aby se liÜily jen tam, kde je to skuteΦn∞ nutnΘ. Proto nap°φklad umo₧≥uje pou₧φvat operace read a write jak pro Φtenφ a zßpis dat do soubor∙, tak i pro jejich vlastnφ p°enos po sφti prost°ednictvφm socket∙. Za tφmto ·Φelem mj. vybφrß celß Φφsla, kterß p°id∞luje jako deskriptory, z jedinΘ mno₧iny. Nem∙₧e se tudφ₧ stßt, aby se Φφselnß hodnota deskriptoru souboru a deskriptoru socketu rovnala.
Tφm se vychßzφ vst°φc pot°ebßm nejr∙zn∞jÜφch proces∙, kterΘ vystupujφ v roli server∙, pot°ebujφ si nechat vytvo°it socket pro komunikaci se sv²mi klienty, ale teprve nßsledn∞ se dozvφdajφ, kte°φ klienti s nimi budou chtφt komunikovat.
Äßdost o vytvo°enφ novΘho socketu, kterou aplikaΦnφ proces p°edßvß operaΦnφmu systΘmu formou systΘmovΘho volßnφ (s p°φznaΦn²m nßzvem socket) vÜak ve sv²ch parametrech obsahuje ·daj o tom, s jakou soustavou protokol∙ bude socket pracovat (co₧ mj. definuje v²znam nßsledn∞ zadßvan²ch adres), dßle druh spojenφ (spolehlivΘ spojovanΘ Φi nespolehlivΘ nespojovanΘ, p°φpadn∞ spojenφ na ni₧Üφ ·rovni, ne₧ je transportnφ), a takΘ konkrΘtnφ protokol z p°φsluÜnΘ rodiny protokol∙, kter² bude p°enos zajiÜ¥ovat (co₧ pamatuje na p°φpad, kdy po₧adovan² druh spojenφ m∙₧e b²t v rßmci zvolenΘ soustavy protokol∙ realizovßn vφce alternativnφmi protokoly).
Zde je ovÜem t°eba si uv∞domit, ₧e porty jsou jednotn²m konstruktem v rßmci celΘho sφ¥ovΘho modelu TCP/IP, zatφmco sockety jsou jen jednφm z mo₧n²ch prost°edk∙ pro zp°φstupn∞nφ transportnφch slu₧eb aplikaΦnφm proces∙m (tφm, kter² je pou₧φvßn v BSD Unixu). Jednotnost port∙ ve vÜech uzlech umo₧≥uje jednotnΘ adresovßnφ entit aplikaΦnφ vrstvy, bez ohledu na to, jak² konkrΘtnφ mechanismus pou₧φvajφ tyto entity pro p°φstup ke slu₧bßm transportnφ vrstvy. Jsou-li tφmto mechanismem sockety, existuje mezi nimi a porty jednoznaΦnß korespondence: ka₧d² socket odpovφdß jednomu portu, resp. je svßzßn s prßv∞ jednφm portem.
Tato vazba mezi portem a socketem vÜak nenφ automatickß. P°esn∞ji: nevznikß p°i vytvo°enφ socketu (systΘmov²m volßnφm socket), ale musφ b²t vytvo°ena a₧ nßsledn∞, na explicitnφ p°φkaz (systΘmov²m volßnφm bind).
Volba lokßlnφho portu, na kter² mß b²t socket navßzßn, m∙₧e b²t pro n∞kterΘ aoplikaΦnφ procesy irrelevantnφ, a tyto procesy pak mohou nechat volbu konkrΘtnφho portu na operaΦnφm systΘmu. Jinak je tomu ale u proces∙, kterΘ vystupujφ v roli server∙, a svΘ slu₧by poskytujφ na tzv. dob°e znßm²ch portech (se kter²mi p°edem poΦφtajφ potencißlnφ klienti t∞chto slu₧eb), viz 55. dφl serißlu.
Jak mß ale postupovat proces, kter² sßm komunikaci iniciovat nechce? Tedy nap°φklad proces, kter² chce vystupovat v roli serveru, a chce p°itom pou₧φvat spojovan² charakter komunikace?
TakΘ si musφ nejprve nechat vytvo°it pot°ebn² socket (volßnφm socket), a pak jej navßzat na vhodn² lokßlnφ port (volßnφm bind). Pak ale musφ uvΘst socket do takovΘho stavu, kter² odpovφdß pasivnφmu otev°enφ - tedy kdy socket (resp. na n∞j navßzan² port) pouze pasivn∞ Φekß na p°ichßzejφcφ ₧ßdosti o navßzßnφ spojenφ. Za tφmto ·Φelem je v BSD Unixu k dispozici dalÜφ systΘmovΘ volßnφ listen, kterΘmu se navφc jako parametr zadßvß, jak velkou frontu si mß vytvo°it pro p°ichßzejφcφ volßnφ Φi data.
Kdy₧ je takto socket p°ipraven p°ijφmat ₧ßdosti o navßzßnφ spojenφ, musφ zaΦφt Φekat i samotn² aplikaΦnφ proces. K tomu mß k dispozici dalÜφ systΘmovΘ volßnφ accept.
![]() |
Cel² postup komunikace spojovanΘho charakteru ze strany serveru i klienta ukazuje obr. 62.1., vΦetn∞ zruÜenφ socketu volßnφm close. V p°φpad∞ nespojovanΘ komunikace je cel² postup pon∞kud jednoduÜÜφ - na stran∞ serveru pak odpadajφ volßnφ listen a accept, kterß se t²kajφ navazovßnφ spojenφ, a na stran∞ klienta nepovinnΘ volßnφ connect.