Sieciowe Systemy Operacyjne Unix


Sieciowe Systemy Operacyjne  UNIX
Tomasz Surmacz
tsurmacz@ict.pwr.wroc.pl
¦roc艂aw, 5 stycznia 2002 roku
1. Podstawy systemu UNIX System UNIX
Podstawy systemu UNIX
System UNIX
Pocz膮tki  1970: Ken Thompson, Dennis Ritchie (Bell Laboratories) na
maszynie PDP-7, nast臋pnie PDP-11/20
" 1973  pierwsza wersja z j膮drem napisanym w C
" 1979  BSD Unix (University of California, Berkeley)
" 1983  Unix System V
" 1990  Unix System V Release 4
" 1987  Minix (A. Tanenbaum)
" 1991  Linux 0.02 (Linus Torvalds)
Brian Kernighan  j臋zyk C, powsta艂 specjalnie w celu zapewnienia prze-
no艣no艣ci pisanego oprogramowania
Cechy systemu:
" system wielou偶ytkownikowy
" system wielozadaniowy (wiele proces贸w)
" podzia艂 czasu
" wyw艂aszczanie proces贸w
" podsystem plik贸w
" zarz膮dzanie pami臋ci膮
" biblioteki systemowe
" wszystkie urz膮dzenia dost臋pne przez pliki specjalne
Sieciowe Systemu Operacyjne  UNIX 1-1
1. Podstawy systemu UNIX System UNIX
3 podstawowe wersje: (1988)
" Version 7
" Berkeley  BSD 4.1 vs. BSD 4.2 (BSD4.4)
" System V  SysV Rel.3 vs. Sysv Rel. 2 (SVR4)
Podstawowe r贸偶nice:
" parametry wykonania komend (np.ps -eflubps -aux)
" r贸偶ne koncepcje dost臋pu do terminali (strumienie w SysV)
" inna obs艂uga przerwa艅 systemowych (sygna艂贸w)
" inne umiejscowienie standardowych program贸w
Standardy:
" ANSI C
" POSIX
" X/Open
"  Jedn膮 z najwspanialszych zalet zwi膮zanych ze standaryzacj膮 jest
to, 偶e obowi膮zuj膮cych standard贸w jest tak wiele, 偶e zawsze znajdzie
si臋 taki, kt贸ry nam odpowiada.
Licencje:
" Systemy komercyjne: SysV, SCO, Solaris, HPUX, OSF, ...
" FreeBSD, Linux
" FSF & GNU
" Licencja GPL
Sieciowe Systemu Operacyjne  UNIX 1-2
1. Podstawy systemu UNIX System plik贸w
System plik贸w
" Separatorem 艣cie偶ki jest znak  /
" Katalog / to  korze艅 (root) systemu plik贸w
" Wszystkie katalogi/dyski s膮 pod艂膮czone jako ga艂臋zie drzewa katalo-
g贸w  zar贸wno lokalne, jak i zdalne.
/
usr bin
var
lib
etc
dev
bin
spool
/dev/dsk/c0t0d1s0
local
log
bin
home
/dev/dsk/c1t2d0s4
lib
/dev/dsk/c0t0d1s1
user1
user2
cyber:/export/home
" R贸偶ne rodzaje system贸w plik贸w: UFS, SysV, minix, ext2, MSDOS,
NFS
" Komendy zwi膮zane z plikami:ls,cd,pwd,mkdir,rmdir,cat,mv,
cp,rm,mount,umount,df,du,quota
" Pliki: /etc/fstab, /etc/mntab, /etc/exports
Sieciowe Systemu Operacyjne  UNIX 1-3
1. Podstawy systemu UNIX Zarz膮dzanie pami臋ci膮
Zarz膮dzanie pami臋ci膮
" Pami臋膰 fizyczna systemu podzielona jest na segmenty
" Rozmiar segmentu  z regu艂y 4-8-32 kB
" Dost臋p do segmentow pami臋ci realizowany jest przez tablic臋 deskryp-
tor贸w pami臋ci, z pomoc膮 sprz臋towych uk艂ad贸w MMU
" Pami臋膰 wirtualna
 Swoboda adresowania
 Mo偶liwo艣膰 zaadresowania wi臋kszego obszaru pami臋ci ni偶 dost臋p-
ny
 Stronicowanie pami臋ci/plik wymiany, dokonywane automatycz-
nie
Podzia艂 pami臋ci w systemie UNIX:
" Pami臋膰 j膮dra systemu
" Bufory dyskowe
" Plik(i) wymiany (swap)
" Pami臋膰 proces贸w u偶ytkownik贸w
 Kod programu (TEXT)
 Dane
 Stos
 Stos wywo艂a艅 systemowych
Sieciowe Systemu Operacyjne  UNIX 1-4
1. Podstawy systemu UNIX Biblioteki
Biblioteki
" J臋zyk C okre艣la konstrukcje steruj膮ce wykonaniem programu
" Funkcje nie s膮 cz臋艣ci膮 j臋zyka C, lecz bibliotek systemowych lub pro-
gram贸w  nawet najbardziej podstawowe, jak printf ()
" Funkcje systemowe znajduj膮 si臋 w bibliotekach dynamicznych,
takich jak libc.so
" Biblioteki statyczne (np. /usr/lib/libc.a)
 do艂膮czane w ca艂o艣ci lub cz臋艣ciowo do kodu kompilowanego pro-
ramu, w trakcie kompilacji
 programy linkowane statycznie s膮 wi臋ksze, lecz nie wymagaj膮
dzia艂aj膮cego linkerald
" Biblioteki dynamiczne (np. /usr/lib/libsocket.so.2 )
 do艂膮czane dynamicznie do kodu programu w trakcie jego uru-
chamiania
 zajmuj膮 region pami臋ci wsp贸艂dzielony z innymi procesami
 mniejsze zapotrzebowanie na pami臋膰
 mniejsze programy
 dynamiczny linker  programyldildd
" Zmienna 艣rodowiskowa LD LIBRARY PATH
" Podstawowe biblioteki systemowe:
 libc.so  standardowe funkcje wej艣cia/wyj艣cia, zarz膮dzania pa-
mi臋ci膮, itp.
 libm.so  funkcje matematyczne
 libsocket.so  funkcje sieciowe (SysV)
 libnsl.so   name server library  t艂umaczenie nazw kompute-
r贸w na adresy
 libX11.so  funkcje systemu okienkowego X11
Sieciowe Systemu Operacyjne  UNIX 1-5
1. Podstawy systemu UNIX U偶ytkownicy
U偶ytkownicy
" System wielozadaniowy (multitasking)
" System wielou偶ytkownikowy (multiuser)
" Konieczno艣膰 ochrony u偶ytkownik贸w przed sob膮 nawzajem
Atrybuty u偶ytkownika  /etc/passwd:
root:x:0:1:Super-User:/root:/sbin/sh
ts:x:138:10:Tomasz Surmacz:/home/ts:/usr/local/bin/tcsh
nobody:x:60001:60001:Nobody:/:
" Nazwa u偶ytkownika
" Identyfikator (uid)
" Grupa (nazwa i identyfikator  gid)
" Has艂o dost臋pu
" Katalog domowy
" Interpreter polece艅 (shell)
Dla j膮dra systemu istotne s膮:
" uid procesu
" gid procesu
" prawa dost臋pu do pliku
" uprawnienia specjalne (uid==0)
Polecenia operuj膮ce na uid/gid:
" newgrp,su,login,id
Sieciowe Systemu Operacyjne  UNIX 1-6
1. Podstawy systemu UNIX Prawa dost臋pu
Prawa dost臋pu
" Ka偶dy plik w systemie ma swojego w艂a艣ciciela i w艂a艣ciciela grupo-
wego
" Ka偶dy plik opisany jest przez 3 grupy praw dost臋pu:
 dla w艂a艣ciciela (user)
 dla grupy (group)
 dla pozosta艂ych u偶ytkownik贸w (other)
" Podstawowe prawa dost臋pu to
 (r)ead  odczyt
 (w)rite  pisanie
 e(x)ecute  wykonanie
w艂a艣ciciel

gru a
p


pozostali
u g o
drwxr-x--x 3 root wheel
111101001

7 5 1
liczba dowi膮za艅


typ (katalog/ lik/...)
p
Przyk艂adowa zawarto艣膰 katalogu domowego:
drwxr-x--x 44 ts users 2048 Feb 27 16:39 .
drwxr-xr-x 47 ts users 3072 Feb 28 00:28 ..
-rw------- 1 ts users 3476 May 25 1998 .cshrc
-rw-r--r-- 1 ts users 16 Jun 28 1999 .forward
Sieciowe Systemu Operacyjne  UNIX 1-7
1. Podstawy systemu UNIX Prawa dost臋pu
drwx------ 2 ts mail 1024 Feb 27 03:44 Mail
drwxr-xr-x 3 ts users 1024 Jun 2 1998 News
drwxr-xr-x 2 ts users 1024 Feb 19 1998 Done
drwxr-xr-x 3 ts users 1024 Dec 1 14:31 hitch
-rw-r--r-- 1 ts wheel 4029 Feb 27 03:13 back.tar.gz
drwxr-xr-x 3 ts users 1024 Feb 27 03:44 pwis
drwxr-xr-x 3 ts users 1024 Feb 27 03:19 src
Komendy pozwalaj膮ce zmienia膰 prawa dost臋pu:
" chmod,chgrp
" chown(tylko u偶ytkownik root!)
" umask
Bity specjalne:
" -rwsr-xr-x set-user-id
" -rwxr-sr-x set-group-id
" -rw------T sticky bit
" drwxr-sr-x set-group-id
" drwxrwxrwt sticky bit
" prw-rw-rw- strumie艅 (named pipe)
" srw-rw-rw- gniazdo w domenie UNIX (UNIX-domain socket)
" brw-rw---- urz膮dzenie blokowe (block device)
" crw-rw---- urz膮dzenie znakowe (character device)
" lrwxrwxrwx dowi膮zanie symboliczne (symbolic link)
Sieciowe Systemu Operacyjne  UNIX 1-8
1. Podstawy systemu UNIX 艢rodowisko programistyczne
Wej艣cie/wyj艣cie
" standardowe wej艣cie  stdin
" standardowe wyj艣cie  stdout
" wyj艣cie b艂臋d贸w  stderr
" strumie艅 pipe
" przekierowanie we/wy:< > << >> |
/etc/passwd
grep cat -n tee abc less
abc
grep :0: < /etc/passwd | cat -n | tee abc | less
" system plik贸w
" katalogi, podkatalogi, pliki
Interpreter polece艅  shell
" /bin/sh
" /bin/csh
" bash
" tcsh
Sieciowe Systemu Operacyjne  UNIX 1-9
1. Podstawy systemu UNIX 艢rodowisko programistyczne
艢rodowisko programistyczne
Edytory tekstu:
" vi
" emacs
" jed
" joe
Kompilatory:
" cc
" gcc
" g++
" Programmakewywo艂uj膮cy odpowiednie kompilatory i linker
" Linkowanie  ldlubgcc
" Pliki nag艂贸wkowe: /usr/include, /usr/local/include
" Biblioteki: /usr/lib, /usr/local/lib
Uruchamianie program贸w:
" Debugger systemowyadb
" Debugger GNUgdb
" 艢cie偶ka wykonania  katalog . (kropka)
Sieciowe Systemu Operacyjne  UNIX 1-10
2. Procesy
Procesy
" tworzone funkcj膮 fork()
" unikalny pid
" przodek (rodzic) potomek (dziecko)
" grupa proces贸w i przewodnik grupy
Stany proces贸w:



tryb u偶 k.
yt



tryb j dra.



u艣piony
gotowy
" prze艂膮czanie proces贸w/prze艂膮czanie kontekstu
" tablica proces贸w
" priorytety
" nice
Sieciowe Systemu Operacyjne  UNIX 2-1
2. Procesy Kontekst procesu
Kontekst procesu
" Ka偶dy proces posiada w艂asne segmenty kodu, danych i stosu.
" J膮dro systemu, poprzez system obs艂ugi pami臋ci wirtualnej, w chwili
wykonywania procesu ma dost臋p do jednego segmentu kodu, jednego
segmentu danych i jednego segmentu stosu.
" Tablica proces贸w zawiera wskazniki do zapami臋tanych kontekst贸w
poszczeg贸lnych proces贸w  zawieraj膮cych ich prywatne mapy odwzo-
rowuj膮ce wszystkie trzy segmenty programu na segmenty pami臋ci
fizycznej.
RAM RAM
CPU


proces 1
proces 1


k od
od
k kod
1 1




ddane
ane
dane


sstos
tos
2 2
stos
3 3
CPU


proces 2
proces 2

4 4

k od
od
kod k



ddane
ane
dane

5 5

sstos
tos
stos
" Prze艂膮czenie kontekstu polega na zapami臋taniu aktualnego kontek-
stu procesu w jego obszarze kontekstu, po czym wczytaniu do pro-
cesora kontekstu innego procesu.
Sieciowe Systemu Operacyjne  UNIX 2-2
2. Procesy Sterowanie procesami z pow艂oki u偶ytkownika
Sterowanie procesami z pow艂oki u偶ytkownika
" Ka偶dy proces zwraca warto艣膰:0 ok,>0 b艂膮d
" Separator komend: znak;lub&lub znak nowej linii
" Uruchamianie w tle:proces &
" A膮czenie proces贸w strumieniem:proces1 | proces2
" Warunkowe wykonanie drugiego procesu:
 je艣li pierwszy zako艅czy艂 si臋 poprawnie:proces1 && proces2
 je艣li pierwszy zako艅czy艂 si臋 b艂臋dem:proces1 || proces2
" Przekierowanie wyj艣cia b艂臋d贸w:
 csh:proces >& plikorazproces1 |& proces2
 sh:proces > plik 2>&1
" Zatrzymanie procesu:stop %nazwa, KlawiszCtrl-Z,kill -STOP,
kill -SUSP
" Zabicie procesu lub wys艂anie sygna艂u:kill,kill -WINCH, itp.
" Ponowne uruchomienie zatrzymanego procesu:fg
" Ponowne uruchomienie procesu w tle:bg
" Sprawdzenie listy dzia艂aj膮cych proces贸w:jobs, a tak偶eps
Sieciowe Systemu Operacyjne  UNIX 2-3
2. Procesy Tworzenie nowych proces贸w
Tworzenie nowych proces贸w
" Do tworzenia nowych proces贸w s艂u偶y fynkcja fork() ze standardowej
biblioteki libc.so.
" Nowy proces, utworzony funkcj膮 fork() jest dok艂adn膮 kopi膮 rodzica
i wykonuje si臋 w tym samym miejscu  za wywo艂aniem funkcji fork()
printf("ok\n");
a=7;
p=fork();
if (p==-1) {

id=1234
...
p
printf("ok\n"); printf("ok\n");
printf("ok\n");
a=7; a=7;
a=7;
p=fork(); p=fork();
p=fork();
if (p==-1) { if (p==-1) {
if (p==-1) {

id=1234 id=1240
... ...
...
p p
" Oba procesy nie r贸偶ni膮 si臋 niczym, poza warto艣ci膮 zwr贸con膮 przez
funkcj臋 fork():
 rodzic: numer procesu potomnego
 dziecko: warto艣膰 0
" Sposobem na rozr贸偶nienie obu proces贸w jest zbadanie tej warto艣ci:
pid=fork();
switch (pid) {
case -1: printf("B艂膮d fork!\n");
exit(1);
case 0: /* dziecko */
printf("Tu pisze dziecko. pid rodzica=%d\n", getppid());
break;
default: /* rodzic */
printf("To drukuje rodzic. pid dziecka=%d\n", pid);
}
" Inne funkcje: getpid(), getppid(), wait(), kill(), exec()
Sieciowe Systemu Operacyjne  UNIX 2-4
2. Procesy Tworzenie nowych proces贸w
Funkcja fork()
" przydziela nowemu procesowi pozycj臋 w tablicy proces贸w
" przydziela nowemu procesowi nowy, unikalny identyfikator
" tworzy kopi臋 kontekstu procesu macierzystego, kopiuj膮c segmenty
pami臋ci lub zwi臋kszaj膮c licznik odwo艂a艅 do segmentu (np. wsp贸艂-
dzielonego segmentu kodu)
" otwarte pliki rodzica pozostawia otwarte w dziecku, a wi臋c zwi臋ksza
liczniki w tablicy plik贸w i i-w臋z艂贸w
" przekazuje rodzicowipiddziecka, a dziecku  warto艣膰 0.
" nowy proces, cho膰 nie by艂 jeszcze nigdy wykonywany,  budzi si臋 tak,
jakby zasn膮艂 w oczekiwaniu na zas贸b (wychodzi ze stanu u艣pienia)



tryb u偶 k.
yt




zombie tryb j dra. wyw艂a zcz.
膮 s


u艣piony
gotowy
fork()

utworzony
Sieciowe Systemu Operacyjne  UNIX 2-5
2. Procesy Tworzenie nowych proces贸w
Funkcje exec()
" Rodzina funkcji: execl(), execv(), execle(), execve(), execlp(), exe-
cvp()
" 1. argument  艣cie偶ka programu lub skryptu
" 2. argument i dalsze  paramentry wywo艂ania
" Wywo艂anie nadpisuje w aktualnym kontek艣cie procesu segmenty ko-
du, danych i stosu nowym programem i wykonanie funkcji main()
if ((pid=fork())==0) {
execl("/bin/ls", "ls", "-la", "/tmp", NULL);
printf("B艂膮d!!! Ta instrukcja nie ma prawa si臋 wykona膰!\n");
} else {
wait(NULL);
}
Nowy proces dziedziczy:
" numer procesu i numer procesu rodzica oraz przynale偶no艣膰 do grupy
proces贸w
" warto艣膰nice
" warto艣膰umask
" priorytet
" uid,gidi przynale偶no艣膰 do grup u偶ytkownik贸w
" katalog bie偶膮cy
" limity zasob贸w
" otwarte pliki1
" kilka innych warto艣ci dotycz膮cych blokad na plikach, semafor贸w i ob-
s艂ugi sygna艂贸w (man exec)
1
niekoniecznie!  uwaga na fcntl() iFDCLOEXEC
Sieciowe Systemu Operacyjne  UNIX 2-6
2. Procesy Sygna艂y
Sygna艂y
Pozwalaj膮 zasygnalizowa膰 wyst膮pienie sytuacji specjalnej, takiej jak:
" 艣mier膰 potomka (przez wywo艂anie exit() lub w inny spos贸b)
" wyj膮tek  np. pr贸ba dost臋pu do pami臋ci poza przyznany zakres ad-
res贸w, pr贸ba zapisu do pami臋ci z atrybutem read-only, itp.
" niespodziewany b艂膮d podczas wykonywania programu (np. pisanie
do 艂膮cza, kt贸rego ju偶 nikt nie czyta)
" b艂膮d, z kt贸rym system nie potrafi sobie poradzi膰, np. brak pami臋ci na
wykonanie exec() gdy ju偶 zosta艂y zwolnione stare segmenty programu
" pobudka, czyli SIGALARM wysylany na 偶yczenie procesu przez sys-
tem
" interakcja z terminalem  klawisz BREAK, SUSPEND, itp.
" wys艂anie sygna艂u przez inny proces
" wykonywanie programu krok po kroku przez debugger
Sygna艂y s膮 obs艂ugiwane tylko przy przej艣ciu mi臋dzy trybem j膮dra systemu
a trybem u偶ytkownika
ryb u k.
偶yt
t
tryb uzytk.


sprawd& i obs! u偶

ryb j dra .
zcz. tryb uzytk.


zombie t wyw! as

sprawd&

iony
u艣p gotowy
fork()

rzony
utwo
uspiony/swap gotowy/swap
Sieciowe Systemu Operacyjne  UNIX 2-7
2. Procesy Sygna艂y
" List臋 dost臋pnych sygna艂贸w mo偶na sprawdzi膰 pisz膮c
kill -list lub przegl膮daj膮c plik /usr/include/sys/signal.h lub
/usr/include/signum.h
#define SIGHUP 1 /* hangup */
#define SIGINT 2 /* interrupt (rubout) */
#define SIGQUIT 3 /* quit (ASCII FS) */
...
#define SIGFPE 8 /* floating point exception */
#define SIGKILL 9 /* kill (cannot be caught or ignored) */
#define SIGBUS 10 /* bus error */
#define SIGSEGV 11 /* segmentation violation */
#define SIGSYS 12 /* bad argument to system call */
#define SIGPIPE 13 /* write on a pipe with no one to read it */
#define SIGALRM 14 /* alarm clock */
#define SIGTERM 15 /* software termination signal from kill */
#define SIGUSR1 16 /* user defined signal 1 */
#define SIGUSR2 17 /* user defined signal 2 */
...
#define SIGLOST 37 /* resource lost (eg, record-lock lost) */
...
" Cz臋艣膰 sygna艂贸w jest domy艣lnie ignorowana, cz臋艣膰 powoduje zako艅-
czenie procesu
" Ka偶dy sygna艂 z wyj膮tkiemSIGKILLiSIGSTOPmo偶na przechwyci膰,
rejestruj膮c odpowiedni膮 funkcj臋 obs艂ugi sygna艂u za pomoc膮 signal()
lub sigset()
" Je艣li funkcja przechwytuj膮ca ma ignorowa膰 sygna艂, wystarczy wywo-
艂a膰 signal(SIGIGN) lub sigignore()
" Funkcj膮 sigpause(numer-sygna艂u) mo偶na zawiesi膰 proces a偶 do mo-
mentu otrzymania 偶膮danego sygna艂u
" Na czas obs艂ugi sygna艂u przyjmowanie sygna艂贸w tego samego typu
zostaje zablokowane automatycznie (a dodatkowo inne sygna艂y mo偶-
na blokowa膰 i odblokowywa膰 wo艂aj膮c sighold() i sigrelse())
Sieciowe Systemu Operacyjne  UNIX 2-8
2. Procesy Ko艅czenie procesu
Grupy proces贸w
" grup臋 mo偶e stanowi膰 np. interpreter polece艅 (shell) i wszystkie proce-
sy przez niego uruchamiane  naci艣ni臋cie BREAK itp. wysy艂a sygna艂
nie tylko do wykonywanego procesu, ale i do interpretera.
" ustawienie grupy  funkcja setpgrp()
Ko艅czenie procesu
" wait()
" exit()
" Zako艅czony proces staje si臋 zombie i powoduje wys艂anie do rodzica
sygna艂u SIGCLD
" Wywo艂anie przez rodzica funkcji wait() pozwala odebra膰 status
zwr贸cony przez exit()
"  uwolniony zombie ostatecznie znika z systemu
" wywo艂anie wait(), gdy nie ma 偶adnego zombie, zawiesza proces, do
momentu gdy kt贸re艣 z dzieci zako艅czy 偶ywot lub gdy ju偶 nie b臋dzie
偶adnego.
Sieciowe Systemu Operacyjne  UNIX 2-9
3. Strumienie pipe i FIFO Strumienie pipe
Strumienie pipe i FIFO
Strumienie pipe
" pozwalaj膮 艂膮czy膰 spokrewnione ze sob膮 procesy
" transmisja jednokierunkowa
" z regu艂y 艂膮cz膮 wyj艣ciestdoutjednego procesu z wej艣ciemstdin
innego

pro 1 pro 2
ces ces



j dro s jadro s
ystemu ystemu
fd[1] fd[0]
" tworzone funkcj膮 pipe(int fd[2])  wype艂nia 2-elementow膮 tablic臋
deskryptor贸w
" fd[1]jest ko艅cem otwartym do pisania
" fd[0]jest ko艅cem otwartym do czytania
" oba ko艅ce to  zwyk艂e deskryptory plik贸w  mo偶na na nich operowa膰
takimi funkcjami jak read(), write(), fprintf (), czy close().
" j膮dro systmu gwarantuje, 偶e operacje zapisu nie przekraczaj膮ce roz-
miaru strumienia s膮 niepodzielne
Sieciowe Systemu Operacyjne  UNIX 3-1
3. Strumienie pipe i FIFO Pisanie do strumienia pipe
Pisanie do strumienia pipe

pro 1 pro 2
ces ces



j dro s jadro s
ystemu ystemu
fd[1] fd[0]
" strumie艅 pipe pe艂ni jednocze艣nie rol臋 bufora o pojemno艣ci 4kB
" zapisanie danych, gdy jest miejsce w strumieniu, powoduje natych-
miastowy powr贸t z funkcji write() itp.
" zapisanie danych powy偶ej maksymalnego rozmiaru powoduje zablo-
kowanie procesu, do czasu a偶 zwolni si臋 miejsce w strumieniu (kto艣
te dane przeczyta)
" za pomoc膮 odpowiednich funkcji fcntl() lub ioctl() mo偶na usta-
wy膰 opcj臋O_NDELAY, lecz w贸wczas proces pisz膮cy musi by膰 przy-
gotowany na to, 偶e mo偶e mu si臋 uda膰 zapis tylko cz臋艣ci wysy艂anych
danych
" pisanie do strumienia, kt贸rego nikt nie czyta (jego drugi koniec zo-
sta艂 zamkni臋ty) powoduje wys艂anie do procesu pisz膮cego sygna艂u
SIGPIPE
" zamkni臋cie zapisywanego ko艅ca powoduje, 偶e proces czytaj膮cy w wy-
niku wywo艂ania funkcji read() otrzyma warto艣膰 0
Sieciowe Systemu Operacyjne  UNIX 3-2
3. Strumienie pipe i FIFO Czytanie ze strumienia pipe
Czytanie ze strumienia pipe

pro 1 pro 2
ces ces



j dro s jadro s
ystemu ystemu
fd[1] fd[0]
" otrzymywane dane stanowi膮 strumie艅 nie podzielony na 偶adne pa-
kiety lub inne fragmenty
" czytanie ze strumienia mo偶e zwr贸ci膰 mniej danych, ni偶 za偶膮dano
" je艣li strumie艅 jest pusty i zamkni臋ty do zapisu, funkcja read() zwraca
warto艣膰 0, oznaczaj膮c膮EOF.
" je艣li strumie艅 jest pusty, ale otwarty do zapisu, funkcja read() zostaje
zablokowana, do momentu gdy mo偶na b臋dzie co艣 przeczyta膰
" blokowania mo偶na unikn膮膰 stosuj膮c opcj臋O_NDELAYw funkcji fcntl()
lub korzystaj膮c z funkcji select()
" zamkni臋cie strumienia do odczytu, gdy ci膮gle znajdowa艂y si臋 w nim
nie przeczytane dane, generuje sygna艂SIGPIPEwysy艂any do procesu
pisz膮cego
" zamkni臋cie pustego strumienia danych nie powoduje 偶adnych kon-
sekwencji dla procesu pisz膮cego  dop贸ki nie spr贸buje czego艣 zapisa膰.
" dzi臋ki blokowaniu mo偶liwe jest wykorzystanie strumieni do wzajem-
nej synchronizacji proces贸w
Sieciowe Systemu Operacyjne  UNIX 3-3
3. Strumienie pipe i FIFO A膮czenie dw贸ch proces贸w strumieniem pipe
A膮czenie dw贸ch proces贸w strumieniem pipe

pro
ces
int fd[2];
if (pipe(fd)==-1)
perror("pipe");
...


j dro s
ystemu
fd[1] fd[0]
switch (p=fork()){
fd[1] fd[1]

case 0: /*dziecko*/
proces pro s p
ce otomny
...
fd[0] fd[0]
break;
default: /*rodzic*/
...
}



j dro s jadro s
ystemu ystemu
fd[1] fd[0]
/*rodzic*/
fd[1]

close(fd[0]);
proces pro p
ces otomny
write(fd[1], buf,
fd[0]
strlen(buf)+1);


/*dziecko*/
j dro s jadro s
ystemu ystemu
close(fd[1]);
n=read(fd[0], buf,
fd[1] fd[0]
BUFSIZE);
Sieciowe Systemu Operacyjne  UNIX 3-4
3. Strumienie pipe i FIFO Tworzenie strumieni stdout-stdin
Tworzenie strumieni stdout-stdin
" Do kopiowania otwartych deskryptor贸w s艂u偶膮 funkcje dup() i dup2 ()
" dup(n) kopiuje deskryptornna najni偶szy wolny numer deskryptora
" Poni偶szy program:
int fdes;
fdes=open("/tmp/test", "rt");
close(0);
dup(fdes);
spowoduje przepisanie deskryptorafdesdo deskryptora nr 0.
" to samo mo偶na osi膮gn膮膰 za pomoc膮 dup2 (fdes, 0)
Najcz臋stszym zastosowaniem jest zast膮pienie standardowego wej艣cia (lub
wyj艣cia) strumieniem pipe, przed wykonaniem funkcji exec():
int fd[2];
pipe(fd);
if ((f=fork()) == 0) {
/* dziecko -- b臋dzie czyta膰 */
close(fd[1]);
close(0);
dup(fd[0]);
execlp("cat", "cat", "-n", NULL);
fprintf(stderr, "exec si臋 nie uda艂!\n");
exit(1)
} else {
/* rodzic lub b艂膮d fork() */
...
wait();
}
Sieciowe Systemu Operacyjne  UNIX 3-5
3. Strumienie pipe i FIFO Funkcja popen()
Funkcja popen()
Podobny efekt mo偶na osi膮gn膮膰 za pomoc膮 funkcji popen():
#include
FILE *popen(const char *command, const char *mode);
int pclose(FILE *stream);
" popen() tworzy strumie艅 pipe oraz proces potomny, w kt贸rym wyko-
nuje/bin/sh, przekazuj膮c mu jako paramentr nazw臋 programu do
wykonania
" je艣li*type== r , to standardowe wyj艣cie uruchomionego podproce-
su jest po艂膮czone ze strumieniem, a proces g艂贸wny mo偶e czyta膰 ze
zwr贸conego deskryptora
" je艣li*type== w , zwr贸cony koniec jest otwarty do zapisu i po艂膮czony
ze standardowym wej艣ciem uruchomionego podprocesu
" zako艅czenie komunikacji mo偶e wymaga膰 u偶ycia pclose(), zawsze te偶
konieczna jest synchronizacja za pomoc膮 wait().
Wady stosowania popen():
" za ka偶dym razem niepotrzebnie uruchamiany jest/bin/sh
" brak pe艂nej kontroli nad wej艣ciem i wyj艣ciem z podprocesu
" nie jest mo偶liwe jednoczesne przechwycenie wej艣cia i wyj艣cia, ani
rozdzielenie standardowego wyj艣cia od wyj艣cia b艂臋d贸w
" funkcja popen() NIGDY i pod 偶adnym pozorem nie powinna by膰
stosowana w programach typu set-user-id (zbyt 艂atwo przeoczy膰 z艂e
dane przekazywane do interpreterash).
Sieciowe Systemu Operacyjne  UNIX 3-6
3. Strumienie pipe i FIFO Strumienie FIFO
Strumienie FIFO
Zasadnicze r贸偶nice w stosunku do strumieni pipe:
" Posiadaj膮 dowi膮zanie w systemie plik贸w  tworzone funkcj膮 mknod()
lub komend膮mknod.
" Mog膮 by膰 u偶ywane przez procesy nie spokrewnione ze sob膮, a nawet
procesy r贸偶nych u偶ytkownik贸w.
" Funkcja open() u偶ywana do otwierania kolejki FIFO do zapisu bloku-
je proces, a偶 do momentu otwarcia kolejki do odczytu, i odwrotnie.
Dopiero gdy kolejka otwarta jest jednocze艣nie do zapisu i odczytu
obie funkcje open() powracaj膮 ze stanu u艣pienia;
"  Sprz膮tanie tymczasowych kolejek mo偶e wymaga膰 usuni臋cia ich z
systemu plik贸w funkcj膮 unlink().
" Kolejki FIFO maj膮 z regu艂y wi臋kszy rozmiar bufora (4 16 kB)
Podobie艅stwa:
" Zamkni臋cie ko艅ca u偶ywanego do pisania (dok艂adniej: wszystkich ko艅-
c贸w) generuje u czytelnik贸wEOF;
" Zamkni臋cie ko艅ca u偶ywanego do czytania generuje sygna艂SIGPIPE
wysy艂any do wszystkich pisz膮cych do strumienia;
" Zapis i odczyt przez standardowe funkcje I/O, takie jak write() czy
read();
" Niepodzielno艣膰 zapis贸w mniejszych ni偶 rozmiar strumienia;
" Blokowanie proces贸w w przypadku przepe艂nienia lub pustego stru-
mienia (i mo偶liwo艣膰 zastosowaniaO_NDELAY).
Sieciowe Systemu Operacyjne  UNIX 3-7
4. Kolejki komunikat贸w
Korzystanie ze strumieni FIFO
#include
main()
{
int fd;
int err;
err=mknod("/tmp/fifo1", S_IFIFO | 0660, 0)
if (err<0 && err!=EEXIST) {
fprintf(stderr, "Nie mog臋 utworzy膰 FIFO\n");
exit (1);
}
fd=open("/tmp/fifo1, O_RDONLY); /* blokada? */
if (fd<0) {
fprintf(stderr, "Nie mog臋 otworzy膰 FIFO do czytania\n");
exit(2);
}
read(fd, ... ...);
...
close(fd);
unlink("/tmp/fifo1");
}
Kolejki komunikat贸w
" lista (jednokierunkowa) zawieraj膮ca komunikaty o okre艣lonym mak-
symalnym rozmiarze;
" nowe komunikaty dodawane s膮 na ko艅cu listy, zachowuj膮c kolejno艣膰
Sieciowe Systemu Operacyjne  UNIX 4-1
4. Kolejki komunikat贸w
ich wysy艂ania
" ka偶dy komunikat ma dodatkowy parametr zwany typem, co pozwala
na obs艂ug臋 kilku  strumieni komunikat贸w w ramach jednej kolejki
(poprzez selektywne odbieranie komunikat贸w wybranego typu).

msgsnd()
5


kolejka


2
komunikat w
2

(w przestrzeni


3
j dra s temu)
ys
2
3
15
2
5
7
7
3 3
2 2

msgrcv()
2
Sieciowe Systemu Operacyjne  UNIX 4-2
4. Kolejki komunikat贸w Struktura kolejki w j膮drze systemu
Struktura kolejki w j膮drze systemu



strukt ra ms id na ! wki komunika w
u q g t
next: next: next: NULL
struct ipc_perm
msg_perm;
type: 7 type: 3 type: 2
len: 5 len: 10 len: 3
uid_t cuid;
data data data
gid_t cgid;
uid_t uid;

gid_t gid;
obszar d ny h
a c
mode_t mode;
msg 1
...
key_t key;
msg 2
struct msg *first;
struct msg *last;
ulong_t msg_cbytes;
ulong_t msg_qnum; msg 3
ulong_t msg_qbytes;
...
time_t msg_rtime;
time_t msg_ctime;
" cuidicgid proces, kt贸ry utworzy艂 kolejk臋 (creator uid, creator
gid);
" uidigid aktualny w艂a艣ciciel i w艂a艣ciciel grupowy kolejki;
" mode prawa dost臋pu do kolejki;
" key klucz identyfikuj膮cy kolejk臋;
" first,last wskazniki na pierwszy i ostatni komunikat w kolejce;
" wielko艣膰 ca艂ej kolejki nie mo偶e przekracza膰msg_qbytes, a aktualna
wielko艣膰 tomsg_cbytes;
" aktualna liczba komunikat贸w w kolejce tomsg_qnum.
Sieciowe Systemu Operacyjne  UNIX 4-3
4. Kolejki komunikat贸w Tworzenie kolejek
Tworzenie kolejek
int msgget(key_t key, int msgflg);
Funkcja msgget() tworzy now膮 kolejk臋 lub znajduje ju偶 istniej膮c膮
" Je艣li klucz ma warto艣膰IPC_PRIVATE, zawsze jest tworzona nowa ko-
lejka.
" Je艣li kolejka o podanym kluczu ju偶 istnieje, zostaje zwr贸cony jej iden-
tyfikator, o ile u偶ytkownik ma odpowiednie prawa dost臋pu, w prze-
ciwnym razie zwracany jest (poprzez zmienn膮errno) b艂膮dENOENT;
" Je艣li kolejka nie istnieje, a w艣r贸d opcji msgflg ustawiona by艂a
IPC_CREAT, zostaje utworzona nowa kolejka i zwr贸cony jej identy-
fikator;
" U偶ycie opcjiIPC_EXCLwymusza utworzenie nowej kolejki  je偶eli by-
艂y ustawione obie opcje:IPC_CREATiIPC_EXCL, a kolejka ju偶 istnia艂a,
zostaje zwr贸cony b艂膮dEEXIST.
Je艣li tworzona jest nowa kolejka, najm艂odsze 9 bit贸w w opcjach oznacza
prawa dost臋pu do tworzonej kolejki, np. 0644 albo 0666.
#include
#include
#include
#define KEY ((key_t) 12345L)
#define PERM 0600
main()
{
int msqid;
if ( (msqid=msgget(KEY, PERM | IPC_CREAT)) < 0) {
fprintf(stderr, "Nie mo偶na utworzy膰 kolejki\n");
exit (1);
}
...
}
Sieciowe Systemu Operacyjne  UNIX 4-4
4. Kolejki komunikat贸w Usuwanie kolejek
Usuwanie kolejek
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
Funkcja msgctl() pozwala usun膮膰 kolejk臋, ale tak偶e sprawdzi膰 jej stan lub
zmieni膰 pewne warto艣ci zwi膮zane z kolejk膮. Spos贸b dzia艂ania zale偶y od
parametrucmd:
" IPC_STAT umieszcza dane o kolejce w strukturze wskazywanej przez
buf;
" IPC_SET zmienia parametry kolejki na parametry przekazane w
strukturze wskazywanej przezbuf. Zmienione mog膮 zosta膰: w艂a艣ci-
ciel i grupa (o ile wo艂aj膮cy proces ma uid=0 lub taki sam, jak proces,
kt贸ry utworzy艂 kolejk臋), prawa dost臋pu do kolejki i maksymalny roz-
miar kolejki;
" IPC_RMID usuwa kolejk臋 z systemu.
Polecenia systemowe zwi膮zane z kolejkami komunikat贸w:
" ipcrm usuwa kolejk臋
" ipcs -q sprawdza status kolejki
Sieciowe Systemu Operacyjne  UNIX 4-5
4. Kolejki komunikat贸w Wysy艂anie komunikat贸w
Wysy艂anie komunikat贸w
int msgsnd(int msqid, const void *msgp, size_t msgsz,
int msgflg);
struct mymsg { /* przyk艂adowa struktura komunikatu */
long mtype; /* typ komunikatu */
char mtext[1]; /* zawarto艣膰 komunikatu */
}
" Wysy艂aj膮c komunikat nale偶y okre艣li膰 jego d艂ugo艣膰 i adres pocz膮tku;
" msgflgmo偶e mie膰 ustawiony bitIPC_NOWAIT, oznaczaj膮cy, 偶e funk-
cja nie b臋dzie blokowana, je艣li komunikatu nie mo偶na wys艂a膰 natych-
miast;
" Wysy艂any komunikat musi mie膰 okre艣lony typ  liczba dodatnia na
samym pocz膮tku struktury przechowuj膮cej komunikat;
" Struktura zawieraj膮ca komunikat mo偶e by膰 dowolna, ale pierwsze
pole musi by膰 liczb膮 typulong, zawieraj膮c膮 typ komunikatu.
struct komunikat {
long type;
int x;
int y;
char opis[30];
}
main()
{
int mq;
struct komunikat msg={12, 1, 2, "abc");
mq=magget(123, IPC_CREAT | 0644);
msgsnd(mq, &msg, sizeof(msg), 0);
}
Sieciowe Systemu Operacyjne  UNIX 4-6
4. Kolejki komunikat贸w Odbieranie komunikat贸w
Odbieranie komunikat贸w
int msgrcv(int msqid, void *msgp, size_t msgsz,
long msgtyp, int msgflg);
Warto艣膰msgtypokre艣la jakie komunikaty mog膮 zosta膰 odebrane:
" 0  pierwszy komunikat z kolejki, dowolnego typu;
" > 0  pierwszy komunikat o podanym typie;
" < 0  spo艣r贸d komunikat贸w, kt贸rych typ jest mniejszy lub r贸wny
warto艣ci bezwzgl臋dnejmsgtyp, wybierany jest komunikat o najni偶-
szym typie (a je艣li jest ich kilka  pierwszy z nich).
Warto艣膰msgflgokre艣la spos贸b zachowania funkcji:
" je艣li ustawiony jest znacznikIPC_NOWAIT, a w kolejce nie ma 偶膮da-
nego komunikatu, funkcja wr贸ci natychmiast, zwracaj膮c warto艣膰 -1
i ustawiaj膮c zmienn膮errnonaENOMSG;
" je艣li znacznikIPC_NOWAITnie jest ustawiony, a w kolejce nie ma
偶膮danego komunikatu, funkcja powoduje u艣pienie procesu, do czasu
gdy:
 zostanie wys艂any odpowiedni komunikat;
 kolejka zostanie usuni臋ta z systemu (b艂膮dEIDRM);
 zostanie odebrany sygna艂, kt贸ry nie jest ignorowany. Komuni-
kat nie jest pobierany z kolejki, a funkcja msgrcv() zwraca b艂膮d
EINTRlub jest automatycznie restartowana  zale偶nie od opcji
ustawionych przez sigaction() (parametrSA_RESTART).
" je艣li ustawiony jest znacznikMSG_NOERROR, funkcja nie b臋dzie sy-
gnalizowa膰 b艂臋du, je艣li odbierany komunikat jest wi臋kszy ni偶 d艂ugo艣膰
przekazanego bufora, przycinaj膮c go do 偶膮danego rozmiaru, w prze-
ciwnym razie komunikat nie zostanie odebrany, a zmiennaerrno
zostanie ustawiona naE2BIG.
Sieciowe Systemu Operacyjne  UNIX 4-7
4. Kolejki komunikat贸w Selektywne przesy艂anie komunikat贸w
Selektywne przesy艂anie komunikat贸w



klient 1 klient 2 klient 3
2 7 2 3 2 15


kolejka


komunikat w
7 3
2
3
2
3
2
2
3
2
2 15
7
3
2 7
15

serwer
" klienci przesy艂aj膮 komunikaty do serwera oznaczaj膮c je typem 2 (lub
np. 1 dla danych o wy偶szym priorytecie, 2  normalnym);
" serwer odbiera wy艂膮cznie komunikaty o typie 2 (lub 1 2), a wysy艂a
komunikaty innych typ贸w;
" ka偶dy klient ma osobny numer dla komunikat贸w, kt贸re odbiera (np.
sw贸j numer procesu).
Sieciowe Systemu Operacyjne  UNIX 4-8
4. Kolejki komunikat贸w Funkcja ftok()
Funkcja ftok()
#include
key_t ftok(const char *path, int id);
Funkcja ftok() zwraca identyfikator, kt贸rego mo偶na u偶y膰 w celu utworze-
nia lub dost臋pu do istniej膮cej kolejki komunikat贸w, semafora lub segmen-
tu pami臋ci wsp贸lnej.
" U偶ycie w dw贸ch wywo艂aniach ftok() takich samych parametr贸wpath
iidpowoduje utworzenie identycznych kluczy;
" U偶ycie r贸偶nych si臋 parametr贸w powoduje wygenerowanie r贸偶nych
(unikalnych) kluczy.
" Klucz tworzony jest na podstawie numeru i-w臋z艂a podanego pliku,
wi臋c plik musi istnie膰, w przeciwnym razie ftok() zwraca warto艣膰 -1.
" Numery i-w臋z艂贸w s膮 unikalne tylko w obr臋bie jednego systemu pli-
k贸w, dlatego w celu zapewnienia unikalno艣ci klucza, u偶ywany jest
tak偶e  ma艂y numer urz膮dzenia (device minor number), na kt贸rym
znajduje si臋 plik (odpowiada to numerowi partycji dysku);
Sieciowe Systemu Operacyjne  UNIX 4-9
5. Semafory Sekcja krytyczna
Semafory
Sekcja krytyczna
Dwa procesy niezale偶nie modyfikuj膮 wsp贸ln膮 zmienn膮  a , jeden po dru-
gim:
int a,b;
500


a == 500
b=a;
b+=100;
a=b;
600
int a,c;

600

a == 600
c=a;
c+=300;
a=c;
900


a == 900
Dwa procesy niezale偶nie modyfikuj膮 wsp贸ln膮 zmienn膮  a , lecz system
operacyjny powoduje chwilowe wstrzymanie pierwszego procesu w trakcie
operacji:


500
a == 500
int a,b;
int a,c;
500
b=a;
c=a;

c+=300;
a == 800
a=b;
b+=100;
800
a=b;
600


a == 600
Sieciowe Systemu Operacyjne  UNIX 5-1
5. Semafory Sekcja krytyczna
" Od momentu pobrania warto艣ci zmiennej  a do momentu jej ode-
s艂ania 偶aden inny proces nie powinien mie膰 do niej dost臋pu
" Fragment programu potrzebuj膮cy wy艂膮czno艣ci dzia艂ania nazwiemy
sekcj膮 krytyczn膮.
int a,b;
b=a;
int a,c;
c=a;
b+=100;
c+=300;
a=b;
a=b;
Rozwi膮zanie?
static int sem=1;
Zajmij(int *wolny) Zwolnij(int *wolny)
{ {
while (*wolny<=0) *wolny++;
sleep(1); }
*wolny--;
}
main()
{
int a, b;
Zajmij(&sem); Dlaczego
b=a; to nie
b+=100; dzia艂a ?
a=b;
Zwolnij(&sem);
}
Sieciowe Systemu Operacyjne  UNIX 5-2
5. Semafory Sekcja krytyczna
To b臋dzie dzia艂a膰, je艣li operacje Zajmij () i Zwolnij () b臋d膮 niepodzielne.
int a,b;
Zajmij(s);
int a,c;
b=a;
Zajmij(s);
b+=100;
a=b;
Zwolnij(s);
c=a;
c+=300;
a=b;
Zwolnij(s);
" Operacja Zajmij () jest wej艣ciem do sekcji krytycznej  usypia pro-
ces, je艣li zas贸b ju偶 jest zaj臋ty, a偶 do momentu, gdy inny proces go
zwolni. Proces zostaje umieszczony w kolejce proces贸w oczekuj膮cych
na zwolnienie zasobu (semafora);
" Operacja Zwolnij () stanowi wyj艣cie z sekcji krytycznej  nigdy nie
usypia procesu, za to mo偶e spowodowa膰 obudzenie innego (przenie-
sienie go z kolejki oczekuj膮cych).
" Obie operacje s膮 niepodzielne (atomowe) i dzia艂aj膮 na poziomie j膮dra
systemu.



tryb u偶 k.
yt


tryb j dra.


u艣piony
gotowy
Sieciowe Systemu Operacyjne  UNIX 5-3
5. Semafory Sekcja krytyczna
Semafor mo偶emy traktowa膰 jak abstrakcyjny typ danych sk艂adaj膮cy si臋
ze zmiennej i kolejki proces贸w:
" Zajmij (S)
Je艣li S > 0, to S ! S - 1 i idz dalej.
Je艣li S = 0, to umie艣膰 proces w kolejce oczekuj膮cych na zwolnienie
semafora i za艣nij.
" Zwolnij (S)
Je艣li kolejka oczekuj膮cych jest pusta, to S ! S + 1:
Je艣li kto艣 czeka, to usu艅 go z kolejki oczekuj膮cych i obudz go, nie
zmieniaj膮c warto艣ci S.
Semafor binarny  przyjmuj膮cy jedynie warto艣ci 0 i 1.
Semafor og贸lny  przymuj膮ce dowolne (lub wybrane) warto艣ci nieujemne
" Bie偶膮ca warto艣膰 semafora odpowiada liczbie  wolnych zasob贸w;
" Osi膮gni臋cie warto艣ci 0 oznacza, 偶e kolejny proces 偶膮daj膮cy zasobu
zostanie u艣piony;
" Mo偶liwe jest zmniejszenie lub zwi臋kszenie warto艣ci semafora o war-
to艣膰 inn膮 ni偶 1 (o ile zmniejszenie nie doprowadzi艂oby do osi膮gni臋cia
warto艣ci ujemnej).
Inne przyk艂ady wymagaj膮ce ochrony dost臋pu do sekcji krytycznej:
" modyfikacja wsp贸lnej zmiennej w pami臋ci lub pliku (konto banko-
we?);
" zapis pliku przez kilka proces贸w;
" modyfikacja rekordu w bazie danych;
" dost臋p do urz膮dze艅 zewn臋trznych (terminale, modemy, itp.);
Sieciowe Systemu Operacyjne  UNIX 5-4
5. Semafory Problem pi臋ciu filozof贸w
Problem pi臋ciu filozof贸w
1
5
2
4
3
" 呕ycie filozofa to medytacje, ale to wyczerpuj膮ce zaj臋cie, wi臋c filozof
czasami robi si臋 g艂odny;
" G艂odny filozof udaje si臋 do jadalni i zajmuje miejsce przy stole;
" Filozof je tylko wtedy, gdy ma dwa widelce;
" Dw贸ch filozof贸w nie mo偶e jednocze艣nie trzyma膰 tego samego widelca;
" Najedzony filozof wychodzi z jadalni i wraca medytowa膰.
Problemy:
" 呕aden filozof nie powinien zosta膰 zag艂odzony.
" Nie mo偶na dopu艣ci膰 do blokady.
" Problem higieny pomijamy, jako nie wnosz膮cy nic do rozwi膮zania.
Sieciowe Systemu Operacyjne  UNIX 5-5
5. Semafory Tworzenie semafor贸w
Tworzenie semafor贸w
int semget(key_t key, int semflg);
Funkcja semget() tworzy nowy zbi贸r semafor贸w lub znajduje ju偶 istnie-
j膮cy:
" Je艣li klucz ma warto艣膰 IPC_PRIVATE, zawsze jest tworzony nowy
zbi贸r semafor贸w;
" Je艣li semafor o podanym kluczu ju偶 istnieje, zostaje zwr贸cony jego
identyfikator, o ile u偶ytkownik ma odpowiednie prawa dost臋pu do
niego, w przeciwnym razie zwracany jest (poprzez zmienn膮errno)
b艂膮dENOENT;
" Je艣li semafor nie istnieje, a w艣r贸d opcji semflg ustawiona by艂a
IPC_CREAT, zostaje utworzony nowy semafor i zwr贸cony jego iden-
tyfikator;
" U偶ycie opcjiIPC_EXCLwymusza utworzenie nowego semafora  je偶eli
by艂y ustawione obie opcje:IPC_CREATiIPC_EXCL, a semafor ju偶
istnia艂, zostaje zwr贸cony b艂膮dEEXIST.
Je艣li tworzony jest nowy semafor, najm艂odsze 9 bit贸w w opcjach oznacza
prawa dost臋pu do tworzonego semafora, np. 0644 albo 0666.
#include
#include
#include
#define KEY ((key_t) 12345L)
#define PERM 0600
main()
{
int semid;
if ( (semid=semget(KEY, PERM | IPC_CREAT)) < 0) {
fprintf(stderr, "Nie mo偶na utworzy膰 semafora\n");
exit (1);
}
...
}
Sieciowe Systemu Operacyjne  UNIX 5-6
5. Semafory Usuwanie semafor贸w
Usuwanie semafor贸w
int semctl(int semid, int semnum, int cmd, union semun arg);
union semun {
int val;
struct semid_ds *buf;
ushort_t *array;
} arg ;
Funkcja semctl() pozwala usun膮膰 semafor, ale tak偶e wykona膰 na nim
r贸偶ne operacje. Spos贸b dzia艂ania zale偶y od parametrucmd, a parametr
semnumokre艣la numer semafora w grupie, kt贸rego dotyczy operacja (przy
pierwszych 3 operacjach, dotycz膮cych ca艂ej grupy, ten parametr jest nie-
istotny):
" IPC_STAT umieszcza dane o semaforze (takie jak w艂a艣ciciel, prawa
dost臋pu, itp.) w strukturze wskazywanej przezbuf;
" IPC_SET zmienia parametry grupy semafor贸w na parametry prze-
kazane w strukturze wskazywanej przezbuf. Zmienione mog膮 zosta膰:
w艂a艣ciciel i grupa (o ile wo艂aj膮cy proces ma uid=0 lub taki sam, jak
proces, kt贸ry utworzy艂 semafor) i prawa dost臋pu do semafora.
" IPC_RMID usuwa grup臋 semafor贸w z systemu.
" GETVAL pobiera i zwraca warto艣膰 semaforasemnum;
" SETVAL  ustawia warto艣膰 semafora semnum na warto艣膰 val unii
semunprzekazanej jako argumentarg;
Polecenia systemowe zwi膮zane z semaforami
" ipcrm usuwa semafor (grup臋 semafor贸w) z systemu;
" ipcs -s sprawdza status semafora.
Sieciowe Systemu Operacyjne  UNIX 5-7
5. Semafory Zajmowanie i zwalnianie semafor贸w
Zajmowanie i zwalnianie semafor贸w
int semop(int semid, struct sembuf *sops, size_t nsops);
struct sembuf {
short sem_num; /* numer semafora */
short sem_op; /* operacja na semaforze */
short sem_flg; /* opcje */
}
Og贸lnie:
" sem_op< 0  zaj臋cie semafora
" sem_op> 0  zwolnienie semafora
" sem_op== 0  synchronizacja z semaforem (oczekiwanie, a偶 jego
warto艣膰 osi膮gnie 0)
Opcjesem_flg:
" IPC_NOWAIT
Je偶eli nie mo偶na wykona膰 偶膮danej operacji, proces nie zostaje u艣pio-
ny, lecz funkcja wraca z b艂臋demEAGAIN
" SEM_UNDO
Je偶eli semafor zostaje przydzielony, liczba, o jak膮 zosta艂a zmniejszo-
na jego warto艣膰, zostaje dodana do zmiennejsemadjprocesu (a przy
zwalnianiu semafora  odj臋ta od tej zmiennej).
Je艣li proces zostaje zako艅czony z niezerow膮 warto艣ci膮semadj(np.
po otrzymaniu sygna艂u itp.), funkcja exit() spowoduje dodanie tej
zmiennej do warto艣ci semafora (czyli zwolnienie zaj臋tych zasob贸w).
Sieciowe Systemu Operacyjne  UNIX 5-8
5. Semafory Zaj臋cie semafora
Zaj臋cie semafora
struct sembuf op_zajm={
0, /* semafor nr 0 */
-1, /* zajmij == odejmij warto艣膰 N (tutaj: 1) */
0 /* opcje */
};
int semid;
semid=semget(IPC_PRIVATE, 1, IPC_CREAT);
if (semid==-1)
... (b艂膮d) ...
semop(semid, &op_zajm, 1);
/* sekcja krytyczna */
Algorytm zajmowania semafora (N < 0):
" je艣li warto艣膰 semafora jest wi臋ksza lub r贸wna warto艣ci bezwzgl臋dnej
N, to zmniejsz j膮 o tyle (a je艣li u偶yto opcjiSEM_UNDO, to dodatkowo
zwi臋ksz o |N| zmienn膮semadj).
" je艣li nie, i nie zosta艂a u偶yta opcjaIPC_NOWAIT, zwi臋ksz licznik pro-
ces贸w oczekuj膮cych na semafor i zawie艣 proces, a偶 do czasu, gdy
nast膮pi jedno ze zdarze艅:
 zostanie spe艂niony ten warunek. W贸wczas warto艣膰 semafora jest
pomniejszana o |N| (i ew. zwi臋kszana o |N| warto艣膰semadj),
zmniejszany jest licznik proces贸w oczekuj膮cych, a proces zostaje
obudzony.
 semafor zostanie usuni臋ty z systemu;
 proces otrzyma sygna艂 (funkcja zwr贸ci b艂膮dEINTRlub zostanie
automatycznie wznowiona).
" je艣li nie by艂o mo偶liwe zaj臋cie semafora, ale u偶yto opcjiIPC_NOWAIT,
wr贸膰 natychmiast z b艂臋demEAGAIN.
Sieciowe Systemu Operacyjne  UNIX 5-9
5. Semafory Zwolnienie semafora
Zwolnienie semafora
struct sembuf op_tab[2]={
0, /* semafor nr 0 */
-1, /* zajmij == odejmij warto艣膰 N (tutaj: 1) */
0 /* opcje */
}, {
0, /* semafor nr 0 */
1, /* zwolnij == dodaj warto艣膰 N (tutaj: 1) */
0 /* opcje */
};
int semid;
semid=semget(IPC_PRIVATE, 1, IPC_CREAT);
if (semid==-1)
... (b艂膮d) ...
semop(semid, op_tab, 1);
/* sekcja krytyczna */
/* ... */
semop(semid, &(op_tab[1]), 1);
Algorytm zwalniania semafora przez system operacyjny (N > 0):
" warto艣膰 semafora zostaje zwi臋kszona o N,
" je艣li ustawiona jest opcjaSEM_UNDO, warto艣膰 ta jest r贸wnie偶 odejmo-
wana od zmiennejsemadjprocesu zwi膮zanej z tym semaforem,
" je艣li licznik proces贸w oczekuj膮cych na semafor ma warto艣膰 wi臋ksz膮
od zera, zostaje obudzony pierwszy proces z kolejki.
Sieciowe Systemu Operacyjne  UNIX 5-10
5. Semafory Oczekiwanie na zaj臋cie semafora przez inny proces
Oczekiwanie na zaj臋cie semafora przez inny proces
Je艣li warto艣膰 N jest r贸wna 0, proces oczekuje a偶 semafor zostanie zaj臋ty
przez inny proces:
" je艣li warto艣膰 semafora wynosi 0, funkcja semop() wraca natychmiast;
" je艣li warto艣膰 semafora jest wi臋ksza od 0, ale u偶yto opcjiIPC_NOWAIT,
funkcja natychmiast wraca z b艂臋demEAGAIN;
" je艣li warto艣膰 semafora jest wi臋ksza od 0 i nie u偶yto opcjiIPC_NOWAIT,
zostaje zwi臋kszona warto艣膰 semzcnt semafora, a proces zostaje
u艣piony, do czasu, gdy:
 warto艣膰 semafora (semval) osi膮gnie zero;
 semafor zostanie usuni臋ty z systemu;
 proces otrzyma sygna艂, kt贸ry ma zosta膰 przechwycony. W贸wczas
warto艣膰semzcntjest zmniejszana i wo艂ana procedura obs艂ugi
sygna艂u zarejestrowana wcze艣niej wywo艂aniem funkcji signal().
Zastosowania dla tego typu post臋powania:
" Rozwi膮zanie problemu wy艣cigu podczas inicjowania warto艣ci sema-
fora.
" Synchronizacja z procesem 偶膮daj膮cym dost臋pu do zasobu (jednocze-
sna operacja typu  czekaj, a偶 osi膮gnie 0, a gdy si臋 to stanie, zwolnij ).
Sieciowe Systemu Operacyjne  UNIX 5-11
6. Pami臋膰 wsp贸lna Stronicowanie pami臋ci
Pami臋膰 wsp贸lna
Stronicowanie pami臋ci
" Adresy wkompilowane w programy nie mog膮 by膰 adresami pami臋-
ci fizycznej, bo nie by艂oby mo偶liwe wsp贸艂bie偶ne wykonywanie kilku
proces贸w.
" Kompilatory generuj膮 kod operuj膮cy w wirtualnej przestrzeni ad-
resowej (ograniczonej z g贸ry, np. do 4GB), a t艂umaczenia adres贸w
wirtualnych na rzeczywiste dokonuje jednostka MMU procesora.
" System mo偶e wykonywa膰 kilka kopii tego samego programu, operu-
j膮cego tymi samymi adresami pami臋ci wirtualnej, wi臋c t艂umaczenie
adres贸w wirtualnych na fizyczne jest 艣ci艣le zwi膮zane z kontekstem
procesu.
" Pami臋膰 wirtualna uzyskiwana jest przez segmentacj臋 i stronicowanie.
Jednostkowym obszarem pami臋ci jest strona, zwykle wielko艣ci od 8
do 32 kB (sta艂y rozmiar zale偶ny od systemu).

pamiR fi
zyczna

8C000000
obszar
nr s ro off
t ny set



pro 20 bi
cesu
t 12 bi
t
8CF19000
0 0 1 A 7 3 F 0







tablica s ro
t n
8F345000 RWX
8CF1A000
8CF04000 R-- 3F0
1A7
81212000 R--
8DD22000 R-X
... RWX
8CF1A000 RW-
8CF1B000 RW-
8CF1B000
Sieciowe Systemu Operacyjne  UNIX 6-1
s
t
r
o
p
n
a
a
m
i
R
c
i
6. Pami臋膰 wsp贸lna Segmentacja pami臋ci
Segmentacja pami臋ci
W rzeczywisto艣ci dost臋p do pami臋ci jest troch臋 bardziej skomplikowany.
Dost臋p do pami臋ci fizycznej odbywa si臋 w pierwszym rz臋dzie poprzez
segmenty (danych, kodu, stosu), a dopiero potem  strony:


pamiR fi
zyczna

8C000000
obszar segment i nr s ro set
t ny off



pro
cesu
20 bi 12 bi
t t
8CF19000
0 0 1 A 7 3 F 0

tablica s ro
t n
8CF04000 R--
81212000 R--
... ...
8CF1A000

tablica seg ent贸w
m
8CF1A000 RW- 3F0


8CF1B000 RW-
k od
od
k



ddane
ane
8F345000 RWX

8DD22000 R-X
sstos
tos
... ...
8CF1B000
8CF1B000 R-X
8FAA5000 RW-
8FAA6000 RW-
... ...
8FAD1000 RW-
" Ka偶dy segment posiada w艂asn膮 tablic臋 stron (adres tablicy i jej d艂u-
go艣膰);
" segment reprezentuje ci膮g艂y obszar pami臋ci;
" przy ka偶dym dost臋pie do pami臋ci starsza cz臋艣膰 adresu wyznacza u偶y-
wany segment, a jednocze艣nie jest por贸wnywana z jego wielko艣ci膮,
w celu wykrycia dost臋pu poza przydzielony segment;
" starsza cz臋艣膰 adresu wyznacza indeks w tablicy stron segmentu i po-
zwala odczyta膰 adres strony pami臋ci fizycznej;
" ostateczny adres powstaje przez zsumowanie adresu strony i offsetu.
Sieciowe Systemu Operacyjne  UNIX 6-2
6. Pami臋膰 wsp贸lna Tworzenie segmentu pami臋ci wsp贸lnej
Tworzenie segmentu pami臋ci wsp贸lnej
int shmget(key_t key, int size, int shmflg);
Funkcja shmget() tworzy nowy segment pami臋ci wsp贸lnej lub znajduje
ju偶 istniej膮cy:
" Je艣li klucz ma warto艣膰IPC_PRIVATE, tworzony jest nowy segment;
" Je艣li segment o podanym kluczu ju偶 istnieje, zostaje zwr贸cony jego
identyfikator, o ile u偶ytkownik ma odpowiednie prawa dost臋pu do
niego, w przeciwnym razie zwracany jest (poprzez zmienn膮errno)
b艂膮dENOENT;
" Je艣li segment pami臋ci wsp贸lnej nie istnieje, a w艣r贸d opcjishmflg
ustawiona by艂aIPC_CREAT, zostaje utworzony nowy blok pami臋ci
i zwr贸cony jego identyfikator;
" U偶ycie opcjiIPC_EXCLwymusza utworzenie nowego segmentu pa-
mi臋ci  je偶eli by艂y ustawione obie opcje:IPC_CREATiIPC_EXCL, a
segment ju偶 istnia艂, zostaje zwr贸cony b艂膮dEEXIST.
Je艣li tworzony jest nowy segment pami臋ci, najm艂odsze 9 bit贸w w opcjach
oznacza prawa dost臋pu do tworzonego bloku pami臋ci, np. 0644 albo 0666.
#include
#include
#include
#define KEY ((key_t) 12345L)
#define PERM 0600
#define SIZE 4096
main()
{
int shmid;
if ( (shmid=shmget(KEY, SIZE, PERM | IPC_CREAT)) < 0) {
fprintf(stderr, "Nie mo偶na utworzy膰 bloku pami臋ci wsp贸lnej\n");
exit (1);
}
...
}
Sieciowe Systemu Operacyjne  UNIX 6-3
6. Pami臋膰 wsp贸lna Usuwanie pami臋ci wsp贸lnej
Usuwanie pami臋ci wsp贸lnej
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
Funkcja shmctl() pozwala usun膮膰 segment pami臋ci wsp贸lnej, ale tak偶e
wykona膰 na nim r贸偶ne operacje. Spos贸b dzia艂ania zale偶y od parametru
cmd:
" IPC_STAT umieszcza dane o bloku pami臋ci (takie jak w艂a艣ciciel,
prawa dost臋pu, itp.) w strukturze wskazywanej przezbuf;
" IPC_SET zmienia parametry segmentu pami臋ci wsp贸lnej na para-
metry przekazane w strukturze wskazywanej przezbuf. Zmienione
mog膮 zosta膰: w艂a艣ciciel i grupa (o ile wo艂aj膮cy proces mauid==0
lub taki sam, jak proces, kt贸ry utworzy艂 segment pami臋ci wsp贸lnej)
i prawa dost臋pu do segmentu.
" IPC_RMID usuwa segment pami臋ci wsp贸lnej z systemu.
" SHM_LOCK  zablokowanie w pami臋ci segmentu pami臋ci wsp贸lnej
(operacja mo偶e by膰 wykonana wy艂膮cznie przez u偶ytkownika posia-
daj膮cegoeuid==0);
" SHM_UNLOCK odblokowanie segmentu.
Polecenia systemowe zwi膮zane z pami臋ci膮 wsp贸ln膮:
" ipcrm usuwa segment pami臋ci wsp贸lnej z systemu;
" ipcs -m sprawdza status pami臋ci wsp贸lnej w systemie.
Sieciowe Systemu Operacyjne  UNIX 6-4
6. Pami臋膰 wsp贸lna Korzystanie z pami臋ci wsp贸lnej
Korzystanie z pami臋ci wsp贸lnej
Zanim proces b臋dzie m贸g艂 odczyta膰 co艣 z pami臋ci wsp贸lnej lub do niej za-
pisa膰, musi za偶膮da膰 od systemu do艂膮czenia segmentu pami臋ci wsp贸lnej do
w艂asnej przestrzeni adresowej (widz膮c jakby przez  okienko swojej pa-
mi臋ci, segment pami臋ci wsp贸lnej). Po zako艅czeniu korzystania z pami臋ci
wsp贸lnej, proces powinien od艂膮czy膰 j膮 od swojej przestrzeni adresowej.
S艂u偶膮 do tego odpowiednio funkcje shmat() i shmdt().
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
Funkcja shmat() zwraca adres przy艂膮czonego segmentu. Adres ten zale偶y
od u偶ytych parametr贸wshmaddrishmflg:
" Je艣lishmaddr==NULL(czyli(void*)0), to przydzielany jest pierwszy
wolny adres znaleziony przez system;
" Je艣lishmaddrjest niezerowy, w贸wczas system pod艂膮cza segment pa-
mi臋ci wsp贸lnej pod podanym adresem, chyba 偶e zosta艂a u偶yta tak偶e
opcjaSHM_RND, w贸wczas adres zostaje wyr贸wnany w d贸艂, do najbli偶-
szego adresu podzielnego przezSHMLBA.
" U偶ycie opcjiSHM_RDONLYpowoduje pod艂膮czenie pami臋ci w trybie
wy艂膮cznie do odczytu, w przeciwnym razie dost臋p jest do czytania
i pisania.
Funkcja shmdt() od艂膮cza od przestrzeni adresowej procesu segment pa-
mi臋ci wsp贸lnej wskazywany przezshmaddr.
Sieciowe Systemu Operacyjne  UNIX 6-5
6. Pami臋膰 wsp贸lna Zarz膮dzanie segmentami pami臋ci przez system
Zarz膮dzanie segmentami pami臋ci przez system
Przydzielanie segmentu pami臋ci:
Nowy segment mo偶e zosta膰 przydzielony programowi tylko w kilku wy-
padkach:
" Tworzenie nowego procesu za pomoc膮 funkcji fork()
" Zwolnienie wszystkich segment贸w procesu i przydzia艂 nowych
w chwili wykonania exec()
" Przydzia艂 segmentu pami臋ci wsp贸lnej za pomoc膮 shmget()
Przy艂膮czenie przydzielonych segment贸w do procesu:
" Nowo tworzony proces: fork(), exec()
" Segment pami臋ci wsp贸lnej: shmdt()
Zmiana rozmiaru segmentu:
" Segmenty prywatne: automatycznie, funkcj膮 sbrk()
" Segmenty wsp贸lne: nigdy
Od艂膮czanie segment贸w od procesu:
" Segmenty prywatne: exit() i exec()
" Segmenty wsp贸lne: shmdt()
Zwalnianie segment贸w:
" Segmenty prywatne: dokonywane automatycznie w chwili, gdy seg-
ment przestaje by膰 do艂膮czony do jakiegokolwiek procesu (o ile nie
by艂 ustawiony sticky bit  rwxr-xr-t).
" Segmenty wsp贸lne: po wykonaniu shmctl(IPCRMID)
Sieciowe Systemu Operacyjne  UNIX 6-6
6. Pami臋膰 wsp贸lna Pami臋膰 wsp贸lna widziana przez 2 procesy
Pami臋膰 wsp贸lna widziana przez 2 procesy

pamiR fi
zyczna

pro 1
ces


8C000000
nr s ro off
t ny set


20 bi 12 bi
t t
0 0 1 A 7 3 F 0
8CF17000

tablica s ro
t n
8F345000 RWX
8CF04000 R--
1A7
81212000 R--
8CF18000
8DD22000 R-X
... ...
8CF1A000 RW-
8CF1B000 RW-
8CF19000

pro 2
ces

8CF1A000
nr s ro off
t ny set
3F0


20 bi 12 bi
t t
0 0 1 0 E 3 F 0
8CF1B000

tablica s ro
t n
8F355000 R-X
10E
... ...
8CF1A000 RW-
8DC10000 RW-
8CFD4000 RW-
8CFBB000 R--
8CFA0000 R--
Sieciowe Systemu Operacyjne  UNIX 6-7
6. Pami臋膰 wsp贸lna Wsp贸lny dost臋p do plik贸w  mmap()
Wsp贸lny dost臋p do plik贸w  mmap()
#include
void *mmap(void *addr, size_t len, int prot, int flags,
int fildes, off_t off);
Funkcja mmap() pozwala na dost臋p do otwartych plik贸w tak, jakby znaj-
dowa艂y si臋 w pami臋ci RAM  zamiast porusza膰 si臋 po pliku za pomoc膮
fseek() i pisa膰/czyta膰 przez fread() i fwrite(), mo偶na u偶ywa膰 wskaznik贸w
i zwyk艂ych operacji przypisania.
" addr preferowany adres w pami臋ci (je艣liNULL system przydzieli
adres ni ekoliduj膮cy z dotychczas przydzielonymi segmentami);
" len wielko艣膰 obszaru;
" prot jedna lub kilka opcji po艂膮czonych logicznym  or :PROT_READ,
PROT_WRITE,PROT_EXEC,PROT_NONE(w niekt贸rych systemach cz臋艣膰
z kombinacji jest niedost臋pna, np. write+exec);
" flags opcje dotycz膮ce mapowanych danych, m.in.:
 MAP_SHARED zmiany s膮 dokonywane wsp贸lnie z innymi proce-
sami;
 MAP_PRIVATE zmiany s膮 dokonywane na prywatnej kopii da-
nych (pierwsza pr贸ba zapisu powoduje utworzenie kopii);
" fildes deskryptor otwartego uprzednio pliku (musi to by膰  zwy-
k艂y plik, nie mo偶e by膰 gniazdko, FIFO, urz膮dzenie itp.);
" off przesuni臋cie mapowanego obszaru wzgl臋dem pocz膮tku pliku.
Inne funkcje: munmap(), msync().
Sieciowe Systemu Operacyjne  UNIX 6-8
6. Pami臋膰 wsp贸lna Pami臋膰 wirtualna
Pami臋膰 wirtualna
W rzeczywisto艣ci dost臋p do pami臋ci jest troch臋 bardziej skomplikowany.
(Deja Vu  to takie dziwne uczucie, ...)

pamiR fi
zyczna

8C000000
obszar segment i nr s ro off
t ny set


pro
cesu
20 bi 12 bi
t t
8CF19000
0 0 1 A 7 3 F 0

tablica s ro
t n
8CF04000 R--V 2
41212000 R--- 0
... ...
8CF1A000

tablica seg ent贸w
m
8CF1A000 RW-V 3 3F0


8CF1B000 RW-V 1
k od
od
k



ddane
ane
8F345000 RWXV 1

8DD22000 R-XV 2
sstos
tos
... ...
8CF1B000
8CF1B000 R-XV 1
8FAA5000 RW-V 3
8FAA6000 RW-V 1
... ...
8FAD1000 RW-V 1


plik w i
ym any

sw ap
" Tablica stron mo偶e zawiera膰 informacje o stronach, kt贸rych nie ma
w pami臋ci fizycznej;
" w chwili dost臋pu do takiej strony generowany jest wyj膮tek powo-
duj膮cy zachowanie kontekstu procesu, ew. przeniesienie do kolejki
proces贸w oczekuj膮cych na sprowadzenie strony z pami臋ci swap, oraz
sprowadzenie strony, po czym wznowienie procesu tak, jakby nic si臋
nie sta艂o;
" Dodatkowo tablica zawiera licznik odwo艂a艅, automatycznie zmniej-
szany, a s艂u偶膮cy do szukania stron, kt贸re mog膮 by膰 wyrzucone do
pami臋ci swap.
Sieciowe Systemu Operacyjne  UNIX 6-9
6. Pami臋膰 wsp贸lna Pe艂ny diagram stan贸w proces贸w
Pe艂ny diagram stan贸w proces贸w



tryb u偶 k.
yt

przerwanie







exit()



zombie tryb j dra. wyw艂a zcz.
膮 s


kill()
wyw艂as cz.
z




obud enie
z


u艣piony
gotowy

fork()

utworzony

swap-out


swap-in


u艣piony/
swap
gotowy/swap
Sieciowe Systemu Operacyjne  UNIX 6-10
p
o
w
r

t
a
c

j
u
k
o
l
b
.
f
7. Komunikacja sieciowa
Komunikacja sieciowa
R贸偶ne rodzaje sieci:
" sieci broadcastowe
" sieci token ring i FDDI
" po艂膮czenia punkt-punkt (point-to-point)


host1 host2 host3




Ethernet
host12


host4

10base5
host5



host11 host13
hub


Ethernet 10base2


Ethernet


10BaseT




host14

host6

host5



host10
host7

Token Ring




host9
host8



host16

PPP/SLIP
" nawet w obr臋bie sieci lokalnych stosowane s膮 r贸偶ne technologie, np.
Ethernet 10baseT (skr臋tka), 10base5 (kabel koncentryczny 50&!),
10base2 ( gruby ethernet)
" pojedyncze sieci lokalne 艂膮czone s膮 ze sob膮 albo przez komputery
z dwoma interfejsami sieciowymi, pe艂ni膮cymi zwykle rol臋 router贸w,
albo specjalne urz膮dzenia  huby, switche, routery.
" sie膰 ethernet jest sieci膮 typu broadcast, sieci kom贸rkowe te偶;
Sieciowe Systemu Operacyjne  UNIX 7-1
7. Komunikacja sieciowa
" zacz臋艂o si臋 od  Aloha network  pakietowej sieci radiowej na Ha-
wajach w latach  70:
_T__
(_.  -{


host1


host2




host3
Dostarczanie pakiet贸w:
" wszyscy s艂uchaj膮 rozg艂aszanych pakiet贸w, wi臋c ka偶dy pakiet musi
mie膰 adres docelowy i adres nadawcy, np. unikalny numer przypisany
komputerowi;
" je艣li pakiet do kogo innego  wyrzu膰 (ethernet  dokonywane na
poziomie sprz臋tu, bez generowania niepotrzebnego przerwania);
" problem z poufno艣ci膮  ka偶dy mo偶e pods艂uchiwa膰!
Sieciowe Systemu Operacyjne  UNIX 7-2
N
W
E
S
7. Komunikacja sieciowa
_T__
(_.  -{


host1

host2



host3
Dost臋p do medium:
" wsp贸lny zas贸b  co b臋dzie, gdy 2 stacje zaczn膮 nadawa膰 jednocze-
艣nie?  trzeba wykrywa膰 jako艣 na艂o偶enie si臋 pakiet贸w, czyli kolizje
" nadawaj w ciemno, ale dodaj sum臋 kontroln膮
" suma kontrolna i tak si臋 przyda  na wypadek nisko przelatuj膮cych
samolot贸w
" je艣li dosta艂e艣 nieuszkodzony pakiet  ode艣lij potwierdzenie
" co b臋dzie, je艣li potwierdzenie nie dotrze?
" nadawca czeka jaki艣 czas i retransmituje to, co wys艂a艂 wcze艣niej
" je艣li nast膮pi kolizja, ka偶dy z nadawc贸w spr贸buje po chwili ponownie
wys艂a膰 pakiet
Skalowalno艣膰:
" co b臋dzie, gdy zwi臋kszy si臋 ruch lub liczba stacji?
" ograniczony zasi臋g  konieczno艣膰 retransmisji przez niekt贸re stacje
pakiet贸w dla innych stacji
Sieciowe Systemu Operacyjne  UNIX 7-3
N
W
E
S
7. Komunikacja sieciowa Sie膰 ethernet  warstwa 2
Model OSI/ISO
W celu umo偶liwienia wsp贸艂dzia艂ania wielu r贸偶nych implementacji proto-
ko艂贸w sieciowych i wykorzystania r贸偶nych medi贸w transmisyjnych, stwo-
rzono warstwowy model OSI/ISO:



7 zastosowa膰



6 prezentacji


5 sesji


4 transportowa

3 sieciowa

2 !  cza

1 fizyczna
Sie膰 ethernet  warstwa 2
" Metoda dost臋pu  CSMA/CD (Carrier Sense Multiple Access with
Collision Detection)
" Adresowanie  ka偶da karta sieciowa ma sw贸j adres  6-bajtow膮 liczb臋
(pierwsze 3 bajty przypisane do producenta, np.08:00:20 Sun,
00:e0:63 Cabletron, itd.)
" AdresFF:FF:FF:FF:FF:FFjest adresem specjalnym  broadcast
" Karta sieciowa odbiera pakiety tylko wtedy, gdy zawieraj膮 jej adres
lub adres broadcast (pozosta艂e ignoruje).


odbiorc nad typ CRC
a awca




nag! w k e h rn tre艣 p ki suma k rol
e t e et a etu ont na
Sieciowe Systemu Operacyjne  UNIX 7-4
7. Komunikacja sieciowa TCP/UDP  warstwa 4
Protoko艂y sieciowe IP  warstwa 3
" wewn膮trz ramek ethernet zawarte s膮 pakiety IP:




nag! w k IP tre艣 p ki
e a etu

nad odb TCP


odbiorc nad typ CRC
a awca




nag! w k e h rn tre艣 p ki suma k rol
e t e et a etu ont na
" nag艂贸wek IP zawiera: adres IP nadawcy i odbiorcy, typ pakietu, TTL,
numer protoko艂u, identyfikator pakietu, opcje, d艂ugo艣膰, itp.  艂膮cznie
20 bajt贸w.
" adresy: 32-bitowe (4 bajty)
" typ protoko艂u: wersja 4 (IPv4)
" numer protoko艂u: TCP, UDP, ICMP
" TTL  Time To Live  maksymalny czas 偶ycia pakietu
" identyfikator pakietu  pozwala wykry膰 duplikaty lub zgubienie pa-
kietu
" fragmentacja  czy wyst臋puje, czy ostatni fragment, offset od po-
cz膮tku
TCP/UDP  warstwa 4
" Numer portu nadawcy i odbiorcy
" D艂ugo艣膰 pakietu
" Suma kontrolna TCP/UDP
" Opcje TCP
" Numer pakietu TCP i potwierdzenie pakietu drugiej strony
Sieciowe Systemu Operacyjne  UNIX 7-5
7. Komunikacja sieciowa Przyk艂adowy pakiet
Przyk艂adowy pakiet
ETHER: ----- Ether Header -----
ETHER: Packet 16 arrived at 0:58:9.26
ETHER: Packet size = 106 bytes
ETHER: Destination = ff:ff:ff:ff:ff:ff, (broadcast)
ETHER: Source = 0:e0:63:4:40:c0, Cabletron
ETHER: Ethertype = 0800 (IP)
ETHER:
IP: ----- IP Header -----
IP: Version = 4
IP: Header length = 20 bytes
IP: Type of service = 0x00
IP: xxx. .... = 0 (precedence)
IP: ...0 .... = normal delay
IP: .... 0... = normal throughput
IP: .... .0.. = normal reliability
IP: Total length = 92 bytes
IP: Identification = 35629
IP: Flags = 0x0
IP: .0.. .... = may fragment
IP: ..0. .... = last fragment
IP: Fragment offset = 0 bytes
IP: Time to live = 1 seconds/hops
IP: Protocol = 17 (UDP)
IP: Header checksum = a551
IP: Source address = 156.17.40.65, hop.ict.pwr.wroc.pl
IP: Destination address = 156.17.40.95, 156.17.40.95
IP: No options
IP:
UDP: ----- UDP Header -----
UDP: Source port = 520
UDP: Destination port = 520 (RIP)
UDP: Length = 72
UDP: Checksum = 1099
UDP:
RIP: ----- Routing Information Protocol -----
RIP: Opcode = 2 (route response)
RIP: Version = 1
RIP:
RIP: Address Port Metric
RIP: 156.17.42.160 NET-42-160.ict.pwr.wroc.pl 0 1
RIP: 156.17.40.192 156.17.40.192 0 1
RIP: 156.17.30.64 156.17.30.64 0 1
0: ffff ffff ffff 00e0 6304 40c0 0800 4500 ........c.@...E.
16: 004c 8b2d 0000 0111 a551 9c11 2841 9c11 ...-.....Q..(A..
32: 285f 0208 0208 0098 1099 0201 0000 0002 (_..............
48: 0000 9c11 2aa0 0000 0000 0000 0000 0000 ....*...........
80: 0001 0002 0000 9c11 28c0 0000 0000 0000 ........(.......
96: 0000 0000 0001 0002 0000 9c11 1e40 0000 .............@..
112: 0000 0000 0000 0000 0001 ..........
Sieciowe Systemu Operacyjne  UNIX 7-6
7. Komunikacja sieciowa Adresy w sieciach IP
Adresy w sieciach IP
Ka偶dy komputer musi mie膰 sw贸j adres w sieci, je艣li ma by膰 osi膮galny
Adres internetowy to 32-bitowa liczba, podzielona zwykle na oktety i za-
pisywana w notacji xxx.xxx.xxx.xxx. Ka偶dy adres nale偶y do jakiej艣 klasy
 A, B, C, D lub E:
Klasa A:
0 1 7 8 31
0
net host
Klasa B:
0 1 2 15 16 31
1 0
net host
Klasa C:
0 2 3 23 24 31
1 1 0
net host
" Klasa A  Adresy 0.x.x.x 127.x.x.x, maska 255.0.0.0
" Klasa B  Adresy 128.0.x.x 191.255.x.x, maska 255.255.0.0
" Klasa C  Adresy 192.0.0.x 223.255.255.x, maska 255.255.255.0
" Klasa D  Adresy 224.0.0.x 239.255.255.x  multicasting
" Klasa E  Adresy 240.0.0.x 255.255.255.x  eksperymentalne
Adresy do prywatnego wykorzystania: (RFC 1918)
" 10.0.0.0 - 10.255.255.255 (10/8)
" 172.16.0.0 - 172.31.255.255 (172.16/12)
" 192.168.0.0 - 192.168.255.255 (192.168/16)
Sieciowe Systemu Operacyjne  UNIX 7-7
7. Komunikacja sieciowa Maski sieciowe i routing
Maski sieciowe i routing
W obr臋bie klasy mo偶na dokonywa膰 dodatkowych podzia艂贸w na podsieci,
np. przyjmuj膮c zaw臋偶on膮 mask臋. (RFC 950)


Dw ziomo hierarchia p dzia! na kla :
upo wa o u sy


prefik si i adre h
s ec s osta


Tr j ziomo hierarchia p dzia! b zkla :
po wa o u e sowego


prefik si i adre p d i i adre h
s ec s o s ec s osta
" taki podzia艂 na podklasy (ang: subnetting) pozwala na logiczn膮 i fi-
zyczn膮 segmentacj臋 sieci  lokalnej
" Przyk艂ad: w sieci WASK o adresie klasy B 156.17.x.x przyj臋to mask臋
podsieci 255.255.255.224, czyli 27 bit贸w na adres sieci, 5 bit贸w na
adres hosta.
Prefiks klasy B
Maska klasy B:
255.255.0.0 11111111.11111111.00000000.000 00000
Maska podsieci: | | | | |
255.255.255.224: 11111111.11111111.11111111.111 00000
156.17.33.34 10011100.00010001.00100001.001 00010
|<---------------------------->|<--->|
podsie膰 host
" W jednej podsieci mieszcz膮 si臋 32 adresy IP.
" Zawsze istnieje 8 podsieci o takich samych 3 pierwszych oktetach
(podsieci 0, 32, 64, 96, 128, 160, 192 i 224).
" Adres hosta z samymi zerami jest adresem zarezerwowanym (adres
sieci)
" Adres hosta z samymi jedynkami to adres  broadcast
" Efektywnie pozostaje 30 adres贸w do wykorzystania. W kolejnych
podsieciach b臋d膮 to odpowiednio: 1-30, 33-62, 65-94, 97-126, 129-
158, 161-190, 193-222, 225-254.
Sieciowe Systemu Operacyjne  UNIX 7-8
7. Komunikacja sieciowa Odwzorowanie adres贸w warstw 2 i 3
Odwzorowanie adres贸w warstw 2 i 3
" Chc膮c wys艂a膰 pakiet IP do komputera znajduj膮cego si臋 w sieci lo-
kalnej, stacja wysy艂aj膮ca musi w nag艂贸wku ramki ethernet umie艣ci膰
6-bajtowy adres karty sieciowej odbiorcy.
" Sk膮d dowiedzie膰 si臋 jaki to adres, je艣li znamy tylko adres IP?
" T艂umaczeniem adres贸w warstwy 2 (ethernet) na adresy warstwy 3
(IP) i odwrotnie zajmuj膮 si臋 specjalne protoko艂y sieciowe  ARP
(Address Resolution Protocol) i RARP (Reverse ARP);
" stacja wysy艂a zapytanie ARP-Request b臋d膮ce pakietem broadcast
z zapytaniem ARP o adres IP:
tre艣膰 pakietu
****** nadawca typ dane CRC
nad *** ARP typ opcje
nag艂贸wek ethernet nag艂贸wek IP nag艂贸wek ARP suma kontrolna
" pakiet odbieraj膮 wszystkie komputery w segmencie lokalnym, a w艂a-
艣ciwy odpowiada na niego, ze swoim adresem karty ethernet w polu
nadawcy (typ pakietu: ARP-response);
" odpowiedzie膰 mog膮 tak偶e inne urz膮dzenia (np. switch),  podszywa-
j膮c si臋 z adresem w艂a艣ciwego nadawcy  proxy ARP;
" inicjator zapytania zapami臋tuje poznane t艂umaczenie IP-ethernet na
jaki艣 czas (15-30 minut), by nie wysy艂a膰 ci膮gle zapyta艅 ARP;
" RARP  inicjowany w celu dowiedzenia si臋 z serwera w艂asnego adresu
IP (np. podczas bootowania stacji bezdyskowych).
Sieciowe Systemu Operacyjne  UNIX 7-9
7. Komunikacja sieciowa Abstrakcyjny model komunikacji sieciowej
Abstrakcyjny model komunikacji sieciowej
UDP
" Bezpo艂膮czeniowa transmisja datagram贸w
" Pakiety mog膮 zagin膮膰
" Mog膮 pojawia膰 si臋 duplikaty
" Warstwa sieciowa gwarantuje, 偶e pakiet dotrze w postaci nieuszko-
dzonej lub nie dotrze w og贸le
" Program sam musi zadba膰 o poprawne dostarczenie pakietu poprzez
odpowiednie potwierdzenia i ew. retransmisj臋
" Brak fazy nawi膮zywania po艂膮czenia, a wi臋c kr贸tszy ni偶 w TCP czas
przes艂ania pierwszych pakiet贸w
TCP
" Transmisja po艂膮czeniowa
" Nawi膮zanie po艂膮czenia zajmuje troch臋 czasu (trzyetapowa konwersa-
cja: wys艂anie 偶膮dania, potwierdzenie gotowo艣ci, ustanowienie kana艂u
komunikacyjnego)
" Warstwa sieciowa gwarantuje, 偶e wszystkie pakiety dotr膮 na miejsce
i we w艂a艣ciwej kolejno艣ci (a je艣li nie  zostanie zwr贸cony odpowiedni
b艂膮d)
" Brak wyraznego podzia艂u na pakiety  po nawi膮zaniu po艂膮czenia
dane widzimy jako strumie艅, w kt贸rym mo偶na wyr贸偶ni膰 jedynie po-
cz膮tek i koniec
" Raz nawi膮zane po艂膮czenie musi zosta膰 poprawnie zamkni臋te (zn贸w
trzyetapowa konwersacja), chyba 偶e zostanie zerwane (skomplikowa-
ne protoko艂y wykrywania zerwanych po艂膮cze艅)
Sieciowe Systemu Operacyjne  UNIX 7-10
7. Komunikacja sieciowa Identyfikacja po艂膮cze艅
Identyfikacja po艂膮cze艅
" Aby rozpocz膮膰 komunikacj臋 mi臋dzy dwoma komputerami (a nast臋p-
nie odpowiednio kierowa膰 nadchodz膮ce pakiety do w艂a艣ciwego pro-
cesu) potrzebne s膮 ich adresy sieciowe, ale nie tylko, bo takich sesji
komunikacyjnych mo偶e by膰 wiele.
" Na tej samej maszynie mo偶e by膰 wiele proces贸w odpowiedzialnych za
r贸偶ne po艂膮czenia2, wi臋c sam adres nie wystarczy  potrzebne jeszcze
co艣: numer portu  16-bitowa liczba typuint;
" Numer portu przypisany jest do us艂ugi. Ale co b臋dzie, je艣li mamy
nawi膮zanych kilka po艂膮cze艅 z t膮 sam膮 us艂ug膮? Po czym je rozr贸偶ni膰?
Ka偶de po艂膮czenie IP jest identyfikowane przez PI膯 parametr贸w:


TCP

156.17.42.30, 156.17.1.33,


5341 23
" Adres IP jednej strony
" Numer portu pierwszej strony
" Adres IP drugiej strony
" Numer portu drugiej strony
" Typ protoko艂u: TCP lub UDP
Je艣li nawi膮zujemy po艂膮czenie z us艂ug膮 TELNET (port TCP/23), odbywa
si臋 to z losowo wybranego portu po stronie nadawcy. Po zaakceptowaniu
po艂膮czenia (w chwili jego nawi膮zywania) mo偶e tak偶e ulec zmianie numer
portu u strony odbieraj膮cej po艂膮czenie.
2
w przypadku UDP jest to tylko bezpo艂膮czeniowa komunikacja mi臋dzy 2 procesami, ale dla uprosz-
czenia nazwijmy to po艂膮czeniem
Sieciowe Systemu Operacyjne  UNIX 7-11
7. Komunikacja sieciowa Problem kolejno艣ci bajt贸w
Problem kolejno艣ci bajt贸w
" Procesory takie jak Zilog Z-80, Intel 80x86, Pentium itp., przechowu-
j膮 dane w formacie little-endian: najpierw najmniej znacz膮cy bajt,
potem bardziej znacz膮ce;
" Procesory Motorola 680x0, SPARC, RISC, MIPS  kolejno艣膰 big-
endian: najpierw najbardziej znacz膮cy bajt, potem coraz mniej zna-
cz膮ce.
Przesy艂aj膮c dane pomi臋dzy r贸偶nymi typami procesor贸w (w szczeg贸lno艣ci
 przy konstruowaniu nag艂贸wk贸w zawieraj膮cych adresy, numery port贸w,
d艂ugo艣ci, itp.) musimy zdecydowa膰 si臋 na jeden rodzaj  wybrany zosta艂
porz膮dek big-endian.
W celu konwersji z porz膮dku hosta do porz膮dku sieciowego nale偶y u偶y膰
jednej z funkcji (makr):
" htons()  dla danych typushort int(np. numery port贸w)
" htonl()  dla danych typuint(np. adresy IP)
i analogicznie, z porz膮dku sieciowego do porz膮dku hosta:
" ntohs()
" ntohl()
W systemach z procesorem typu little-endian makra te dokonuj膮 odpo-
wiedniej konwersji, a w systemach typu big-endian  s膮 to puste definicje.
Sieciowe Systemu Operacyjne  UNIX 7-12
7. Komunikacja sieciowa Uproszczony model OSI
Model komunikacji klient serwer
" Z regu艂y komunikacja sieciowa odbywa si臋 z u偶yciem serwer贸w ocze-
kuj膮cych non-stop na przyj臋cie zg艂oszenia od klient贸w, czyli progra-
m贸w nawi膮zuj膮cych po艂膮czenie.
" W przypadku transmisji UDP tak偶e klient musi zarejestrowa膰 ch臋膰
odbierania pakiet贸w adresowanych na konkretny numer portu, wi臋c
z sieciowego punktu widzenia  po cz臋艣ci staje si臋 tak偶e serwerem.
" Serwer oczekuje na zg艂oszenia pod znanym numerem portu, a po
przyj臋ciu zg艂oszenia uruchamia swoj膮 kopi臋 (fork()), kt贸ra b臋dzie
obs艂ugiwa膰 tego klienta lub robi to r贸wnolegle z obs艂ug膮 innych klien-
t贸w w g艂贸wnym w膮tku, mo偶liwe jest wi臋c wielokrotne jednoczesne
korzystanie z tej samej us艂ugi.
" Trzymanie  w pogotowiu serwer贸w wszystkich us艂ug, tak偶e tych
bardzo rzadko u偶ywanych, to marnowanie pami臋ci  dlatego wi臋k-
szo艣膰 mo偶e by膰 uruchamiana przez programinetd Internet Super-
daemon.
"  Znane lub  zarezerwowane numery port贸w to numery wymienio-
ne w pliku /etc/services, np.:
 23/tcp TELNET
 21/tcp FTP
 520/udp RIP
 6667/tcp IRC
 itp.
Uproszczony model OSI:
" 5-7 warstwa proces贸w (procesy/daemony)
" 3-4 warstwa transportowa (UDP, TCP)
" 2-3 warstwa sieciowa (IP)
" 1-2 warstwa 艂膮cza (interfejs sprz臋towy)
Sieciowe Systemu Operacyjne  UNIX 7-13
8. Protoko艂y sieciowe
Protoko艂y sieciowe
Standardowe us艂ugi, takie jak zdalny dost臋p, transfer plik贸w, poczta elek-
troniczna itp. s膮 przypisane do sta艂ych numer贸w port贸w.
" Us艂ugi zdalnego dost臋pu
 TELNET, RLOGIN
 RSH, REXEC
 SSH, STELNET
" Us艂ugi t艂umaczenia nazw i katalogowe
 DNS (Domain Name System)
 NIS (Network Information System)
 NIS+ (NISPLUS  zaawansowana wersja NIS)
 FNS (Federated Naming System)
" Us艂ugi zdalnej autoryzacji
 RADIUS
 TACACS, TACACS+
" Us艂ugi poczty elektronicznej i Usenet news
 SMTP (Simple Mail Transfer Protocol)
 POP2, POP3
 IMAP
 NNTP, NNRP
" Synchronizacja czasu
 NTP (Network Time Protocol)
 RDATE
Sieciowe Systemu Operacyjne  UNIX 8-1
8. Protoko艂y sieciowe
" Zdalny dost臋p do plik贸w
 NFS, RFS
 LOCK, STAT
 AFS
 SAMBA
" Zarz膮dzanie sieci膮 i us艂ugi wspomagaj膮ce
 ECHO, CHARGEN, DISCARD  testowanie sieci
 SNMP (Simple Network Management Protocol)
 DHCP
 BOOTP
 TFTP (Trivial File Transfer Protocol)
 RIP, OSPF, IGRP, BGP  routing
" Us艂ugi system贸w UNIX w sieciach lokalnych
 FINGER, RWHO
 LPR
 TALK
 SYSLOG
" Us艂ugi informacyjne i transfer plik贸w
 HTTP (WWW)
 GOPHER
 WHOIS
 FTP
 ARCHIE
i wiele innych...
Sieciowe Systemu Operacyjne  UNIX 8-2
8. Protoko艂y sieciowe Powi膮zania mi臋dzy us艂ugami a numerami port贸w
Powi膮zania mi臋dzy us艂ugami a numerami port贸w
Ka偶dy protok贸艂 zwi膮zany jest tak偶e z konkretnym typem komunikacji, np.
SMTP zawsze u偶ywa TCP, RIP zawsze u偶ywa komunikacji UDP, jednak
niekt贸re us艂ugi mog膮 by膰 oferowane w obu typach komunikacji:
" RDATE  zamiennie, pe艂na funkcjonalno艣膰 w TCP i UDP;
" DNS  UDP u偶ywany do zapyta艅 o pojedyncze adresy, TCP do trans-
fer贸w pe艂nych stref pomi臋dzy serwerami DNS.
Przypisanie us艂ug do konkretnych numer贸w portu mo偶na znalez膰 w pli-
ku /etc/services lub za pomoc膮 funkcji systemowych getservbyname(),
getservbyport(), getservent() i innych.
#
# Network services, Internet style
#
echo 7/tcp
echo 7/udp
daytime 13/tcp
daytime 13/udp
ftp-data 20/tcp
ftp 21/tcp
ssh 22/tcp
telnet 23/tcp
smtp 25/tcp mail
domain 53/udp
domain 53/tcp
http 80/tcp www
pop2 109/tcp pop-2 # Post Office Protocol - V2
pop3 110/tcp # Post Office Protocol - Version 3
sunrpc 111/udp rpcbind
sunrpc 111/tcp rpcbind
...
irc 6667/tcp
Sieciowe Systemu Operacyjne  UNIX 8-3
8. Protoko艂y sieciowe T艂umaczenie nazw us艂ug w systemie UNIX
T艂umaczenie nazw us艂ug w systemie UNIX
#include
struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);
int setservent(int stayopen);
struct servent *getservent(void);
int endservent(void);
" getservbyname() i getservbyport() pozwalaj膮 przet艂umaczy膰 pojedyn-
cze nazwy us艂ug na numery port贸w lub odwrotnie;
" Dane zwracane s膮 w strukturzestruct servent:
struct servent {
char *s_name; /* oficjalna nazwa us艂ugi */
char **s_aliases; /* lista alias贸w, zako艅czona NULL */
int s_port; /* numer portu */
char *s_proto; /* nazwa protoko艂u */
};
" getservent() pozwala sekwencyjnie przegl膮da膰 list臋 us艂ug, korzysta-
j膮c z lokalnego pliku /etc/services lub serwer贸w NIS/NIS+;
" getservent(), getservbyname() i getservbyport() zwracaj膮 wskaznik
na statyczn膮 struktur臋 danych w pami臋ci systemowej, dlatego nie
mo偶na tych funkcji wykorzystywa膰 w programach wielow膮tkowych.
Zamiast nich nale偶y korzysta膰 z getservent r(), getservbyname r(),
getservbyport r().
Sieciowe Systemu Operacyjne  UNIX 8-4
8. Protoko艂y sieciowe Przyk艂ad protoko艂u  SMTP
Przyk艂ad protoko艂u  SMTP
Przyk艂adowa konwersacja z demonem poczty elektronicznej wykonana
przy pomocy programutelnet:
% telnet cyber 25
Trying 156.17.41.30...
Connected to cyber.
Escape character is  ^] .
220 cyber.ict.pwr.wroc.pl ESMTP Sendmail 8.9.3 Mon, 17 Apr 2000 21:00:00 +0200 (MET DST)
ehlo okapi.ict.pwr.wroc.pl
250-cyber.ict.pwr.wroc.pl Hello ts@okapi [156.17.42.30], pleased to meet you
250-8BITMIME
250-SIZE 1500000
250-ETRN
250 HELP
help
214-This is Sendmail version 8.9.3
214-Commands:
214- HELO EHLO MAIL RCPT DATA EXPN
214- RSET NOOP QUIT HELP VRFY VERB
214-For more info use "HELP ".
214-To report bugs in the implementation send email to
214- sendmail@CS.Berkeley.EDU.
214-For local information send email to Postmaster at your site.
214 End of HELP info
mail from:
250 ... Sender ok
rcpt to:
250 ... Recipient ok
rcpt to:
250 ... Recipient ok
rcpt to:
550 ... User unknown
data
354 Enter mail, end with "." on a line by itself
From: Swiety Mikolaj
To: Wszystkie grzeczne dzieci (undisclosed recipients at cyber)
Subject: Swieta...
Wprawdzie to nie te swieta, ale i tak -- Weso艂ych 艢wi膮t!
.
250 VAA08247 Message accepted for delivery
quit
221 cyber.ict.pwr.wroc.pl closing connection
Connection closed by foreign host.
Sieciowe Systemu Operacyjne  UNIX 8-5
8. Protoko艂y sieciowe Tworzenie gniazdek
Protoko艂y sieciowe wi臋kszo艣ci us艂ug z regu艂y stosuj膮 si臋 do nast臋puj膮cych
zasad:
" komunikacja odbywa si臋 w spos贸b ca艂kowicie tekstowy (z wyj膮tkiem
fragment贸w wymagaj膮cych przes艂ania plik贸w/danych binarnych);
" klient wydaje tekstowe polecenia zako艅czone znakiem ko艅ca linii;
" serwer odpowiada w spos贸b tekstowy, rozpoczynaj膮c lini臋 3-
cyfrowym kodem, po kt贸rym nast臋puje dodatkowa informacja dla
u偶ytkownika;
 Trzy cyfry i minus oznaczaj膮, 偶e kod odpowiedzi b臋dzie konty-
nuowany w nast臋pnej linii;
 Trzy cyfry i spacja oznaczaj膮, 偶e jest to ostatnia linia.
" Pierwsza cyfra okre艣la, czy wykonanie operacji si臋 uda艂o:
 Kody2xxoznaczaj膮 poprawne zako艅czenie operacji;
 3xx poprawne zako艅czenie wydanej komendy, ale wymaga-
ne jest kontynuowanie rozpocz臋tej operacji zgodnie z przyj臋tym
protoko艂em (np. po podaniu komendy  user abc mo偶e si臋 po-
jawi膰 odpowiedz  331 Password required for user abc ;
 4xx tymczasowy b艂膮d, np. brak wolnej pami臋ci, zaj臋te zasoby,
itp. Pr贸ba mo偶e by膰 ponowiona za jaki艣 czas;
 5xx b艂膮d, np. z艂a nazwa u偶ytkownika, z艂e parametry, itp. Nie
ma sensu ponawia膰 pr贸b, bo w tej postaci zawsze b臋dzie gene-
rowany b艂膮d.
" dzi臋ki tekstowemu charakterowi transmisji (i komentarzom po ko-
dach numerycznych) mo偶liwe jest  r臋czne testowanie po艂膮cze艅 na-
wet bez specjalnego programu klienta;
" programy klienta z regu艂y interpretuj膮 wy艂膮cznie numeryczne kody
zako艅czenia operacji. 艢cis艂a interpretacja pierwszej (i drugiej) cy-
fry pozwala na poprawn膮 reakcj臋 nawet w przypadku rozbie偶no艣ci
w implementacji protoko艂u po obu stronach po艂膮czenia.
Sieciowe Systemu Operacyjne  UNIX 8-6
8. Protoko艂y sieciowe Tworzenie gniazdek
Tworzenie gniazdek
Komunikacja sieciowa w systemie UNIX odbywa si臋 za pomoc膮 gniazd
sieciowych (zwanych te偶 gniazdkami lub gniazdkami BSD).
" Gniazdko jest przez system UNIX traktowane tak, jak deskryptor
otwartego pliku  mo偶na z niego czyta膰 funkcj膮 read(), mo偶na do
niego pisa膰 przez write(), zamkn膮膰 je za pomoc膮 close(), a tak偶e
wykona膰 operacje mo偶liwe tylko na deskryptorach b臋d膮cych gniazd-
kami;
" Gniazdko istnieje w okre艣lonej domenie adresowej, co implikuje w ja-
ki spos贸b zapisywany b臋dzie adres gniazdka  stosowane obecnie do-
meny to:
 AF_UNIX gniazdka systemu UNIX, zwi膮zane z systemem pli-
k贸w;
 AF_INET gniazdka sieciowe, IPv4;
 AF_INET6 nowe gniazdka sieciowe, IPv6;
 Mniej popularne:AF_ISO,AF_NS(Xerox).
" Opr贸cz domeny adresowej na spos贸b komunikacji ma wp艂yw typ
gniazdka:
 SOCK_STREAM gniazdka strumieniowe (TCP);
 SOCK_DGRAM gniazdka datagramowe (UDP);
 SOCK_RAW gniazdka operuj膮ce w warstwie 2 modelu OSI/ISO
(np. ARP, pakiety ICMP i inne);
 inne.
" Nowe gniazdko mo偶na utworzy膰 za pomoc膮 socket() lub socketpair()
(ta druga wy艂膮cznie w domenieAF_UNIX);
" Zanim gniazdko b臋dzie nadawa艂o si臋 do u偶ycia, nale偶y mu nada膰
adres za pomoc膮 funkcji bind().
Sieciowe Systemu Operacyjne  UNIX 8-7
8. Protoko艂y sieciowe Tworzenie gniazdek
Funkcja socket()
#include
#include
int socket(int domain, int type, int protocol);
" Domena  AF_UNIXlubAF_INET
" Typ  SOCK_STREAM,SOCK_DGRAM,SOCK_RAW,SOCK_SEQPACKET
" Protok贸艂  艣ci艣le zwi膮zany z typem gniazdka, np. gniazdkaAF_INET
SOCK_STREAMkorzystaj膮 zawsze z protoko艂uIPPROTO_TCP, a inter-
netowe gniazdka typuSOCK_DGRAM protoko艂uIPPROTO_UDP.
Rozr贸偶nienie mo偶e by膰 istotne w przypadku gniazdek SOCK_RAW,
gdzie mo偶emy wybra膰IPPROTO_ICMPlubIPPROTO_RAW.
Podanie warto艣ci 0 spowoduje wybranie protoko艂u w艂a艣ciwego dla
podanej kombinacji domeny i typu gniazdka.
Funkcja socketpair()
#include
#include
int socketpair(int domain, int type, int protocol, int sv[2]);
Tworzy dwa nie po艂膮czone ani nie nazwane deskryptory gniazd, z kt贸rych
ka偶dy mo偶e s艂u偶y膰 do dwukierunkowej komunikacji (inaczej ni偶 w stru-
mieniach FIFO czy deskryptorach zwracanych przez pipe()).
" DomenaAF_UNIX
" TypSOCK_STREAMlubSOCK_DGRAM
" Protok贸艂  warto艣膰 0 wybiera w艂a艣ciwy.
Sieciowe Systemu Operacyjne  UNIX 8-8
8. Protoko艂y sieciowe Tworzenie gniazdek
Nadanie nazwy  funkcja bind()
#include
#include
int bind(int s, const struct sockaddr *name, socklen_t *namelen);
" sockfd deskryptor utworzonego wcze艣niej gniazda;
" name odpowiednia do domeny adresowej struktura zawieraj膮ca ad-
res nadawany gniazdku;
" namelen d艂ugo艣膰 struktury adresowej.
W przypadku gniazdek sieciowych IPv4 adres okre艣la struktura
sockaddr_inzdefiniowana w pliku /usr/include/netinet/in.h:
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
Sktruktorain_addroraz typin_port_ts膮 okr臋偶nym sposobem zdefinio-
wania adresu/portu w spos贸b przeno艣ny, by nadawa艂y si臋 do zastosowania
w wielu architekturach procesor贸w i r贸偶nych systemach. W rzeczywisto-
艣ci s膮 to odpowiednio 32- i 16-bitowe liczby typuunsigned int ZAW-
SZE zapisane w porz膮dku sieciowym.
Sieciowe Systemu Operacyjne  UNIX 8-9
8. Protoko艂y sieciowe Tworzenie gniazdek
Nadanie nazwy jest konieczne:
" w przypadku serwer贸w  zar贸wno po艂膮czeniowych, jak i bezpo艂膮-
czeniowych  pozwala odnotowa膰 w systemie og贸lnie znany adres
serwera i powi膮za膰 nadchodz膮ce pakiety z procesem, kt贸ry ma je
otrzymywa膰;
" w przypadku transmisji bezpo艂膮czeniowej  zar贸wno po stronie ser-
wera, jak i klienta. Pakiety wysy艂ane z systemu b臋d膮 mia艂y ustawiony
okre艣lony adres nadawcy, co umo偶liwia odes艂anie mu odpowiedzi;
Nadanie nazwy jest opcjonalne:
" je艣li w systemie znajduje si臋 kilka interfejs贸w sieciowych3 i chcemy
wymusi膰 skorzystanie z wybranego. Mo偶emy te偶 u偶y膰 pseudo-adresu
INADDR_ANY, kt贸ry zezwala na u偶ycie dowolnego adresu/interfejsu.
" je艣li klient chce uzyska膰 przed uzyskaniem po艂膮czenia wybrany numer
portu. Domy艣lnie stosowany port 0 pozwala na wybranie dowolnego
numeru portu przez system, w chwili 艂膮czenia z serwerem.
Porty poni偶ej 1024 (IPPORT_RESERVED) s膮 portami zarezerwowanymi lub
uprzywilejowanymi  taki numer mo偶e przypisa膰 gniazdku funkcja bind()
wywo艂ana wy艂膮cznie przez u偶ytkownika zeuid==0(root).
Pierwszy wolny (od g贸ry) numer portu z zakresu zarezerwowanego (512-
1023) mo偶na przydzieli膰 funkcj膮 rresvport(int* port), kt贸ra przydziela
gniazdko i nadaje mu nazw臋 (zwracaj膮c jego deskryptor).
Porty powy偶ej 5000 (IPPORT_USERRESERVED) s膮 zarezerwowane na us艂ugi
serwer贸w uruchamianych przez u偶ytkownik贸w (bez uprawnie艅 u偶ytkow-
nika root).
Je艣li numer portu pozostanie ustawiony na 0, w chwili uzyskania po艂膮-
czenia zostanie przydzielony piwrwszy wolny (unikalny) numer z zakresu
1024-5000.
3
eth,lo...
Sieciowe Systemu Operacyjne  UNIX 8-10
8. Protoko艂y sieciowe Us艂ugi t艂umaczenia nazw  DNS/NIS/NIS+
Us艂ugi t艂umaczenia nazw  DNS/NIS/NIS+
#include
struct hostent *gethostbyname(const char *name);
struct hostent *gethostbyaddr(const char *addr, int len, int type);
To, w jaki spos贸b system UNIX t艂umaczy nazwy na adresy i odwrotnie,
zale偶y od konfiguracji systemu:
" Plik /etc/nsswitch.conf okre艣la z jakich us艂ug sieciowych nale偶y ko-
rzysta膰  lokalnych plik贸w, NIS, NIS+ czy DNS (i w jakiej kolejno-
艣ci);
" Plik /etc/hosts zawiera nazwy host贸w i adresy konieczne podczas
uruchamiania systemu (np. do skonfigurowania kart sieciowych, gdy
jeszcze nie mo偶na skorzysta膰 z DNS);
" Plik /etc/resolv.conf okre艣la adresy serwer贸w DNS oraz domy艣lne
domeny doklejane do zapyta艅.
Korzystanie z funkcji systemowych pozwala uniezale偶ni膰 si臋 od r贸偶norod-
no艣ci stosowanych system贸w t艂umaczenia nazw (pliki lokalne, DNS, NIS,
NIS+)
Korzystaj膮c z tych funkcji nale偶y pami臋ta膰, 偶e:
" Jednej nazwie hosta mo偶e by膰 przyporz膮dkowanych wiele adres贸w
(np. w przypadku router贸w lub host贸w maj膮cych kilka interfejs贸w
sieciowych)  nale偶y przejrze膰 je wszystkie;
" Ka偶dy host mo偶e opr贸cz nazwy kanonicznej (g艂贸wnej) posiada膰 i in-
ne nazwy, zwyczajowe, zwane aliasami, np.ftp.pwr.wroc.pljest
aliasem nazwy kanonicznejpanorama.wcss.wroc.pl;
" Wszystkie adresy zwracane s膮 w porz膮dku sieciowym i mo偶e by膰
konieczne u偶ycie odpowiednich makr htonl() lub ntohl().
Sieciowe Systemu Operacyjne  UNIX 8-11
8. Protoko艂y sieciowe Us艂ugi t艂umaczenia nazw  DNS/NIS/NIS+
Adresy i nazwy zwracane s膮 w strukturzehostent
struct hostent {
char *h_name; /* canonical name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
};
Struktura ta zawiera pola pozwalaj膮ce przekaza膰 adres niezale偶nie od
stosowanej domeny adresowej.
Opr贸cz funkcji szukaj膮cych adresu/nazwy wybranego hosta istniej膮 funk-
cje pozwalaj膮ce sekwencyjnie przegl膮da膰 zawarto艣膰 pliku /etc/hosts lub
map NIS/NIS+:
int sethostent(int stayopen);
struct hostent *gethostent(void);
int endhostent(void);
Wszystkie z funkcji: gethostbyname(), gethostbyaddr(), gethostent() zwra-
caj膮 wskaznik na statyczn膮 struktur臋 danych w pami臋ci systemowej,
dlatego nie mo偶na tych funkcji wykorzystywa膰 w programach wielow膮t-
kowych. Zamiast nich nale偶y korzysta膰 z gethostbyname r(), gethostby-
addr r() i gethostent r(), kt贸re dodatkowo wymagaj膮 podania wskaznika
na bufor, gdzie zostan膮 zwr贸cone szukane dane, jego d艂ugo艣ci, oraz adresu
zmiennej pe艂ni膮cej funkcj臋 zmiennejerrno(w kt贸rej zostanie umieszczo-
ny kod ewentualnego b艂臋du).
Inne przydatne funkcje:
#include
#include
char *inet_ntoa(const struct in_addr in);
unsigned long inet_addr(const char *cp);
unsigned long inet_network(const char *cp);
struct in_addr inet_makeaddr(const int net, const int lna);
Sieciowe Systemu Operacyjne  UNIX 8-12
9. Komunikacja TCP Nawi膮zywanie po艂膮cze艅 TCP
Komunikacja TCP
Nawi膮zywanie po艂膮cze艅 TCP
" Klient wywo艂uje funkcj臋 connect(), podaj膮c adres serwera, z kt贸rym
chce si臋 po艂膮czy膰;
" Serwer rejestruje swoj膮 us艂ug臋 w systemie za pomoc膮 funkcji listen(),
a nast臋pnie oczekuje na po艂膮czenia za pomoc膮 accept();
" Funkcje connect() i accept() s膮 funkcjami blokuj膮cymi, tzn. powoduj膮
u艣pienie procesu do momentu uzyskania po艂膮czenia z drug膮 stron膮.
socket() s1=socket()


klient serw r
e
bind() bind()
connect() listen()
s2=accept(s1)


synchroniza j
c a


wymiana d ny h
a c
read() read(s2)
write() write(s2)
" Zaakceptowanie po艂膮czenia powoduje utworzenie przez proces serwe-
ra nowego gniazdka, kt贸re jst gniazdkiem po艂膮czonym, podczas gdy
g艂贸wne gniazdko (s1) mo偶e nadal s艂u偶y膰 do przyjmowania nowych
po艂膮cze艅.
Sieciowe Systemu Operacyjne  UNIX 9-1
9. Komunikacja TCP Serwery wsp贸艂bie偶ne
Serwery wsp贸艂bie偶ne
Po zaakceptowaniu po艂膮czenia funkcj膮 accept() serwer mo偶e niezale偶nie
obs艂ugiwa膰 klienta, kt贸ry si臋 z nim po艂膮czy艂, oraz nawi膮zywa膰 nowe po-
艂膮czenia.
Wykorzystuj膮c funkcje nieblokuj膮ce lub inne mechanizmy, mo偶na to robi膰
w jednym procesie, z regu艂y jednak wygodniej jest do obs艂ugi po艂膮czonego
klienta utworzy膰 nowy proces:
connect() listen()

s2=accept()

synchroniza j
c a

rodzic
fork()
fork()


dzie ko
c


wymiana d ny h
a c
read() read(s2)
write() write(s2)
" Po wykonaniu accept() proces wykonuje fork(), rozdzielaj膮c si臋 na 2
procesy;
" Rodzic zamyka gniazdkos2(po艂膮czone z klientem) i wraca w p臋tli
do funkcji accept(), oczekuj膮c na nowe po艂膮czenia, a tak偶e od czasu
do czasu  sprz膮taj膮c po procesach potomnych za pomoc膮 wait();
" Dziecko zamyka gniazdkos1, s艂u偶膮ce do akceptowania nowych po-
艂膮cze艅, oraz inne niepotrzebne deskryptory przekazane mu przez ro-
dzica, do komunikacji z klientem u偶ywaj膮c jedynie gniazdkas2.
Sieciowe Systemu Operacyjne  UNIX 9-2
9. Komunikacja TCP Funkcja listen()
Funkcja connect()
#include
#include
int connect(int s, const struct sockaddr *name, struct_t namelen);
" Funkcj臋 mo偶na zastosowa膰 zar贸wno w przypadku gniazd strumienio-
wych (TCP) jak i datagramowych (UDP).
" TCP  nawi膮zuje po艂膮czenie z serwerem
" UDP  tworzy asocjacj臋 (przypisanie adres贸w do gniazdka)
" nameokre艣la adres drugiego gniazdka, z kt贸rym ma nast膮pi膰 po艂膮-
czenie (lub w przypadku UDP  asocjacja)
" je艣li do gniazdkasnie jest przypisany funkcj膮 bind() 偶aden adres,
to zostaje on nadany automatycznie przez warstw臋 transportow膮
w chwili nawi膮zania po艂膮czenia.
Funkcja listen()
int listen(int s, int backlog);
" Parametr backlog okre艣la maksymaln膮 wielko艣膰 kolejki po艂膮cze艅
oczekuj膮cych na zaakceptowanie funkcj膮 accept().
" Je艣li kolejka zostanie przepe艂niona klienci zaczn膮 otrzymywa膰 b艂膮d
ECONNREFUSEDw gniazdkach typuAF_UNIX, a w gniazdkachAF_INET
 po艂膮czenia b臋d膮 ignorowane po stronie serwera, a retransmitowane
po stronie klienta (a偶 doETIMEDOUT).
Sieciowe Systemu Operacyjne  UNIX 9-3
9. Komunikacja TCP Funkcja shutdown()
Funkcja accept()
int accept(int s, struct sockaddr *addr, int *addrlen);
" Funkcja powoduje zablokowanie programu do czasu, gdy jest przy-
najmniej jedno zg艂oszenie w kolejce oczekuj膮cych po艂膮cze艅.
" Pierwsze zg艂oszenie z kolejki zostaje zaakceptowane, tworz膮c nowe
gniazdko, a w zmiennejaddrzostaj膮 umieszczone dane na temat
drugiej strony po艂膮czenia, o ile s膮 znane.
" Wykonalno艣膰 funkcji accept() mo偶na sprawdzi膰 tak偶e za pomoc膮 se-
lect() lub poll().
Funkcja shutdown()
int shutdown(int s, int how);
" Zamyka dwukierunkowe po艂膮czenie zwi膮zane z gniazdkiemsca艂ko-
wicie, lub tylko jednostronnie.
" 0: z gniazdka nic ju偶 nie b臋dzie czytane;
" 1: do gniazdka ju偶 nic nie b臋dzie pisane;
" 2: gniazdko zostaje zamkni臋te zar贸wno do pisania jak i do czytania.
Sieciowe Systemu Operacyjne  UNIX 9-4
9. Komunikacja TCP Serwery samodzielne i uruchamiane przez inetd
Serwery samodzielne i uruchamiane przez inetd
Typowy mechanizm dzia艂ania serwerow sieciowych:
" Serwer g艂贸wny rejestruje gniazdko przyjmuj膮ce po艂膮czenia;
" nadchodz膮ce po艂膮czenia przejmowane s膮 przez procesy potomne;
" zako艅czone po艂膮czenie z klientem oznacza koniec pracy serwera po-
tomnego;
" proces g艂贸wny oczekuje na 艣mier膰 proces贸w potomnych wo艂aj膮c re-
gularnie wait() lub przechwytuj膮c sygna艂ySIGCLD;
" proces g艂贸wny nigdy si臋 nie ko艅czy.
Skoro mechanizm dzia艂anie jest identyczny w przypadku wi臋kszo艣ci serwe-
r贸w sieciowych (TELNET,RLOGIN,TALK,FINGERitp.), to po co wielokrotnie
marnowa膰 pami臋膰 na proces g艂贸wny dla ka偶dej z us艂ug z osobna?
" Jeden wsp贸lny proces akceptuj膮cy po艂膮czenia dla wielu us艂ug siecio-
wych i uruchamiaj膮cy odpowiednie serwery potomne;
" Problemy:
 r贸偶norodno艣膰 protoko艂贸w (TCP, UDP);
 r贸偶ne uprawnienia serwer贸w (dzia艂aj膮ce z konta root, sys lub
innego);
 elastyczno艣膰:
" r贸偶ne serwery w r贸偶nych katalogach dyskowych;
" niekt贸re us艂ugi obs艂ugiwane przez ten sam serwer;
" mo偶liwo艣膰 przekazania parametr贸w, opcji, plik贸w konfigura-
cyjnych;
 efektywno艣膰  mo偶liwo艣膰 przej臋cia przyjmowania nowych po艂膮-
cze艅 przez  usamodzielniony proces potomny.
Sieciowe Systemu Operacyjne  UNIX 9-5
9. Komunikacja TCP Serwer inetd
Serwer inetd
inetdlubin.inetd  Internet-superdaemon , program uruchamiaj膮cy
inne serwery na 偶膮danie  wtedy, gdy s膮 potrzebne, np:
" in.telnetd
" in.ftpd
" tftpd
" in.fingerd
" in.rshd
" in.rlogind
" in.rshd
" in.rexecd
" in.identd (pidentd)
" pop3d
Konfiguracja programuinetdznajduje si臋 w pliku /etc/inetd.conf i okre-
艣la spos贸b obs艂ugi ka偶dego z wymienionych w nim port贸w:
ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd -l
telnet stream tcp nowait root /usr/sbin/in.telnetd in.telnetd
talk dgram udp wait root /usr/sbin/in.talkd in.talkd
#
# Time service is used for clock synchronization.
#
time stream tcp nowait root internal
time dgram udp wait root internal
#
printer stream tcp nowait root /usr/lib/print/in.lpd in.lpd
ident stream tcp wait sys /usr/sbin/in.identd in.identd -w -t180
Sieciowe Systemu Operacyjne  UNIX 9-6
9. Komunikacja TCP Serwer inetd
Procesy uruchamiane przezinetdnie martwi膮 si臋 o nawi膮zywanie po艂膮-
czenia, lecz komunikuj膮 si臋 z klientem przez swoje standardowe wej艣cie
i wyj艣cie:
connect() listen(s1)

select(...);

synchroniza j s2=accept();
c a
fork()

rodzic
fork()


wait?:

dzie ko
c
- zwalnia s1


- wait3(pid)
dup2(s2,0);
dup2(s2,1);
setuid();
exec("rshd");


wymiana d ny h
a c
read()
read(0);
write()
write(1);
" inetd dla ka偶dej us艂ugi znalezionej w /etc/inetd.conf przydziela
osobne gniazdko, przypisuje mu za pomoc膮 bind() w艂a艣ciwy numer
portu, wykonuje listen(), by zacz膮膰 nas艂uchiwa膰 na po艂膮czenia, po
czym za pomoc膮 select() czeka, a偶 na kt贸rym艣 z nich mo偶na b臋dzie
wykona膰 accept();
" Po przyj臋ciu zg艂oszenia i wykonaniu fork(), proces macierzysty:
 zamyka po艂膮czone gniazdko (s2);
 je艣li w konfiguracji wyst膮pi艂a opcjawait, od艂膮cza si臋 od g艂贸w-
nego gniazdka, a偶 do chwili, gdy proces potomny si臋 zako艅czy;
 dalej nas艂uchuje na gniazdku g艂贸wnym, w przypadkunowait;
" Proces potomny kopiuje po艂膮czone gniazdkos2do deskryptor贸w 0,
1 i 2, zamyka wszystkie pozosta艂e otwarte deskryptory, je艣li trzeba 
wykonuje setuid() i setgid(), po czym uruchamia odpowieni program
za pomoc膮 exec().
Sieciowe Systemu Operacyjne  UNIX 9-7
10. Komunikacja UDP
Komunikacja UDP
" GniazdkaSOCK_DGRAM, u偶ywane w komunikacji UDP, s膮 bezpo艂膮cze-
niowe, wi臋c nie trzeba nawi膮zywa膰 po艂膮czenia funkcjami takimi, jak
connect() i accept().
" Konieczne jest zarejestrowanie w systemie ch臋ci otrzymywania pakie-
t贸w wysy艂anych na 偶膮dany numer portu, co wymaga nadania nazwy
gniazdku funkcj膮 bind().
Typowa kolejno艣膰 wo艂ania funkcji systemowych w komunikacji UDP:
socket() socket()
bind() bind()


wymiana danych UDP
sendto() recvfrom()
recvfrom() sendto()
" Funkcja bind() nadaje nazw臋 gniazdku (lokalny adres i lokalny numer
portu), tworz膮c p贸艂asocjacj臋.
" sendto() wymaga ka偶dorazowego podania adresu drugiej strony, do
kt贸rej jest wysy艂any pakiet.
" recvfrom() wymaga ka偶dorazowo dostarczenia zmiennej, w kt贸rej zo-
stanie zwr贸cony adres strony, kt贸ra przys艂a艂a pakiet.
Sieciowe Systemu Operacyjne  UNIX 10-1
10. Komunikacja UDP
" Nie ma 偶adnej synchronizacji pomi臋dzy procesami.
" Po zarejestrowaniu ch臋ci otrzymywania pakiet贸w (funkcj膮 bind())
tworzona jest kolejka, do kt贸rej s膮 zapisywane przychodz膮ce pakiety.
" Warstwa transportowa nie zapewnia niezawodno艣ci przesy艂anych da-
nych nawet po zarejestrowaniu gniazdka  pakiety mog膮 gin膮膰 lub
przychodzi膰 w kilku kopiach.
socket() socket()
bind()

pakiet UDP
sendto()
bind()

pakiet UDP
sendto()
recvfrom()
recvfrom()
sendto()
" Pakiety przychodz膮ce przed wykonaniem funkcji bind() s膮 odrzucane
(bez potwierdzenia).
" Pakiety przychodz膮ce po wykonaniu funkcji bind() s膮 kolejkowane
i dostarczane do aplikacji, po wywo艂aniu przez ni膮 funkcji recvfrom().
Sieciowe Systemu Operacyjne  UNIX 10-2
10. Komunikacja UDP Funkcje recvfrom() i sendto()
Funkcje recvfrom() i sendto()
#include
#include
#include
ssize_t recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen);
ssize_t sendto(int s, const void *msg, size_t len, int flags,
const struct sockaddr *to, socklen_t tolen);
ssize_t recv(int s, void *buf, size_t len, int flags);
ssize_t send(int s, const void *msg, size_t len, int flags);
" sendto() wysy艂a dostarczony pakiet na adres przekazany w zmiennej
wskazywanej przezfrom;
" recvfrom() w zmiennej wskazywanej przez from umieszcza adres
nadawcy pakietu, a d艂ugo艣膰 tego adresu w zmiennej wskazywanej
przezfromlen, chyba 偶efrom==NULL.
" send() i recv() wymagaj膮 wcze艣niejszego utworzenia pe艂nej asocjacji
(za pomoc膮 funkcji connect()), w kt贸rej zawarty jest adres drugiej
strony.
" Podanie w opcjach recvfrom() i recv() sta艂ejMSG_PEEKpowoduje
podgl膮dni臋cie dost臋pnych danych, bez ich  konsumowania .
" recvfrom() i recv() s膮 funkcjami blokuj膮cymi.
Je艣li po偶膮dane jest, by funkcja nie blokowa艂a aplikacji przy braku ko-
munikatu, mo偶na skorzysta膰 z funkcji select() lub przestawi膰 gniazd-
ko w tryb nieblokuj膮cy, za pomoc膮 fcntl(). W takim przypadku re-
cvfrom() i recv() mog膮 zwr贸ci膰 warto艣膰 -1 i ustawi膰 zmienn膮errno
naEWOULDBLOCK.
Sieciowe Systemu Operacyjne  UNIX 10-3
10. Komunikacja UDP Korzystanie z connect()
Korzystanie z connect()
" Dzia艂anie funkcji connect() w przypadku gniazdek typuSOCK_DGRAM
ogranicza si臋 do zarejestrowania w systemie pe艂nej asocjacji zwi膮za-
nej z kominikacj膮, a wi臋c tak偶e adresu drugiej strony.
" Po wykonaniu connect() z podanym adresem drugiej strony, w dal-
szej komunikacji mo偶na u偶ywa膰 tak偶e funkcji recv() i send().
" W trakcie komunikacji mo偶na wielokrotnie wo艂a膰 connect() z r贸偶ny-
mi adresami, zmieniaj膮c istniej膮c膮 asocjacj臋.
" Po wywo艂aniu connect() z pustym adresem, ustanowiona wcze艣niej
asocjacja zostaje usuni臋ta i dalsza komunikacja mo偶liwa jest wy艂膮cz-
nie za pomoc膮 funkcji recvfrom() i sendto().


socket() utworzenie gniazdka socket()

bind() nad nie adresu bind()
a

przy isanie adresu
p
connect() connect()

dru iej strony
g


send()recvfrom() pakie UDP send()
ty
recv() sendto() recv()
recvfrom()
sendto()
close()
Sieciowe Systemu Operacyjne  UNIX 10-4
10. Komunikacja UDP Przyk艂ad serwera protoko艂u TCP
Przyk艂ad serwera protoko艂u TCP
#define SERVPORT 8000
main (int argc,char ** argv)
{ int sock, newsock, pid, clen, port;
struct sockaddr_in cl_addr, serv_addr;
if (argc>1)
port = atoi(argv[1]);
else
port = SERVPORT;
if ((sock=socket(AF_INET, SOCK_STREAM, 0)) < 0)
sys_err("serwer: nie mo偶na utworzy膰 gniazdka");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
sys_err("serwer: nie mo偶na nada膰 gniazdku adresu");
listen(sock, 5);
while(1) {
clen = sizeof(cl_addr);
newsock = accept(sock, (struct sockaddr*) &cl_addr, &clen);
if (newsock < 0)
sys_err("serwer: b艂膮d w funkcji accept()");
else {
switch (pid=fork()) {
case 0: /* dziecko */
close (sock);
...
read(newsock, ... ); write(newsock, ... );
...
close(newsock);
exit(0):
case (-1):
sys_err("b艂膮d podczas fork()"); break;
} /* switch */
} /* else */
close (newsock);
} /* while */
}
Sieciowe Systemu Operacyjne  UNIX 10-5
10. Komunikacja UDP Przyk艂ad klienta protoko艂u TCP
Przyk艂ad klienta protoko艂u TCP
#define SERVPORT 8000
#define SERVADDR "127.0.0.1"
main (int argc,char ** argv)
{
int sock, n, nw;
struct sockaddr_in serv_addr;
char *serv_ip;
int serv_port
char buf[1024];
if (argc>=3) {
serv_ip = argv[1]; serv_port = atoi(argv[2]);
} else {
serv_ip = SERVADDR; serv_port = SERVPORT;
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(serv_ip);
serv_addr.sin_port = htons(serv_port);
if ((sock=socket(AF_INET, SOCK_STREAM, 0)) < 0)
sys_err("klient: nie mo偶na utworzy膰 gniazdka");
if (connect(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
sys_err("klient: nie mo偶na po艂膮czy膰 si臋 z serwerem);
while ( (n=read(sock, buf, sizeof(buf))) >0) {
...
nw = write(sock, ..., ... );
...
if ( /* koniec po艂膮czenia inicjowany przez klienta: */ ) {
write(sock, "koniec\n", 8);
shutdown(sock, 1); /* nie b臋dziemy ju偶 pisa膰 */
}
}
if (n==0) { /* EOF */
shutdown(sock, 2);
close(sock);
} else {
sys_err("b艂膮d funkcji read()");
}
}
Sieciowe Systemu Operacyjne  UNIX 10-6
10. Komunikacja UDP Przyk艂ad serwera protoko艂u UDP
Przyk艂ad serwera protoko艂u UDP
#define PORT 7000
main (int argc,char ** argv)
{
int sock, cl_len, n;
struct sockaddr_in serv_addr, cl_addr;
if ((sock=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
sys_err("server: nie mo偶na utworzy膰 gniazdka");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(PORT);
if (bind(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
sys_err("serwer: nie mo偶na nada膰 gniazdku lokalnego adresu");
cl_len=sizeof(cl_addr):
n = recvfrom(sock, buf, sizeof(buf), 0, &cl_addr, &cl_len);
if (n<0)
sys_err("serwer: b艂膮d w funkcji recvfrom());
strcpy(buf, "dane wysy艂ane do klienta");
n=sendto(sock, buf, strlen(buf)+1, &cl_addr, cl_len);
if (n != strlen(buf)+1) {
sys_err("serwer: b艂膮d wysylania danych - sendto()");
}
close(sock);
}
Sieciowe Systemu Operacyjne  UNIX 10-7
10. Komunikacja UDP Przyk艂ad klienta protoko艂u UDP
Przyk艂ad klienta protoko艂u UDP
#define PORT 7000
#define SERWER "localhost"
#define SERWER_IP "127.0.0.1"
main (int argc,char ** argv)
{
int sock;
struct sockaddr_in serv_addr, cl_addr;
struct hostent *hname;
if ((sock=socket(AF_INET, SOCK_DGRAM, 0)) < 0)
sys_err("klient: nie mo偶na utworzy膰 gniazdka");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(SERWER_IP);
serv_addr.sin_port = htons(PORT);
if (argc>1) {
hname=(gethostbyname(argv[1]));
if (hname != NULL) {
memcpy(&serv_addr.sin_addr, hname->h_addr_list[0], hname->h_length);
/* kopiujemy tylko pierwszy znaleziony adres, w bardziej rozbudowanej
wersji mogliby艣my pr贸bowa膰 wszystkich po kolei, do skutku */
}
}
memset(&cl_addr, 0, sizeof(cl_addr));
cl_addr.sin_family = AF_INET;
cl_addr.sin_addr.s_addr = htonl(INADDR_ANY);
cl_addr.sin_port = htons(0);
if (bind(sock, (struct sockaddr*) &cl_addr, sizeof(cl_addr)) < 0)
sys_err("klient: nie mo偶na nada膰 gniazdku lokalnego adresu");
...
n=sendto(sock, "test", strlen("test"), &serv_addr, sizeof(serv_addr));
if (n != strlen("test")) {
/* b艂膮d wysy艂ania */
...
}
...
close(sock);
exit(0);
}
Sieciowe Systemu Operacyjne  UNIX 10-8
11. Zaawansowane zagadnienia dotycz膮ce gniazd Funkcje wysy艂ania i odbierania danych
Zaawansowane zagadnienia dotycz膮ce gniazd
Funkcje wysy艂ania i odbierania danych
#include
#include
ssize_t readv(int fildes, const struct iovec *iov, int iovcnt);
ssize_t writev(int fildes, const struct iovec *iov, int iovcnt);
#include
#include
ssize_t recvmsg(int s, struct msghdr *msg, int flags);
ssize_t sendmsg(int s, const struct msghdr *msg, int flags);
struct msghdr {
caddr_t msg_name; /* opcjonalny addres */
int msg_namelen; /* wielko艣膰 addresu */
struct iovec *msg_iov; /* tablica fragment贸w danych */
int msg_iovlen; /* liczba element贸w msg_iov */
caddr_t msg_accrights;
int msg_accrightslen;
}
" readv() i writev() pozwalaj膮 zminimalizowa膰 konieczno艣膰 kopiowania
fragment贸w danych z pami臋ci do bufora pami臋ci, kt贸ry by艂by u偶yty
w standardowych funkcjach read() i write().
" readmsg() i sendmsg() pozwalaj膮 na minimalizacj臋 kopiowania da-
nych w przypadku komunikacji UDP (mo偶na ich u偶y膰 zamiast re-
cvfrom() i sendto()).
Sieciowe Systemu Operacyjne  UNIX 11-1
11. Zaawansowane zagadnienia dotycz膮ce gniazd Zwielokrotnione wej艣cie/wyj艣cie
Zwielokrotnione wej艣cie/wyj艣cie
" Pisanie serwer贸w wsp贸艂bie偶nych wymaga obs艂ugi wielu klient贸w jed-
nocze艣nie.
" Najpro艣ciej, cho膰 wcale nie najefektywniej  dla ka偶dego klienta uru-
chamia膰 osobny proces serwera.
" Obs艂uga wszystkich klient贸w przez jeden serwer  nie mo偶na sobie
pozwoli膰 na blokowanie serwera w oczekiwaniu na dane od jednego
z klient贸w, podczas gdy gotowe s膮 ju偶 dane od innego.
Mo偶liwe wyj艣cia z sytuacji:
" korzystanie z gniazd nieblokuj膮cych (u偶ycie fcntl(FNDELAY) lub
ioctl(FIONBIO))).
 aktywne odpytywanie, kt贸re gniazdo jest gotowe,
 sprawdzanie warto艣ciEWOULDBLOCKprzed ka偶d膮 operacj膮 mog膮-
c膮 zablokowa膰 proces (read(), accept() itp.)
" korzystanie z asynchronicznego wej艣cia/wyj艣cia
 przechwytywanie sygna艂贸w jest kosztowne,
 otrzymanie sygna艂u nie informuje o tym kt贸ry deskryptor jest
gotowy do odczytu/zapisu  trzeba przebada膰 wszystkie.
" korzystanie z funkcji select() lub poll()
 pozwala okre艣li膰 list臋 deskryptor贸w, kt贸re nas interesuj膮,
 czeka na gotowo艣膰 dowolnego z nich w spos贸b bierny (umiesz-
czaj膮c proces w kolejce oczekuj膮cych na spe艂nienie warunku),
 mo偶e zosta膰 zako艅czona po up艂ywie zadanego czasu, nawet je艣li
偶aden z deskryptor贸w nie jest gotowy do zapisu/odczytu.
Sieciowe Systemu Operacyjne  UNIX 11-2
11. Zaawansowane zagadnienia dotycz膮ce gniazd Zwielokrotnione wej艣cie/wyj艣cie
Funkcja select()
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *errorfds, struct timeval *timeout);
void FD_ZERO(fd_set *fdset);
void FD_SET(int fd, fd_set *fdset);
void FD_CLR(int fd, fd_set *fdset);
int FD_ISSET(int fd, fd_set *fdset);
" Listy deskryptor贸w s膮 upakowane w odpowiednich zmiennych
readfds,writefdsierrorfds, po 1 bit na deskryptor;
" Do manipulowania tymi listami s艂u偶膮 makra takie, jakFD_ZERO, ze-
ruj膮ce list臋, czyFD_SET, ustawiaj膮ce bit odpowiedaj膮cy podanemu
deskryptorowi pliku, gniazda, strumienia FIFO itp.
" Je艣li lista jest pusta, mo偶na zamiast niej poda膰 wskaznik NULL;
" Strukturatimeoutokre艣la maksymalny czas oczekiwania na dost臋p-
no艣膰 okre艣lonych deskryptor贸w.
struct timeval {
long tv_sec; /* sekundy */
long tv_usec; /* mikrosekundy */
};
Spos贸b interpretowania tego czasu:
 Powr贸膰 natychmiast, je艣li 偶aden deskryptor nie jest gotowy:
struktura wskazywana przeztimeoutwype艂niona zerami;
 Czekaj zadany czas: je艣li warto艣ci w*timeoutnie s膮 obie r贸wne
zero;
 Czekaj w niesko艅czono艣膰 (a偶 kt贸ry艣 z deskryptor贸w b臋dzie go-
t贸w):timeout == NULL.
Sieciowe Systemu Operacyjne  UNIX 11-3
11. Zaawansowane zagadnienia dotycz膮ce gniazd Zwielokrotnione wej艣cie/wyj艣cie
Warto艣膰 zwracana przez funkcj臋 select() okre艣la liczb臋 deskryptor贸w, kt贸-
re s膮 gotowe do wykonania 偶膮danej operacji:
" -1: b艂膮d funkcji;
" 0: 偶aden deskryptor nie jest got贸w, funkcja zako艅czy艂a si臋 z powodu
przekroczenia maksymalnego czasu oczekiwania;
" > 0: liczba deskryptor贸w.
Je艣li cho膰 jeden deskryptor jest got贸w, nale偶y sprawdzi膰 kt贸ry, wo艂aj膮c
w p臋tli makroFD_ISSET:
while (1) {
wait.tv_sec=5;
wait.tv_usec=0;
FD_ZERO(&rd_templ);
FD_SET(0, &rd_templ); /* stdin */
FD_SET(sock, &rd_templ); /* gniazdko */
max = sock; /* najwy偶szy numer deskryptora wart sprawdzania */
n=select(max, &rd_templ, NULL, NULL, &wait);
if (nb>0) {
int i;
for (i=0; i<=max; i++) {
if FD_ISSET(i, &rd_templ) {
...
... read(i, ..., ...); /* deskryptor nr i jest got贸w do odczytu */
...
}
} /* for */
} /* while */
W systemie Linux i niekt贸rych innych, zmiennatimeoutpo wyj艣ciu z se-
lect() zawiera czas pozosta艂y do zako艅czenia funkcji gdyby 偶aden z de-
skryptor贸w nie by艂 got贸w do wykonania na nim operacji (czyli zadany
czas minus czas faktycznego oczekiwania), w innych systemach  warto艣膰
jest nieokre艣lona. Dlatego zawsze trzeba t臋 zmienn膮 inicjowa膰 tu偶 przed
wywo艂aniem select().
Sieciowe Systemu Operacyjne  UNIX 11-4
12. Funkcje RPC
Funkcje RPC
RPC  Remote Procedure Call  mechanizm u艂atwiaj膮cy pisanie aplikacji
sieciowych.


klient serw r
e

funkcj funkcj
a a

wo! aj c wywo! ywana
a


Lokalne w ! nie funkcji
ywo a


klient serw r
e


funkcj
a
funkcj
a


wo! aj c
a
wywo! ywana


kad! b k klient kad! b k s rw ra
u e a u e e e


funkcj
e
funkcj
e




trans rt
po owe
trans rt
po owe

sie

Wywo! anie funkcji z u iem RPC
偶yc
" Przy wywo艂aniu lokalnym, funkcja wo艂aj膮ca i funkcja wywo艂ywa-
na znajduj膮 si臋 w jednym obszarze adresowym (jednym lub kilku
segmentach pami臋ci, ale znajduj膮cych si臋 w przestrzeni adresowej
programu).
" Przy wywo艂aniu zdalnym, we wsp贸lnej przestrzeni adresowej znaj-
duj膮 si臋 odpowiednio: w kliencie: funkcja wo艂aj膮ca i kad艂ubek klienta
(zast臋puj膮cy funkcj臋 wo艂an膮), w serwerze: wykonywana funkcja oraz
jej kad艂ubek, pobieraj膮cy argumenty z sieci i przekazuj膮cy przez sie膰
wyniki.
Sieciowe Systemu Operacyjne  UNIX 12-1
12. Funkcje RPC
Fragmenty programu generowane automatycznie:
" funkcje-kad艂ubki klienta (client stub)
" funkcje-kad艂ubki serwera (server stub)
" funkcje pomocnicze konwersji typ贸w danych
" pliki nag艂贸wkowe
a tak偶e:
" szkielet aplikacji serwera
" plik makefile u艂atwiaj膮cy kompilacj臋 ca艂o艣ci
Fragmenty programu konieczne do napisania:
" funkcje klienta
" funkcje serwera
" specyfikacja interfejsu klient-serwer i u偶ywanych typ贸w danych
Specyfkacja interfejsu jest w rzeczywisto艣ci sformalizowan膮 deklaracj膮
wszystkich funkcji serwera, kt贸re mog膮 by膰 wo艂ane przez klienta, a tak偶e
typ贸w danych, u偶ywanych jako argumenty lub warto艣ci tych funkcji.
Przyk艂adowa specyfikacja w pliku prog.x:
const MAX = 256;
struct record {
string name;
int val;
char initial;
};
program PROG {
version PRVERS {
record GETNAME(string) = 1;
record GETPHONE(int) = 2;
int ADDRECORD(record) = 3;
} = 1;
} = 0x200000001;
Sieciowe Systemu Operacyjne  UNIX 12-2
12. Funkcje RPC
Po przetworzeniu tego pliku programemrpcgen, uzyskujemy pliki:
" prog.h  plik nag艂贸wkowy, zawieraj膮cy dyrektywy#definedla sta-
艂ych takich jakMAX, a tak偶e prototypy funkcji i kad艂ubk贸w.
" prog clnt.c  funkcje-kad艂ubki klienta.
W przyk艂adzie z poprzedniego slajdu b臋d膮 to funkcje:
record * getname_1(char **argp, CLIENT *clnt);
record * getphone_1(int *argp, CLIENT *clnt);
int * addrecord_1(record *argp, CLIENT *clnt);
" prog svc.c  szkielet aplikacji serwera, zawieraj膮cy funkcj臋 main()
funkcj臋  sortuj膮c膮 wywo艂ania przychodz膮ce z sieci na konkretne
funkcje-kad艂ubki serwera.
" prog server.c  kad艂ubki funkcji serwera, dekoduj膮ce dane wej艣ciowe
i wywo艂uj膮ce w艂a艣ciwe funkcje przetwarzaj膮ce te dane. Na przyk艂ad:
record * getname_1(char **argp, struct svc_req rqstp)
{
static record result;
/*
* insert server code here
*/
return (&result);
}
" prog xdr.c  funkcje konwersji typ贸w danych. Przyk艂adowo:
bool_t xdr_record(register XDR *xdrs, record *objp)
{
if (!xdr_string(xdrs, &objp->name, MAX))
return (FALSE);
if (!xdr_int(xdrs, &objp->val))
return (FALSE);
if (!xdr_char(xdrs, &objp->initial))
return (FALSE);
return (TRUE);
}
" makefile.prog, pozwalaj膮cy skompilowa膰 ca艂o艣膰 po wywo艂aniu ko-
mendymake.
Sieciowe Systemu Operacyjne  UNIX 12-3
12. Funkcje RPC Standard XDR
Standard XDR
R贸偶ne typy danych s膮 przezentowane w r贸偶nych architekturach system贸w
w odmienny spos贸b:
" Typ  integer , czyliint:
 PC/MSDOS: 2 bajty, LSB (little-endian)
 PC/UNIX: 4 bajty, LSB (little-endian)
 Sparc/UNIX: 4 bajty, MSB (big-endian)
 Alpha/UNIX: 8 bajt贸w, MSB (big-endian, 64-bitowy procesor)
" Typ wskaznikowy,
" Tablice i struktury.
Potrzebne s膮 funkcje konwersji!
" 1.  ka偶dy z ka偶dym
 jak zachowa si臋 program po wprowadzeniu na rynek nowego pro-
cesora?
 jaki ma to wp艂yw na wielko艣膰 programu?
 na efektywno艣膰 dzia艂ania?
" 2. jeden wsp贸lny standard i zestaw procedur konwersji dla wszysyt-
kich typ贸w lokalnych
 skalowalno艣膰?
 wielko艣膰 programu?
 efektywno艣膰 dzia艂ania?
" wsp贸lny standard: XDR  eXternal Data Representation
Sieciowe Systemu Operacyjne  UNIX 12-4
12. Funkcje RPC Standard XDR
Funkcje XDR
" Standard pozwalaj膮cy przenosi膰 dane r贸偶nych typ贸w pomi臋dzy kom-
puterami o r贸偶nych architekturach wewn臋trznych.
" Funkcje xdr dokonuj膮 serializacji lub deserializacji danych, czyli
przekszta艂cenia struktur, z kt贸rych korzysta program, na p艂aski stru-
mie艅 danych, kt贸ry mo偶e by膰 przes艂any przez sie膰, a nast臋pnie od-
tworzenie z niego odpowiadaj膮cych mu struktur wyj艣ciowych.
" W bibliotekach xdr znajduj膮 si臋 funkcje konwersji dla wszyst-
kich typ贸w podstawowych, takich jak char, int, long, short,
unsigned int(u_int) i pozosta艂e, zmiennoprzecinkowe typyfloat
idouble, a tak偶e typvoidienum.
" Dodatkowo, w bibliotekach znajduj膮 si臋 funkcje pozwalaj膮ce budo-
wa膰 z typ贸w podstawowych inne typu, takie jak unie, tablice, wskaz-
niki i odwo艂ania, a tak偶e 艂a艅cuchy tekstowe i ci膮gi bajt贸w.
" Funkcje przetwarzaj膮ce struktury generowane s膮 przezrpcgenze
specyfikacji aplikacji, a ich dzia艂anie polega na wywo艂aniu po kolei
odpowiednich funkcji XDR dla wszystkich element贸w struktury.
Sieciowe Systemu Operacyjne  UNIX 12-5
12. Funkcje RPC RPC w modelu OSI/ISO
RPC w modelu OSI/ISO



7 zastosowa膰


aplikacja



6 prezentacji

xdr


5 sesji

rpc

4 sieciowa



tcp udp


3 transportowa

ip

2 !  cza

interfejs


fizyczny
1 fizyczna


sie fizyczna (ethernet, point-to-point, atm, itp.)
Sieciowe Systemu Operacyjne  UNIX 12-6
12. Funkcje RPC Portmapper
Portmapper
" W typowej kompunikacji TCP/UDP serwery s膮 identyfikowane przez
numer portu, czytany z pliku /etc/services lub uzyskiwany za po-
moc膮 us艂ug takich, jak NIS.
" W RPC programy identyfikowane s膮 na poziomie symbolicznym,
przez numer programu i numer wersji programu. Dzi臋ki podzia艂owi
na wersje mog膮 wsp贸艂istnie膰 starsze i nowsze implementacje r贸偶nych
protoko艂贸w sieciowych, np. istotnie si臋 od siebie r贸偶ni膮ce NFS v2
i NFS v3.
" T艂umaczeniem nazw/numer贸w RPC na numery port贸w TCP/UDP
zajmuje si臋 program/us艂ugaportmap.
" W implementacjach RPC niezale偶nych od warstwy transportowej
(pozwalaj膮cych korzysta膰 nie tylko z TCP/UDP), abstrakcyjne ad-
resy (nazwy/numery program贸w) s膮 t艂umaczone na parametry po-
trzebne warstwie transportowej przez us艂ug臋/programrpcbind.
" Zar贸wnoportmapjak irpcbindmusz膮 zosta膰 zlokalizowane z po-
mini臋ciem mechanizm贸w RPC  obie te us艂ugi korzystaj膮 z portu
numer 111.
Komunikacja RPC pomi臋dzy klientem a serwerem odbywa si臋 w nast臋-
puj膮cy spos贸b:
" Serwer RPC po uruchomieniu 艂膮czy si臋 z portmapperem i rejestruje
w nim sw贸j adres (w warstwie transportowej) powi膮zany z numerem
programu i wersji. S艂u偶y do tego funkcja registerrpc().
" Klient RPC, chc膮c uzyska膰 po艂膮czenie z serwerem, 艂膮czy si臋 z port-
mapperem i dowiaduje, pod jakim adresem znajduje si臋 偶膮dany pro-
gram.
" Po uzyskaniu adresu serwera, klient nawi膮zuje po艂膮czenie z serwe-
rem i wysy艂a 偶膮danie wywo艂ania funkcji, a serwer zwraca wyniki. Do
wywo艂ania zdalnej procedury potrzebna jest po stronie klienta tylko
jedna funkcja  callrpc().
Sieciowe Systemu Operacyjne  UNIX 12-7
Indeks
accept(), 9-1 9-4, 9-7, 10-1, 11-2 gethostent r(), 8-12
getpid(), 2-4
bind(), 8-7, 8-9, 8-10, 9-3, 9-7, 10-
getppid(), 2-4
1, 10-2
getservbyname(), 8-3, 8-4
getservbyname r(), 8-4
callrpc(), 12-7
getservbyport(), 8-3, 8-4
close(), 3-1, 8-7
getservbyport r(), 8-4
connect(), 9-1, 9-3, 10-1, 10-3, 10-
getservent(), 8-3, 8-4
4
getservent r(), 8-4
dup(), 3-5
htonl(), 7-12, 8-11
dup2 (), 3-5
htons(), 7-12
exec(), 2-4, 2-6, 2-7, 3-5, 6-6, 9-7
ioctl(), 3-2, 11-2
execl(), 2-6
execle(), 2-6
kill(), 2-4
execlp(), 2-6
execv(), 2-6 listen(), 9-1, 9-3, 9-7
execve(), 2-6
main(), 2-6, 12-3
execvp(), 2-6
mknod(), 3-7
exit(), 2-7, 2-9, 5-8, 6-6
mmap(), 6-8
fcntl(), 2-6, 3-2, 3-3, 10-3, 11-2 msgctl(), 4-5
fork(), 2-1, 2-4, 2-5, 6-6, 7-13, 9-2, msgget(), 4-4
9-7 msgrcv(), 4-7
fprintf (), 3-1 msync(), 6-8
fread(), 6-8 munmap(), 6-8
fseek(), 6-8
ntohl(), 7-12, 8-11
ftok(), 4-9
ntohs(), 7-12
fwrite(), 6-8
open(), 3-7
gethostbyaddr(), 8-12
gethostbyaddr r(), 8-12
pclose(), 3-6
gethostbyname(), 8-12
pipe(), 3-1, 8-8
gethostbyname r(), 8-12
poll(), 9-4, 11-2
gethostent(), 8-12
popen(), 3-6
13-1
printf (), 1-5 unlink(), 3-7
read(), 3-1 3-3, 3-7, 8-7, 11-1, 11- wait(), 2-4, 2-9, 3-6, 9-2, 9-5
2 write(), 3-1, 3-2, 3-7, 8-7, 11-1
readmsg(), 11-1 writev(), 11-1
readv(), 11-1
Zajmij (), 5-3, 5-4
recv(), 10-3, 10-4
Zwolnij (), 5-3, 5-4
recvfrom(), 10-1 10-4, 11-1
registerrpc(), 12-7
rresvport(), 8-10
sbrk(), 6-6
select(), 3-3, 9-4, 9-7, 10-3, 11-2
11-4
semctl(), 5-7
semget(), 5-6
semop(), 5-11
send(), 10-3, 10-4
sendmsg(), 11-1
sendto(), 10-1, 10-3, 10-4, 11-1
setgid(), 9-7
setpgrp(), 2-9
setuid(), 9-7
shmat(), 6-5
shmctl(), 6-4, 6-6
shmdt(), 6-5, 6-6
shmget(), 6-3, 6-6
shutdown(), 9-4
sigaction(), 4-7
sighold(), 2-8
sigignore(), 2-8
signal(), 2-8, 5-11
sigpause(), 2-8
sigrelse(), 2-8
sigset(), 2-8
socket(), 8-7, 8-8
socketpair(), 8-7, 8-8
Sieciowe Systemu Operacyjne  UNIX 13-2
Spis tre艣ci
Podstawy systemu UNIX 1-1
System UNIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-1
System plik贸w . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-3
Zarz膮dzanie pami臋ci膮 . . . . . . . . . . . . . . . . . . . . . . . . 1-4
Biblioteki . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-5
U偶ytkownicy . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-6
Prawa dost臋pu . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7
Wej艣cie/wyj艣cie . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-9
Interpreter polece艅  shell . . . . . . . . . . . . . . . . . . . . . 1-9
艢rodowisko programistyczne . . . . . . . . . . . . . . . . . . . . 1-10
Procesy 2-1
Kontekst procesu . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2
Sterowanie procesami z pow艂oki u偶ytkownika . . . . . . . . . . . 2-3
Tworzenie nowych proces贸w . . . . . . . . . . . . . . . . . . . . 2-4
Sygna艂y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-7
Grupy proces贸w . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-9
Ko艅czenie procesu . . . . . . . . . . . . . . . . . . . . . . . . . 2-9
Strumienie pipe i FIFO 3-1
Strumienie pipe . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-1
Pisanie do strumienia pipe . . . . . . . . . . . . . . . . . . . . . 3-2
Czytanie ze strumienia pipe . . . . . . . . . . . . . . . . . . . . 3-3
Sieciowe Systemu Operacyjne  UNIX 14-1
A膮czenie dw贸ch proces贸w strumieniem pipe . . . . . . . . . . . 3-4
Tworzenie strumieni stdout-stdin . . . . . . . . . . . . . . . . . 3-5
Funkcja popen() . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-6
Strumienie FIFO . . . . . . . . . . . . . . . . . . . . . . . . . . 3-7
Korzystanie ze strumieni FIFO . . . . . . . . . . . . . . . . . . 4-1
Kolejki komunikat贸w 4-1
Struktura kolejki w j膮drze systemu . . . . . . . . . . . . . . . . 4-3
Tworzenie kolejek . . . . . . . . . . . . . . . . . . . . . . . . . . 4-4
Usuwanie kolejek . . . . . . . . . . . . . . . . . . . . . . . . . . 4-5
Wysy艂anie komunikat贸w . . . . . . . . . . . . . . . . . . . . . . 4-6
Odbieranie komunikat贸w . . . . . . . . . . . . . . . . . . . . . . 4-7
Selektywne przesy艂anie komunikat贸w . . . . . . . . . . . . . . . 4-8
Funkcja ftok() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-9
Semafory 5-1
Sekcja krytyczna . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1
Problem pi臋ciu filozof贸w . . . . . . . . . . . . . . . . . . . . . . 5-5
Tworzenie semafor贸w . . . . . . . . . . . . . . . . . . . . . . . . 5-6
Usuwanie semafor贸w . . . . . . . . . . . . . . . . . . . . . . . . 5-7
Zajmowanie i zwalnianie semafor贸w . . . . . . . . . . . . . . . . 5-8
Zaj臋cie semafora . . . . . . . . . . . . . . . . . . . . . . . . . . 5-9
Zwolnienie semafora . . . . . . . . . . . . . . . . . . . . . . . . 5-10
Oczekiwanie na zaj臋cie semafora przez inny proces . . . . . . . . 5-11
Sieciowe Systemu Operacyjne  UNIX 14-2
Pami臋膰 wsp贸lna 6-1
Stronicowanie pami臋ci . . . . . . . . . . . . . . . . . . . . . . . 6-1
Segmentacja pami臋ci . . . . . . . . . . . . . . . . . . . . . . . . 6-2
Tworzenie segmentu pami臋ci wsp贸lnej . . . . . . . . . . . . . . 6-3
Usuwanie pami臋ci wsp贸lnej . . . . . . . . . . . . . . . . . . . . 6-4
Korzystanie z pami臋ci wsp贸lnej . . . . . . . . . . . . . . . . . . 6-5
Zarz膮dzanie segmentami pami臋ci przez system . . . . . . . . . . 6-6
Pami臋膰 wsp贸lna widziana przez 2 procesy . . . . . . . . . . . . 6-7
Wsp贸lny dost臋p do plik贸w  mmap() . . . . . . . . . . . . . . . 6-8
Pami臋膰 wirtualna . . . . . . . . . . . . . . . . . . . . . . . . . . 6-9
Pe艂ny diagram stan贸w proces贸w . . . . . . . . . . . . . . . . . . 6-10
Komunikacja sieciowa 7-1
Dostarczanie pakiet贸w: . . . . . . . . . . . . . . . . . . . . 7-2
Dost臋p do medium: . . . . . . . . . . . . . . . . . . . . . . 7-3
Skalowalno艣膰: . . . . . . . . . . . . . . . . . . . . . . . . . 7-3
Model OSI/ISO . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-4
Sie膰 ethernet  warstwa 2 . . . . . . . . . . . . . . . . . . . . . 7-4
Protoko艂y sieciowe IP  warstwa 3 . . . . . . . . . . . . . . . . . 7-5
TCP/UDP  warstwa 4 . . . . . . . . . . . . . . . . . . . . . . 7-5
Przyk艂adowy pakiet . . . . . . . . . . . . . . . . . . . . . . . . . 7-6
Adresy w sieciach IP . . . . . . . . . . . . . . . . . . . . . . . . 7-7
Maski sieciowe i routing . . . . . . . . . . . . . . . . . . . . . . 7-8
Odwzorowanie adres贸w warstw 2 i 3 . . . . . . . . . . . . . . . . 7-9
Sieciowe Systemu Operacyjne  UNIX 14-3
Abstrakcyjny model komunikacji sieciowej . . . . . . . . . . . . 7-10
UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10
TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-10
Identyfikacja po艂膮cze艅 . . . . . . . . . . . . . . . . . . . . . . . 7-11
Problem kolejno艣ci bajt贸w . . . . . . . . . . . . . . . . . . . . . 7-12
Model komunikacji klient serwer . . . . . . . . . . . . . . . . . 7-13
Uproszczony model OSI . . . . . . . . . . . . . . . . . . . . . . 7-13
Protoko艂y sieciowe 8-1
Powi膮zania mi臋dzy us艂ugami a numerami port贸w . . . . . . . . 8-3
T艂umaczenie nazw us艂ug w systemie UNIX . . . . . . . . . . . . 8-4
Przyk艂ad protoko艂u  SMTP . . . . . . . . . . . . . . . . . . . . 8-5
Tworzenie gniazdek . . . . . . . . . . . . . . . . . . . . . . . . . 8-7
Funkcja socket() . . . . . . . . . . . . . . . . . . . . . . . . 8-8
Funkcja socketpair() . . . . . . . . . . . . . . . . . . . . . 8-8
Nadanie nazwy  funkcja bind() . . . . . . . . . . . . . . . 8-9
Us艂ugi t艂umaczenia nazw  DNS/NIS/NIS+ . . . . . . . . . . . 8-11
Komunikacja TCP 9-1
Nawi膮zywanie po艂膮cze艅 TCP . . . . . . . . . . . . . . . . . . . 9-1
Serwery wsp贸艂bie偶ne . . . . . . . . . . . . . . . . . . . . . . . . 9-2
Funkcja connect() . . . . . . . . . . . . . . . . . . . . . . . . . . 9-3
Funkcja listen() . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-3
Funkcja accept() . . . . . . . . . . . . . . . . . . . . . . . . . . 9-4
Sieciowe Systemu Operacyjne  UNIX 14-4
Funkcja shutdown() . . . . . . . . . . . . . . . . . . . . . . . . . 9-4
Serwery samodzielne i uruchamiane przez inetd . . . . . . . . . 9-5
Serwer inetd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-6
Komunikacja UDP 10-1
Funkcje recvfrom() i sendto() . . . . . . . . . . . . . . . . . . . 10-3
Korzystanie z connect() . . . . . . . . . . . . . . . . . . . . . . 10-4
Przyk艂ad serwera protoko艂u TCP . . . . . . . . . . . . . . . . . 10-5
Przyk艂ad klienta protoko艂u TCP . . . . . . . . . . . . . . . . . . 10-6
Przyk艂ad serwera protoko艂u UDP . . . . . . . . . . . . . . . . . 10-7
Przyk艂ad klienta protoko艂u UDP . . . . . . . . . . . . . . . . . 10-8
Zaawansowane zagadnienia dotycz膮ce gniazd 11-1
Funkcje wysy艂ania i odbierania danych . . . . . . . . . . . . . . 11-1
Zwielokrotnione wej艣cie/wyj艣cie . . . . . . . . . . . . . . . . . . 11-2
Funkcja select() . . . . . . . . . . . . . . . . . . . . . . . . 11-3
Funkcje RPC 12-1
Standard XDR . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-4
Funkcje XDR . . . . . . . . . . . . . . . . . . . . . . . . . 12-5
RPC w modelu OSI/ISO . . . . . . . . . . . . . . . . . . . . . . 12-6
Portmapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-7
Indeks 13-1
Spis tre艣ci 14-1
Sieciowe Systemu Operacyjne  UNIX 14-5


Wyszukiwarka

Podobne podstrony:
Systemy Operacyjne Unix Linux solarka2
wstep historia sieciowych system贸w operacyjnych
Systemy Operacyjne Unix Linux solaris1
Uzytkowanie systemu operacyjnego UNIX
Systemy Operacyjne Unix Linux solarka4
MATERIA艁 NA EGZAMIN KONCOWY CZESC 2 Administracja Sieciowymi Systemami Operacyjnymi
MATERIA艁 NA EGZAMIN KONCOWY CZESC 1 Administracja Sieciowymi Systemami Operacyjnymi

wi臋cej podobnych podstron