4 paskaita 2006
DESCRIPTION
4 Paskaita 2006. 2006m. Aplikacinių programų sąsaja(API). Aplikacinių programų sąsaja(API) tai sąsaja, kurią teikia op. sistema, biblioteka ar aplikacija. Jos tikslas-leisti kitoms kompiuterinėms programoms kreiptis tam tikro serviso atlikimo ar duomenų apsikeitimo. - PowerPoint PPT PresentationTRANSCRIPT
Sarafinienė Nijolė 1
4 Paskaita2006
2006m
Sarafinienė Nijolė 2
Aplikacinių programų sąsaja(API)• Aplikacinių programų sąsaja(API) tai sąsaja, kurią teikia op.
sistema, biblioteka ar aplikacija.• Jos tikslas-leisti kitoms kompiuterinėms programoms kreiptis
tam tikro serviso atlikimo ar duomenų apsikeitimo.• Vienas iš pagrindinių API tikslų yra aprašyti tai, kaip
pasiekiamas tam tikras funkcijų rinkinys. Pavyzdžiui, API gali aprašyti, kaip nupiešiami langai ar ikonos ekrane naudojant biblioteką, kuri skirta šiam tikslui. API, kaip ir dauguma sąsajų yra tam tikra abstrakcija.
• API- tai rinkinys protokolų, procedūrų bei įrankių, skirtų programinėms aplikacijoms kurti.
• API palengvina programų sukūrimą, nes teikia paruoštus programų blokus, skirtus tam tikrų veiksmų realizavimui.
• Dauguma operacinių aplinkų teikia vartotojams API, kurias naudodami programuotojai gali kurti aplikacines programas, suderinamas su operacine aplinka.
Sarafinienė Nijolė 3
Sąsajos
Sarafinienė Nijolė 4
Aplikacinių programų sąsaja
• API – tai tam tikra kalba, pranešimų formatai, kurie nusako tai, kaip programos bendrauja su operacine sistema, su kitų programų vykdomomis funkcijomis, su komunikacinėmis sistemomis ar įrenginių tvarkyklėmis.
• Pavyzdžiui, operacinė sistema gali turėti eilę standartinių API, kuriuos vartotojas gali panaudoti vartotojo įvedamų duomenų priėmimui, informacijos išvedimui į ekraną ar failų valdymui.
• Atskira API gali būti skirta palengvinimui programuotojui kuriant langų sistemą, su jų įvairiais elementais (iššokančiais meniu, slankikliais,...)
• API gali būti orientuojama kaip sąsaja skirta tinklinei komunikacijai – duomenų siuntimui per tinklą
• API gali būti orientuojama ir į darbą skirtingose techninėse platformose ar skirtingose operacinėse sistemose.
Sarafinienė Nijolė 5
Aplikacinių programų sąsaja(API)
• API apsprendžia, kaip programuotojai pasinaudoja tam tikra kompiuterio savybe.
• API egzistuoja tiek “Windows” sistemose, tiek failų sistemose, duomenų bazių sistemose, ir, be abejo, tinklinėse sistemose.
• UNIX-orientuotas, su Internetu surištas programavimas naudojasi trimis API: Berkeley Sockets, System V TLI, ir RPC.
• Soketai ir TLI teikia labai panašų funkcionalumą (priėjimą prie TCP ir UDP) , jie naudojami skirtingose UNIX versijose.
• RPC' API (RPC kalba) palaiko tinklines procedūras pasinaudojant Sun's RPC protokolu.
• Microsoft Windows turi į Soketų API panašų API.
Sarafinienė Nijolė 6
Berkeley Soketai • Soketai tai originali tinklinė sąsaja, sukurta BSD-serijos UNIX operacinėms
sistemoms. • Soketas tai galinis komunikavimo taškas, sukuriamas naudojant socket() funkciją, kuri
naudoja du raktinius argumentus – domeną (domain) ir tipą. • Domenas (domain), kuris leidžia bendrauti tinkle yra Internetinis AF_INET.• Naudojami du pagrindiniai Internetinių soketų tipai - STREAM (TCP) ir DGRAM (UDP),
kurie nusako skirtingus bendravimo būdus.• UDP komunikacijoms, kurių metu sujungimas nėra vykdomas, yra naudojami DGRAM soketai.
– Sukūrus DGRAM soketą, jis iš karto gali būti panaudojamas perdavimui UDP paketų, naudojant sendto() funkciją.
– Norint priimti UDP paketus soketas turi būti pririšamas prie lokalaus porto adreso– Pririšus DGRAM soketą prie UDP porto, jis gali būti naudojamas tiek persiuntimui informacijos( sendto()),
tiek priėmimui (recvfrom()). • TCP komunikacijoms, orientuotoms į susijungimus, STREAM naudojami soketai.
– STREAM soketas negali nei siųsti nei priimti duomenų, kol susijungimas nėra įkuriamas.– Susijungimas įkuriamas naudojant connect() funkciją , kurios pagalba aktyvi susijungimo dalyvė bando
sukurti susijungimą.– Sudarius susijungimą, TCP soketai veikia taip kaip UNIX failų deskriptoriai, jie naudojami read(), write(), ir
close() funkcijose.– TCP susijungimas yra nusakomas dviejų galinių taškų pora, o kiekvieną tašką nusako IP adresas bei
portas.– Daug aktyvių soketų gali būti susijungę su tuo pačiu pasyviu soketu.
• Soketų API tui bibliotekines funkcijas, skirtas paieškai DNS serveriuose tam kad kompiuterių vardus pakeisti į Ip adresus ( gethostbyname() funkcija)
Sarafinienė Nijolė 7
System V TLI• System V's Transport Layer Interface (TLI) teikia beveik
identišką funkcionalumą kaip ir Berkeley soketai. • naudoja standartinius Interneto protokolus, taigi TLI aplikacijos gali
bendrauti su Soket API ir atvirkščiai.• t_open funkcija sukuria transportinį galinį komunikavimo tašką,
kuriuo gali manipuliuoti tokios funkcijos kaip t_bind, t_connect, t_snd ir t_rcv, kurios yra analogiškos atitinkamoms Soketų API f-joms, skirsis tik sintaksė. Normalios UNIX operacijos su failais gali būti naudojamos operuojant transportiniais galinio komunikavimo taškais.– “\begin{soapbox} TLI's main claim to superiority is its support for OSI,
but there seems no compelling reason why Sockets couldn't also operate in an OSI environment, if anyone really wanted it to do so. AT&T's desire for a more proprietary networking interface is probably the real driving force behind TLI. Berkeley Sockets remains the API of choice for almost all UNIX-based Internet code.
– \end{soapbox} “
Sarafinienė Nijolė 8
RPC kalba • RPC kalba leidžia programuotojui apibrėžti funkcionalią sąsają
RPC programai, tada sukompiliuoti tai į kelis C kalbos failus naudojant rpcgen programą.
• Vienas iš šių failų yra serveris-shell’as. Kodas gali būti pridedamas tam, kad šis shell’as vykdytų norimas funkcijas. Serveris-shellas yra tada kompiliuojamas siekiant gauti dirbantį serverį.
• Kitas iš šių failų apibrėžia klientą, jis kompiliuojamas į klientinę programą, kuri vykdo tinklines RPC(remote process call) operacijas, naudojant tam tikras funkcijas .
• RPC servisai sukonstruojami reliatyviai paprastai– “A major drawback of the method described above is the inability to re-
create the server shell after it has been modified. This problem can be circumvented by using rpcgen's ability to conditionally include escaped C code in the original source.”
Sarafinienė Nijolė 9
Tinklinių programų sąsaja Jos tikslas – leisti vartotojams kurti tinklines aplikacijas,
kurios bendrauja tarpusavyje.Vartotojui nereikia rūpintis tokiais klausimais:
– Kaip veikia tinklai,– kaip siunčiami duomenys tinklu,– Kaip duomenys paruošiami persiuntimui tinklu.
Programuotojo dispozicijoj rinkinys funkcijų, kurios sudaro aplikacinių programų sąsają su žemesniais lygiais ir nusako pagrindinius veiksmus, reikalingus procesų bendravimui tinkle.
Sarafinienė Nijolė 10
Tinklinių aplikacinių programų sąsaja
• Sąsaja tarp aplikacijos ir tinklo
• Aplikacija gali siųsti/gauti duomenis į/iš tinklo, t.y. komunikuoti.
ApliAplikkaacijacija
Tinklinių programų sąsaja(Tinklinių programų sąsaja( API API ) )
ProtoProtokkololasas A A ProtoProtokkololasas B B ProtoProtokkololasas C C
Sarafinienė Nijolė 11
Sąsajos uždaviniai• Priskirti komunikacijai reikalingus lokalius resursus.• Nusakyti lokalų bei nutolusį galinius komunikavimo
taškus.• Inicijuoti susijungimą (klientinėje pusėje)• Laukti ateinančių susijungimų (serverio pusėje)• Siųsti ar priimti duomenis.• Nustatyti, kada duomenys pasirodė.• Generuoti skubius duomenis.• Apdoroti atėjusius skubius duomenis.• Tvarkingai užbaigti susijungimą. Apdoroti susijungimo
nutraukimą atėjusį iš nutolusio hosto. Nutraukti komunikacijas, įvykus klaidingai situacijai.
• Atlaisvinti resursus pasibaigus susijungimui.
Sarafinienė Nijolė 12
Sisteminiai kreipiniai
Aplikacija 1
Aplikacija n
Aplikacija 2
Aplikacijų kviečiamos sisteminės funkcijos
Operacinės sistemos branduolys, turintis TCP/IP programinę įrangą
Sarafinienė Nijolė 13
4.3BSD
Pirmi bandymai susiję su UNIX 4.2 BSD – kaip “pipe” mechanizmo išplėtimas.
Tarp-procesinio bendravimo pradžia galima laikyti UNIX 4.3 BSD , kuri turi posistemę, skirtą tarp-procesiniam bendravimui.
Soketų mechanizmas buvo sukurtas tikslu užtikrinti procesų tarpusavio bendravimą tinkle.
Soketai apibrėžti kaip galiniai komunikavimo taškai.
Sarafinienė Nijolė 14
Portai
Port 0
Port 1
Port 65535
• Kiekvienas hostas turi 65,536 portus
• Kai kurie portai yra rezervuoti specialioms aplikacijoms– 20,21: FTP– 23: Telnet– 80: HTTP
Soketas užtikrina sąsają adresinei porai IP:portas
Sarafinienė Nijolė 15
Failai ir srautai
Pagrindinė abstrakcija – failas – arba nuosekli baitų seka – baitų srautas.
Pavyzdys :Skaitymas iš klaviatūros, mainai su tinkline korta,
rašymas į ekraną, komunikacija su kitu procesu naudojant “pipe” mechanizmą, ir visa kita – tai veiksmai su failais.
Sarafinienė Nijolė 16
Bazinės UNIX funkcijos
• open Paruošti įrenginį ar failą įvedimo /išvedimo oper.
• close Baigt naudoti anksčiau atidarytą įrenginį ar failą.
• read Paimti duomenis iš įvedimo įrenginio ar failo ir padėti juos į aplikacinės programos atmintį.
• Write Perduoti duomenis iš aplikacinės programos atminties į išvedimo įrenginį ar failą.
• lseek Pasislinkti iki specialios pozicijos faile ar įrenginyje. (ši operacija taikoma failams ar
įrenginiams, kurie surišti su disku).• Ioctl Kontroliuoti įrenginį ar progr. įrangą, kuri
kreipiasi į jį (pavyzdžiui, nusakyti buferio dydį)
Sarafinienė Nijolė 17
Soketo apibrėžimas
Soketas yra tam tikra abstrakcija, atitinkanti galinius komunikavimo taškus.
• Dauguma aplikacijų, naudojančių TCP/IP sukuria atitinkamo tipo soketą ir vykdo seriją operacijų su soketais.
• Operacijos, kurios yra vykdomos su soketais:– kontrolės operacijos( tai porto numerio surišimas su soketu,
ryšio inicijavimas arba priėmimas sokete arba soketo suardymas)
– duomenų perdavimo operacijas(duomenų rašymas / skaitymas per soketą kitai aplikacijai).
– Statusą nusakančios operacijos(Tokios kaip kad IP adreso susijusio su soketu suradimas).
• Visuma operacijų, kurios gali būti vykdomos su soketais sudaro Soketų API (Aplikacijų programinį interfeisą-Application Programming Interface).
Sarafinienė Nijolė 18
Soketo sukūrimas C: socket()• int s = socket(domain, type, protocol);
– s: soketo deskriptorius (sveikas skaičius (kaip ir failų-atveju) – domain: komunikacinis domenas
• pav., AF_INET (IPv4 protokolui) – dažniausiai naudojama
– type: komunikacijų tipas• SOCK_STREAM: patikimas, 2-krypčių sujungimu pagrįstas susijungimas• SOCK_DGRAM: nepatikimas, be sujungimo.• SOCK_RAW : teikia priėjimą prie vidinio tinklinio protokolo bei sąsajos.
Prieinamas tik “root” vartotojui.
– protocol: nusakomas protokolas (faile /etc/protocols ) – paprastai nurodomas 0
• Kreipinys socket() grąžina failų deskriptorių, kurį galima naudoti tolimesniuose veiksmuose
Sarafinienė Nijolė 19
Deskriptorių lentelė
• Nors soketai turi tam tikrų specifinių savybių, jie yra labai panašūs į jums gerai pažįstamus failų deskriptorius.
• Pavyzdžiui, kai panaudojate open() kreipinį, šis jums gražina failų deskriptorių, kurį vėliau galima panaudoti programose operacijose read(), write() lseek() close()su šiuo failu.
• Sukūrus soketą, jis yra panašus į failo deskriptorių, jūs galite naudoti tas pačias I/O funkcijas- skaitymui, rašymui ar soketo uždarymui .
Sarafinienė Nijolė 20
Failų deskriptorių lentelė
Sarafinienė Nijolė 21
Socketo deskriptoriaus duomenų struktūra
DesDeskkriptorriptoriųių lentelėlentelė
0
1
2
3
4
Family: PF_INETFamily: PF_INETService: SOCK_STREAMService: SOCK_STREAMLocal IP: 111.22.3.4Local IP: 111.22.3.4Remote IP: 123.45.6.78Remote IP: 123.45.6.78Local Port: 2249Local Port: 2249Remote Port: 3726Remote Port: 3726
Family: PF_INETFamily: PF_INETService: SOCK_STREAMService: SOCK_STREAMLocal IP: 111.22.3.4Local IP: 111.22.3.4Remote IP: 123.45.6.78Remote IP: 123.45.6.78Local Port: 2249Local Port: 2249Remote Port: 3726Remote Port: 3726
Sarafinienė Nijolė 22
skirtumai tarp soketų bei atidarytų failų
• Negalima naudoti lseek(2) funkcijos su soketais(kaip ir su pipe)
• Soketai gali turėti adresus, susijusius su jais. Failai ir pipe neturi tinklinių adresų.
• Soketai turi būti tinkamam būvyje norint vykdyti įvedimą/išvedimą. Atidaryti failai atvirkščiai gali būti tiek skaitomi tiek į juos galima rašyti.
Sarafinienė Nijolė 23
Soketų charakteristikos:
• Soketais nusakomas dviejų krypčių komunikacinis kelias.• Soketas apibrėžiamas nusakant jo tipą• Soketas egzistuoja tam tikrame domene.• Soketai nereikalauja bendrų protėvių komunikavimo
užtikrinimui tarp procesų.Aplikacinė programa užprašo operacinės sistemos sukurti soketą
kai jai jo prireikia.Operacinė sist sukurdama soketą grąžina sveiką skaičių.
Sukuriant soketą, jis gali būti nepririštas prie specifinio nutolusio adreso.
Aplikacijų programai leidžiama pateikti paskirties adresą kiekvieną kartą panaudojant soketą.
Sarafinienė Nijolė 24
Veiksmai su soketais
• Sukurti soketą ir surišti jį su vardu.
• Sudaryti sujungimus ir priimti susijungimus.
• Siųsti ir priimti duomenis
• Nutraukti soketų operacijas
• Transliuoti tinklinius adresus
Sarafinienė Nijolė 25
Soketų komunikaciniai domenai
• Soketai, kurie pasižymi bendrom komunikacinėmis savybėmis, tokiomis kaip bendrai priimtini vardai, protokolai, adresų formatai, yra grupuojami į atskirus komunikacinius domenus.
• Komunikacinis domenas kartais interpretuojamas kaip vardų ar adresų erdvė.
• Komunikacinis domenas apima:– Vardų manipuliavimo ir interpretavimo taisykles.– Adresų formatų rinkinį, nusakantį adresų šeimą.– Rinkinį protokolų, sudarantį protokolų šeimą.
Sarafinienė Nijolė 26
Adresų formatas• Adresų formatas nusako kokios taisyklės yra naudojamos
sukuriant atitinkamo formato tinklinius adresus. Pavyzdžiui, Interneto komunikaciniame domene 32 bitų reikšmė, žyminti tinklinį hosto adresą yra sudaroma pagal taisykles, kurios įvertina tai, kokiame tinkle hostas randasi.
• Kiekvienas komunikacinis domenas turi skirtingas taisykles, kurios nusako, koks soketo vardas yra teisingas ir kaip šis vardas turi būti interpretuojamas. Soketą sukūrus, jam gali būti suteikiamas vardas, kuris sudaromas pagal konkretaus domeno taisykles. Pavyzdžiui, UNIX komunikaciniame domene gali būti /dev/pav.
• Soketai gali keistis duomenimis tik su to paties domeno soketais.
Sarafinienė Nijolė 27
Komunikacinis domenas
4.3BSD soketų sąsajoje yra palaikomi trys skirtingi komunikaciniai domenai:UNIX domenas, skirtas komunikacijoms
pačioje sistemoje palaikyti,
Internet domenas, kuris naudojamas procesams komunikuojant Internete,
NS domenas, kuris naudojamas kai procesai komunikuoja remdamiesi Xerox standartiniais komunikaciniais protokolais.
Sarafinienė Nijolė 28
Domenas – adresų šeima
Pasirinktas domenas nusako atitinkamą, sąsajoje naudojamą adresų šeimą:
/usr/include/sys/socket.h faile nurodomos šios dažniausiai naudojamos adresų šeimos:
AF_UNIX Žymi UNIX operacinėje sistemoje įprastus kelio vardus.AF_INET Žymi ARPA Interneto adresus. AF_NS Skirtas XEROX Network Systems protokolui.
Sarafinienė Nijolė 29
Pavyzdys
#include <sys/types.h>#include <sys/socket.h>s1 = socket(AF_UNIX, SOCK_DGRAM,0);s2 = socket(AF_INET, SOCK_STREAM, 0);
Jei protokolas nėra nusakomas ( 0 ), tai sistema parinks tinkamą protokolą, iš tų kurie tinka pagal komunikacinį domeną bei soketo tipą.
“/usr/include/sys/types.h file defines data types used in system source code” “ /usr/include/sys/socket.h Socket header files contain data definitions, structures, constants, macros, and options
used by socket subroutines. An application program must include the appropriate header file to make use of structures or other information a particular socket subroutine requires”.
Sarafinienė Nijolė 30
Adresų šeimos
• Pirmas iš socket ()kreipinyje nurodomų parametrų yra komunikacinis domenas, kuris kartu žymi ir adresų šeimą.
• Adresų šeima nusako operacinei sistemai kaip interpretuoti pateikiamus adresus.
• Kreipinyje socket kaip adresinės šeimos (AF) gali būti naudojamos AF_UNIX (UNIX), AF_INET (Internet), AF_NS (Xerox Network Systems), ar AF_NDD (AIX Network Device Drivers) .
Sarafinienė Nijolė 31
UNIX adresų šeima
AF_UNIX• Ji užtikrina komunikacijas tarp procesų, kurie sukasi
toje pačioje operacinėje sistemoje. Adresų šeima specifikuojama kaip AF_UNIX. Soketo vardas- tai ASCII simbolių eilutė, kurios max ilgį apsprendžia naudojama mašina.
• UNIX domene soketui suteikiamas kelio vardas failų sistemos vardų erdvėje. Failų sistemoje sukuriamas soketui mazgas ir kiti procesai gali kreiptis į soketą pateikdami tinkamą kelio vardą.
• UNIX domenų vardai leidžia komunikuoti bet kuriems dviems procesams, kurie dirba toje pačioje failų sistemoje.
Sarafinienė Nijolė 32
Interneto adresų šeima
• Uždavus adresų šeima AF_INET yra užtikrinamos komunikacijos tarp lokalaus proceso ir proceso , besisukančio nutolusiame hoste.
• Interneto domenas reikalauja, kad TCP/IP protokolai būtų instaliuoti sistemoje. Interneto domene soketo vardą sudaro 32 bitų IP adresas ir 16 bitų porto adresas.
• Interneto domenas remiasi standartiniais protokolais IP/TCP/UDP.
• Interneto domenas leidžia komunikacijas tarp dviejų mašinų.
Sarafinienė Nijolė 33
Protokolų šeimaKomunikacinis domenas indikuoja protokolų šeimą
(PF), kuri bus naudojama su sukurtu soketu.Kai kurios protokolų šeimos turi keletą protokolų,
nusakančių tą patį serviso tipą. Programuotojas turi turėt žinių apie protokolų šeimas ir
apie tai kokį servisą teikia atitinkamas protokolas. PF_UNIX UNIX sistemos vidiniai protokolai PF_INET Interneto Protokolai (IPv4)PF_INET6 Interneto Protokolai (IPv6)
Sarafinienė Nijolė 34
Du pagrindiniai soketų tipai• SOCK_STREAM
– TCP
– Patikimas pristatymas– Garantuota pristatymo
tvarka– Orientuotas į susijungimą– dvipusis
• SOCK_DGRAM– UDP
– Nepatikimas pristatymas– Negarantuota eilės tvarka– Neorientuotas į susijungimus – Gali siųsti arba priimti
App
socket3 2 1
Dest.
App
socket3 2 1
D1
D3
D2
Sarafinienė Nijolė 35
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h> main(int argc,char **argv) { int z; /* Status return code */ int s[2]; /* Pair of sockets */ z = socketpair(AF_UNIX,SOCK_STREAM,0,s);if ( z == -1 ) { fprintf(stderr,"%s: socketpair(AF_LOCAL,SOCK_STREAM,0)\n", strerror(errno)); return 1; /* Failed */ } /* Report the socket file descriptors returned */ printf("s[0] = %d;\n",s[0]); printf("s[1] = %d;\n",s[1]);return 0; }soketų sukūrimas yra beveik toks pat paprastas kaip pipe jungties sukūrimas Atsakymai:./soc_pora.exes[0] = 5;s[1] = 4;
Sarafinienė Nijolė 36
Soketas
Kai soketas yra sukurtas, tai dar neturi savyje detalios informacijos apie tai, kaip jis bus naudojamas.
Socket’as neturi savyje informacijos apie protokolo portų numerius ar lokalių mašinų ar nutolusių mašinų IP adresus.
Ryšio galinis-taškas = <IP adresas> + <protokolo-porto-numeris>
Sarafinienė Nijolė 37
Bendra adresinė struktūra
Apibendrintas adreso formatas susideda iš poros:
(adreso šeima, šios šeimos galinio taško adresas)
Soketo adresinė struktūra yra sockaddr , kuri susideda iš tokių laukų:
struct sockaddr { sa_family_t sa_family; /* adreso šeima AF_xxx */ char sa_data[14]; /* iki 14 baitų nusakančių adresą */ };
Bendra soketo adresinė struktūra yra aprašyta <sys/socket.h> faile.sa_data uždavimo forma yra surišta su atitinkama protokolų šeima.
Sarafinienė Nijolė 38
AF_INET adresų struktūraProgramos, kurios išimtinai naudoja TCP/IP protokolus gali
išskirtinai naudoti struktūrą, taikomą protokolui IPv4 sockaddr_in;
Nenaudoja sockaddr struktūros, nes joje sa_data turi nurodyt galinį adresą ir porto nr. soketo. Nesinori sa_data formuoti rankiniu būdu.
Naudojama struktūra struct sockaddr_in ("in" žymi “Internet".)struct sockaddr_in { short int sin_family; // Address family unsigned short int sin_port; // Port number struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr }; Šioje struktūroje naudojama adreso struktūra:
struct in_addr { in_addr_t s_addr; /* 32-bit IPv4 address */
/* network byte ordered */ };
Sarafinienė Nijolė 39
Pastabos
Ši struktūra palengvina kreipimąsi į soketo adreso elementus.
sin_zero (kuris naudojamas siekiant suvienodinti jos ilgį su bendra struktūra struct sockaddr) turi būti nustatoma į nulius naudojant f-ją memset().
nuoroda į struct sockaddr_in gali būti naudojama vietoje nuorodos į struct sockaddr ir atvirkščiai.
sin_family atitinka sa_family struktūroje sockaddr ir turi būti nustatomas į "AF_INET".
sin_port ir sin_addr turi būti Network Byte Order!- labiau reikšminiai baitai - pirmi
Sarafinienė Nijolė 40
struct sockaddr• Bendra:
struct sockaddr {u_short sa_family;char sa_data[14];
};
sa_family • Nusako, kuri adresų
šeima yra naudojama.
sa_data• Apsprendžia, galinį
komunikavimo tašką.
• Internetui-orientuota:struct sockaddr_in {
short sin_family;u_short sin_port;struct in_addr sin_addr;char sin_zero[8];
};sin_family = AF_INETsin_port: portas # (0-
65535)sin_addr: IP-adresassin_zero: nenaudojama
Sarafinienė Nijolė 41
Adresinės struktūros
Keturios su soketais surištos funkcijos perduoda soketo adresinę struktūrą iš proceso branduoliui (kernel): bind, connect, sendto, ir sendmsg
Jos perduoda soketo adresinę struktūrą per šių funkcijų argumentus, jų saraše nurodant nuorodą į struktūrą bei struktūros ilgį.
Penkios su soketais surištos funkcijos perduoda soketo adresinę struktūrą iš branduolio (kernel) – procesui:accept, recvfrom, recvmsg, getpeername, ir getsockname, visose jose yra nurodoma perduodamos struktūros ilgis.
Sarafinienė Nijolė 42
Adresinių struktūrų palyginimas
visos soketų adresinės struktūros turi 1baito ilgio struktūros ilgio lauką, adresinė šeima užima 1 baitą. Dvi iš šių soketų adresinių struktūrų yra fiksuoto ilgio, o Unix domeno struktūra ir datalink struktūra yra kintamo ilgio.
Sarafinienė Nijolė 43
Soketo surišimas su lokaliu protokolo adresu
Funkcija bind soketui priskiria lokalų protokolo adresą. Interneto protokolų atveju, protokolo adresą nusako kombinacija 32 bitų IPv4 adreso (arba 128 bitų IPv6 adreso), kartu su 16 bitų TCP arba UDP porto numeriu.
Surišimas reikalingas tais atvejais, jei, pavyzdžiui, yra ruošiamasi naudoti listen() klausymui ateinančių sujungimų.
int bind(int sockfd, const struct sockaddr *name, socklen_t namelen);
bind() suriša soketą su galiniu komunikavimo tašku.Kai soketas yra sukuriamas, jis egzistuoja vardų erdvėje, kurią nusako
adresų šeima.bind() f-ja suriša soketą, nurodomą deskriptoriumi su adresine struktūra,
kuri talpina informaciją apie jūsų adresą, tai yra, portą ir IP adresą.Jei surišimas pavyksta yra grąžinamas 0, -1 indikuoja klaidą.Startuojant serveriams, jie pririša atitinkamus soketus prie gerai žinomų
portų.TCP klientams soketo surišimas su adresu nėra būtinas. Operacinė sistema pati
vykdo šį surišimą vykdydama connect kreipinį.
Sarafinienė Nijolė 44
PastabosSavojo IP adreso ir porto uždavimas gali būti
automatizuotas:my_addr.sin_port = 0; // choose an unused port at
random my_addr.sin_addr.s_addr = INADDR_ANY; // use my IP
address
Nustatydami my_addr.sin_port lygų nuliui, pranešate bind() parinkti laisvą portą.
Nustatant my_addr.sin_addr.s_addr į INADDR_ANY, liepiate automatiškai įrašyti mašinos IP adresą (kurioje šis procesas sukasi). INADDR_ANY nereikia užduoti, kad būtų “Network Byte Order”! : INADDR_ANY realiai yra nuliai
Sarafinienė Nijolė 45
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* This function reports the error */
static void bail(const char *on_what) {
fputs(on_what,stderr);
fputc('\n',stderr);
exit(1); }
Soketo sukūrimas ir surišimas su portu
Sarafinienė Nijolė 46
int main(int argc,char **argv) {
int z;
struct sockaddr_in adr_inet;/* AF_INET */
int len_inet; /* length */
int sck_inet; /* Socket */
/* Create a Socket */
sck_inet = socket(AF_INET,SOCK_STREAM,0);
if ( sck_inet == -1 )
bail("socket()");
/* Establish address */
memset(&adr_inet,0,sizeof adr_inet);
adr_inet.sin_family = AF_INET;
adr_inet.sin_port = htons(9000);
adr_inet.sin_addr.s_addr = inet_addr("127.0.0.1");
Soketo sukūrimas ir surišimas su portu
Sarafinienė Nijolė 47
len_inet = sizeof adr_inet;
/* Bind it to the socket */
z = bind(sck_inet,(struct sockaddr *)&adr_inet, len_inet);
if ( z == -1 ) bail("bind()");
/* Display our socket address */ system("netstat -pa ");
return 0; }
Soketo sukūrimas ir surišimas su portu
Sarafinienė Nijolė 48
Adresai ir portai baitų-rikiavimas Problema:
Skirtingos mašinos / OS naudoja skirtingą žodžių rikiavimą• little-endian: žemiausio svorio baitai - pirmi• big-endian: aukščiausio svorio baitai pirmi
Šios mašinos gali komunikuoti viena su kita tinkle.
128.119.40.12
128
119
40 12
12.40.119.128
128
119
40 12
Big-Endianmachine Little-Endian
machine
Sarafinienė Nijolė 49
Konvertavimas iš tinklo į hosto baitų tvarką.
Galimi du duomenų tipai, kuriuos gali prireikti konvertuoti : short (du baitai) ir long (keturi baitai).
Konvertavimo f-jos taikomos beženkliams dydžiams taip pat
Pavyzdžiui: norima konvertuoti short tipo dydį iš “Host Byte Order” į “Network Byte Order”.
Naudojama f-ja užrašoma taip "h" - "host", toliau "to", tada "n" - "network", ir "s" - "short": h-to-n-s, or htons() ("Host to Network Short").
adr_inet.sin_port = htons(9000);
Sarafinienė Nijolė 50
Galimi konvertavimai
• htons() -- "Host to Network Short"
• htonl() -- "Host to Network Long"
• ntohs() -- "Network to Host Short"
• ntohl() -- "Network to Host Long“
Kadangi sin_addr ir sin_port yra įtraukiami į paketų galvutes, jie turi būti pateikiami “Network Byte Order” tvarka.
Sarafinienė Nijolė 51
inet_addr() f-ja
inet_addr() konvertuoja IP adresą iš formos, išreikštos dešimtainiais skaičiais ir taškais (pavyzdžiui “193.219.32.184”) į 32 bitų tinklinės orientacijos tvarkos (network byte order) bitų eilutę.
Galimas toks adreso uždavimas:ina.sin_addr.s_addr = inet_addr("10.12.110.57");
inet_addr() grąžina adresą “Network Byte Order”, taigi kviesti htonl() nebereikia.
Ši f-ja turi problemų su adresu 255.255.255.255, nes konvertavus į 32 bitus gaunamas pranešimas apie klaidą.
inet_addr() grąžina -1 esant klaidai.
Sarafinienė Nijolė 52
inet_aton() ascii to network
Kaip ir inet_addr, ši f-ja konvertuoja simbolinę eilutę į 32 bitų tinklinio rikiavimo adresą.
struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte
order
inet_aton("10.12.110.57", &(my_addr.sin_addr)); memset(&(my_addr.sin_zero), '\0', 8); // zero the
rest of
the struct inet_aton(), ne taip, kaip kitos visos f-jos, susijusios su soketais grąžina ne
nulį sėkmės atveju ir 0 esant klaidai.Tačiau ne visos platformos palaiko inet_aton() , todėl nors ją patartina būtų
vartoti, yra naudojama ir inet_addr()
Sarafinienė Nijolė 53
spausdinimas
Kaip atspausdinti IP adresus?Tarkim, jie yra struktūroje struct in_addr inair norime juos atspausdinti įprastoje formoje – skaičiai –
taškai.Naudojama f-ja inet_ntoa() ("ntoa" reiškia "network to
ascii") :printf("%s", inet_ntoa(ina.sin_addr));Pavyzdžiui: char *a1, *a2; . . a1 = inet_ntoa(ina1.sin_addr); // this is
192.168.4.14 a2 = inet_ntoa(ina2.sin_addr); // this is
10.12.110.57 printf("address 1: %s\n",a1);
printf("address 2: %s\n",a2);
Sarafinienė Nijolė 54
Tinklo adresų baitų rikiavimas
• Visi dydžiai saugomi struktūroje sockaddr_in turi turėti tinklo baitų rikiavimą(network byte order- aukščiausio svorio baitai - pirmi).– sin_port TCP/IP porto numeris.– sin_addr IP adresas.
Sarafinienė Nijolė 55
Susijungimas – connect()
Įsivaizduokite kelioms minutėms, kad jūs esate “telnet” aplikacija.
Jūsų vartotojas liepia jums gauti soketo failų deskriptorių.
Jūs kviečiate socket(). Toliau jums liepia susijungti su IP adreso
"10.12.110.57" --- "23” portu ( standartiniu telnet portu.)
Kokie seks veiksmai? Kviečiamas connect()—tikslu susijungti su
nutolusiu hostu.
Sarafinienė Nijolė 56
Connection est.: connect()
• Aktyvi pusė:
• int status = connect(sock, &name, namelen);– status: 0 if successful connect, -1 otherwise– sock: integer, socket to be used in connection– name: struct sockaddr: address of passive
participant– namelen: integer, sizeof(name)
Sarafinienė Nijolė 57
Susijungimo sudarymas
• TCP soketo atveju, connect() inicijuoja trijų rankų paspaudimą ir ši funkcija grąžina reikšmę tik po to kai šis susijungimas įvyksta, arba įvyksta klaida.
• Jei TCP klientas negauna atsakymo, tai jo paketas su įjungta SYN reikšme kartojamas po 6 sekundžių, ir jei per 75 sek negaunamas atsakymas, pranešama apie klaidą.
• Jei į kliento SYN grįžta RST, pranešama apie klaidą (ECONNREFUSED)- tame porte nėra klausančio serverio.
• Jei iš maršrutizatoriaus grįžta ICMP "destination unreachable" , tai reiškia, kad nutolusi sistema yra nepasiekiama, ir aplikacinei programai grąžinamas klaidos pranešimas (EHOSTUNREACH or ENETUNREACH )
Sarafinienė Nijolė 58
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define DEST_IP "10.12.110.57"
#define DEST_PORT 23
main() { int sockfd;
struct sockaddr_in dest_addr; // will hold the destination addr sockfd = socket(AF_INET, SOCK_STREAM, 0); /* do some error checking! */
dest_addr.sin_family = AF_INET; // host byte order dest_addr.sin_port = htons(DEST_PORT); /* short, network byte order */
dest_addr.sin_addr.s_addr = inet_addr(DEST_IP); memset(&(dest_addr.sin_zero), '\0', 8); // zero the rest of the //struct don't forget to error check the connect()! connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)); . .
Susijungimas
Sarafinienė Nijolė 59
Pastabos
Patikrinti reikia ką grąžina connect()--jei -1 įvyko klaida.Nebuvo kviesta f-ja bind(). Praktiškai nereikia rūpintis apie
lokalų porto numerį.Reikia rūpintis tik apie tą porto numerį nutolusios mašinos,
su kuria norima susijungti.Operacinės sistemos branduolys parinks lokalų portą ir tas
hostas su kuriuo jungiamasi automatiškai gaus informaciją apie portą.
Sarafinienė Nijolė 60
Susijungimo sudarymas (SOCK_STREAM)
• Susijungimas gali būti organizuojamas tarp dviejų rūšių dalyvių:– Pasyvių: laukiančių kol aktyvus dalyvis pareikalaus
susijungimo– Aktyvių: inicijuojančių susijungimo užklausas į
pasyviojo dalyvio pusę.
• Kai susijungimas yra sukuriamas tiek “pasyvus” dalyvis, tiek “aktyvus” dalyvis elgiasi vienodai:– Abu gali siųsti &gauti duomenis– Bet kuris gali užbaigti susijungimą
Sarafinienė Nijolė 61
Susijungimo sudarymas
• Pasyvus dalyvis– step 1: listen (for
incoming requests)– step 3: accept (a
request)– step 4: data transfer
• Priimtas susijungimas realizuojamas naujame sokete
• Senas soketas toliau naudojamas klausymui
• Aktyvus dalyvis– step 2: request &
establish connection– step 4: data transfer
Passive Participant
l-socka-sock-1 a-sock-2
Active 1
socket
Active 2
socket
Sarafinienė Nijolė 62
Pasyvus dalyvisJis neorganizuoja susijungimo su nutolusiu hostu. Jis laukia ateinančių užklausų susijungimui ir jas tam
tikru būdu apdoroja.Jo vykdomi veiksmai susideda iš susijungimo užklausų
klausymo- listen(), o po to jų priėmimo- accept() .
int listen(int sockfd, int backlog); sockfd yra paprastas soketo failo deskriptorius iš
socket() kreipinio. backlog leistinų susijungimų kiekis įėjimo
eilėje.Ateinantys susijungimai lauks šioje eilėje, kol bus priimti accept(), riba 5-20.
Sarafinienė Nijolė 63
Pasyvus dalyvis
Jei norima klausytis ateinančių užklausų, tai reikia panaudoti bind() prieš kviečiant listen() arba operacinės sistemos branduolys bus priverstas klausytis atsitiktiniame porte.
Taigi kreipinių seka turi būti tokia:socket(); bind(); listen();
/* accept() po to */
Sarafinienė Nijolė 64
Pasyvus dalyvis accept()
Kažkas iš kažkur bandys susijungti- vykdys: connect() į jūsų mašinos portą, kuriame klausomasi listen().
Susijungimas bus patalpintas į eilę ir lauks accept().Iškvietus accept() yra išimamas “kabantis” susijungimo
prašymas.Accept() grąžins naują soketo failo deskriptorių šio
susijungimo realizavimuiAtsiras du soketų failų deskriptoriai:• Naujas bus pasiruošęs f-joms send() ir recv()• Senas ir toliau vykdys klausymą.
Sarafinienė Nijolė 65
Connection est.: listen() & accept()• Pasyvus dalyvis• int status = listen(sock, queuelen);
– status: 0 if listening, -1 if error – sock: integer, socket descriptor– queuelen: integer, # of active participants that can “wait” for
a connection
• int s = accept(sock, &name, &namelen);– s: integer, the new socket (used for data-transfer)– sock: integer, the orig. socket (being listened on)– name: struct sockaddr, address of the active participant– namelen: sizeof(name): value/result parameter
Sarafinienė Nijolė 66
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
main() { int sockfd, new_fd; // listen on sock_fd,
// new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
int sin_size;
sockfd = socket(AF_INET, SOCK_STREAM, 0); // do some error checking!
my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
// don't forget your error checking for these calls:
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)); listen(sockfd, BACKLOG); sin_size = sizeof(struct sockaddr_in);
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); . .
Sarafinienė Nijolė 67
Duomenų siuntimas / priėmimas
Esant soketams (SOCK_STREAM):– int count = send(sock, &buf, len, flags);
• count: # bytes transmitted (-1 if error)• buf: char[], buffer to be transmitted• len: integer, length of buffer (in bytes) to transmit• flags: integer, special options, usually just 0
– int count = recv(sock, &buf, len, flags);• count: # bytes received (-1 if error)• buf: void[], stores received bytes• len: # max size of buf• flags: integer, special options, usually just 0
Sarafinienė Nijolė 68
Duomenų siuntimas / priėmimas
Esant soketams (SOCK_DGRAM):– int count = sendto(sock, &buf, len, flags, &addr,
addrlen);• count, sock, buf, len, flags: same as send• addr: struct sockaddr, address of the destination• addrlen: sizeof(addr)
– int count = recvfrom(sock, &buf, len, flags, &name, &namelen);
• count, sock, buf, len, flags: same as recv• name: struct sockaddr, address of the source• namelen: sizeof(name): value/result parameter
Sarafinienė Nijolė 69
Susijungimo nutraukimasBaigus perdavimus, uždaromas susijungimas
susijęs su soketu. Galima naudoti įprastą UNIX f-ją
status = close(s);– status: 0 jei pavyko, -1 jei klaida– s: soketo deskriptorius (soketo, kuris uždaromas).– Toliau negalimas nei skaitymas nei rašymas, susijęs su
soketu (duos klaidą)
Uždarant soketą– Uždaromas susijungimas ( SOCK_STREAM soketams)– Atlaisvinamas su soketu susijęs portas
Sarafinienė Nijolė 70
Susijungimo nutraukimas
shutdown() funkcija. Ji leidžia nutraukti komunikacijas tam tikra kryptimi arba abiem kryptimis.
int shutdown(int sockfd, int how); sockfd yra soketo failo deskriptorius, kurį norite uždaryti, ir how yra viena iš reikšmių:
• 0 – Tolimesni priėmimai yra neleidžiami• 1 – Tolimesni siuntimai yra neleidžiami• 2 -- Tolimesni siuntimai ir priėmimai yra
neleidžiami (kaip close())shutdown() grąžins 0 sėkmės atv, ir -1 esant
klaidai
Sarafinienė Nijolė 71Log off