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

zp∞t do archivu Φlßnk∙ | rejst°φk | p°edchozφ dφl | nßsledujφcφ dφl

Ji°φ Peterka: Co je Φφm ... v poΦφtaΦov²ch sφtφch (62):

Transportnφ rozhranφ - BSD Sockets

V minulΘm dφlu jsme dosp∞li k tomu, ₧e implementace protokol∙ transportnφ vrstvy, stejn∞ tak jako vÜech ni₧Üφch vrstev, je souΦßstφ operaΦnφho systΘmu, a slu₧by t∞chto vrstev jsou jednotliv²m aplikacφm poskytovßny pomocφ takov²ch mechanism∙, kterΘ jsou v danΘm operaΦnφm systΘmu k dispozici - a kterΘ samoz°ejm∞ mohou b²t v r∙zn²ch operaΦnφch systΘmech r∙znΘ. Pak jsme se ji₧ zam∞°ili na prost°edφ operaΦnφho systΘmu Unix a °ekli si, ₧e ten se zpoΦßtku sna₧il uplatnit i na sφ¥ sv∙j jednotn² pohled na vÜechna za°φzenφ, kterß chßpe jako specißlnφ soubory, a jako se soubory s nimi takΘ pracuje. ╪ekli jsme si vÜak takΘ, ₧e prßv∞ v p°φpad∞ sφ¥ov²ch slu₧eb se p∙vodnφ prost°edky pro prßci se soubory zßhy ukßzaly b²t nedostaΦujφcφ, a proto musely b²t vyvinuty novΘ, obecn∞jÜφ mechanismy. Zßv∞rem jsme si pak takΘ naznaΦili, ₧e v ka₧dΘ z obou hlavnφch v∞tvφ Unixu byly za tφmto ·Φelem vytvo°eny jinΘ mechanismy. Dnes si podrobn∞ji ukß₧eme, jak je tomu v tzv. BSD Unixu.

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.

Co je vlastn∞ socket?

Nov² mechanismus pro zp°φstupn∞nφ slu₧eb transportnφch protokol∙, vytvo°en² pro tzv. BSD Unix (tj. pro Unix, vyvφjen² ve st°edisku Berkeley Software Distribution p°i University of Berkeley), je oznaΦovßn jako socket interface, nebo zkrßcen∞ jen jako sockets (doslova: objφmky, zßsuvky. V prvnφm p°iblφ₧enφ lze °φci, ₧e jde o zobecn∞nφ p∙vodnφho mechanismu Unixu pro prßci se soubory, a ₧e ka₧d² "socket" je vlastn∞ koncov²m bodem komunikace.

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.

Vytvß°enφ socket∙

SpoleΦnou vlastnostφ obou mechanism∙ je skuteΦnost, ₧e p°φsluÜnΘ datovΘ struktury vznikajφ a₧ v okam₧iku jejich skuteΦnΘ pot°eby - p°i otevφrßnφ souboru, resp. p°i °ßdosti o vytvo°enφ socketu, a vytvß°φ je operaΦnφ systΘm na zßklad∞ bezprost°ednφho po₧adavku aplikaΦnφho procesu. V²znamn² rozdφl je ale v tom, co vÜechny musφ b²t v okam₧iku vytvß°enφ p°φsluÜn²ch datov²ch struktur zadßno: v p°φpad∞ otevφrßnφ soubor∙ to musφ b²t explicitnφ ·daj o konkrΘtnφm souboru, kter² mß b²t otev°en. Naproti tomu p°i z°izovßnφ socketu se jeÜt∞ neuvßdφ, s k²m se bude jeho prost°ednictvφm komunikovat.

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).

Vazba socketu na lokßlnφ port

Jestli₧e jsme si ji₧ d°φve uvedli, ₧e na socket se m∙₧eme dφvat jako na koncov² bod komunikace na danΘm uzlovΘm poΦφtaΦi, jak² je v tomto p°φpad∞ jeho vztah k port∙m? Jak jsme si uvedli v 55. dφlu, je prßv∞ port koncov²m bodem komunikace na rozhranφ mezi transportnφ vrstvou a vrstvou aplikaΦnφ.

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.

Vazba socketu na vzdßlen² port

Vytvo°enφ vazby socketu na n∞kter² z lokßlnφch port∙ na danΘm uzlovΘm poΦφtaΦi stßle jeÜt∞ nic ne°φkß o tom, s k²m se bude prost°ednictvφm danΘho socketu komunikovat - tj. s kter²m jin²m uzlov²m poΦφtaΦem a kterou aplikaΦnφ entitou na tomto poΦφtaΦi. Za tφmto ·Φelem je BSD Unix vybaven dalÜφm systΘmov²m volßnφm (connect), kterΘmu se jako parametr zadß adresa vzdßlenΘho poΦφtaΦe a Φφslo portu na tomto poΦφtaΦi. V²sledn² efekt systΘmovΘho volßnφ connect pak ovÜem zßvisφ na tom, jak² druh spojenφ byl specifikovßn p°i vytvß°enφ socketu (pomocφ volßnφ socket). Pokud Ülo o spojenφ spojovanΘho charakteru, je v rßmci volßnφ connect spojenφ skuteΦn∞ vytvo°eno (tj. navßzßno). Pokud jde o komunikaci nespojovanΘho charakteru, je volßnφ connect nepovinnΘ, a mß vlastn∞ jen vedlejÜφ efekt v tom, ₧e specifikuje adresu, na kterou budou nßsledn∞ odesφlßny jednotlivΘ datagramy - tak aby tato adresa nemusela b²t s ka₧d²m datagramem zadßvßna v₧dy znovu.

╚ekßnφ na ₧ßdost o spojenφ

AplikaΦnφ proces, kter² sßm iniciuje p°enos dat, si tedy nejprve nechß vytvo°it socket (volßnφm socket), pak jej svß₧e s urΦit²m mφstnφm portem (volßnφm bind), a poslΘze i s portem na vzdßlenΘm poΦφtaΦi (volßnφm connect), jde-li o spojovanou komunikaci. Pak ji₧ m∙₧e p°istoupit k vysφlßnφ Φi p°φjmu vlastnφch dat. Za tφmto ·Φelem mß k dispozici hned n∞kolik variant operacφ read a write (realizovan²ch op∞t formou systΘmov²ch volßnφ), kterΘ jsou v principu shodnΘ se Φtenφm a zßpisem dat do soubor∙.

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.

Obrßzek 62.1.
Obr. 62.1.: P°edstava prßce se sockety p°i spojovanΘ komunikaci
Jakmile na port, na kterΘm proces "Φekß", p°ijde n∞jakß ₧ßdost o navßzßnφ spojenφ, operaΦnφ systΘm tuto ₧ßdost p°ijme, a vytvo°φ nov² socket, kter² "navß₧e" na port volajφcφho - Φφm₧ vlastn∞ navß₧e spojenφ mezi serverem a jeho klientem. P°es tento nov² socket bude probφhat vlastnφ komunikace, zatφmco na p∙vodnφm socketu budou dßle oΦekßvßny po₧adavky na navßzßnφ spojenφ. ┌daj o nov∞ vytvo°enΘm socketu p°itom operaΦnφ systΘm p°edßvß jako v²stupnφ parametr volßnφ accept. AplikaΦnφ proces v roli serveru pak bu∩to zajistφ nßslednou komunikaci s klientem sßm, a po jejφm skonΦenφ nov∞ vytvo°en² socket zase nechß zruÜit, nebo si ke zpracovßnφ po₧adavku vytvo°φ samostatn² podproces, a sßm se v∞nuje jen Φekßnφ na dalÜφ ₧ßdosti (volß 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.


zp∞t do archivu Φlßnk∙ | rejst°φk | p°edchozφ dφl | nßsledujφcφ dφl
Tento Φlßnek m∙₧e b²t voln∞ Üφ°en, pokud se tak d∞je pro studijnφ ·Φely, na nev²d∞leΦnΘm zßklad∞ a se zachovßnφm tohoto dov∞tku. Podrobnosti hledejte zde, resp. na adrese http://archiv.czech.net/copyleft.htm