Download - Socket Programozas

Transcript

TCP/IP szlltsi rteg ( socket programozsi interfsz )

sszelltotta:

Mohcsi Jnos BME Informatikai Kzpont

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk

TCP/IP socket programozi interfsz

2

1 TCP/IP

1.1 TCP/IP S SOCKET INTERFSZ VISZONYAA TCP/IP rteges felptse: Alkalmazi program rteg Szlltsi rteg Internet rteg Adaptcis rteg Hordoz hlzat rteg A socket interfszt az 1980-as vek elejn, a University of California at Berkeley (UCB) egyik laborjban dolgoztk ki TCP/IP kezeli felleteknt, UNIX opercis rendszerekhez, azta UNIX szabvnyknt terjedt el, implementlva van a Windowsban is WinSock nven. A socket egy API (Application Program Interface), ami eredetileg Berkeley-UNIX -ban (4.x) jelent meg. System V. Release 4 is tvette, de abban van ms API is erre: TLI = Transport Layer Interface (Lsd szlltsi interfsz vizsglata). A socket processzek kztti kommunikcis eszkz, mely fggetlen attl, hogy a kommunikl processzek azonos, vagy klnbz gpen vannak-e, illetve amennyire lehet, elfedik a kommunikci megvalstsnak alsbb szintjeit. A kommunikci formja kliens-szerver alap, ami azt jelenti, hogy a szerver valamilyen jl definilt szolgltatst nyjt, amit a kliensek ignybe vesznek.

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -2-

TCP/IP socket programozi interfsz

3

A host szerver kliens B host kliens hlzat hlzat

1.2

C host

bra a kliens szerver kommunikcirl.

Lehet kapcsolat-orientlt (connection-oriented) vagy kapcsolat nlkli (connectionless): minden adattviteli krsnl meg kell adni a clcmet. Szerver lehet iteratv (ilyenkor a szerver ciklusban vr, azonnal feldolgozza a berkezett krst, tipikusan akkoralkalmazott, ha minden krs feldolgozs vges s rvid idej), vagy konkurens (ilyenkor a szerver minden kiszolglskor fork()-ol, gyereke dolgozza fel, szl jra vr ciklusban a kvetkez krsre.) Ezek klnbz "kombincija" is megvalsithat (preforked, filedescriptor passing, stb.) ha nem blokkold vagy/s aszinkron rendszerhivsokat alkalmazunk.

1.2.1.1

BSD socket szerkezete:Felhasznli program socket knyvtr felhasznl kernel Stream fej SOCKMOD TPI: Transport Provider Interface Transport provider

1. bra: Socket szerkezet SVR4 UNIX-ban BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -3-

TCP/IP socket programozi interfsz

4

a felhasznli program szinte mint egy filedescriptort ltja a socket-et. Br nem minden filedescriptor mvelet mkdik (pl. lseek -> ESPIPE zenet)

1.3 A SOCKET RENDSZERHVSOKA Socket s TLI sszehasonltsa a rendelkezsre ll rendszerhvsok tekintetben: Szerep Funkci Socket TLI Szerver allokci/helyfoglals vgpont ltrehozs cmhez rendels queue mret llts vrakozs kapcsolat krelemre j filedescriptor ltrehozs Kliens allokci/helyfoglals vgpont ltrehozs cmhez rendels szerverhez kapcsolds Mindkettsocket() bind() connect() socket() bind() listen() accept() t_alloc() t_open() t_bind() t_listen()

t_open() t_bind() t_accept() t_alloc() t_open() t_bind() t_connect()

adattvitel (kapcsolat read() write() orintlt)recv() send()

read() write() t_rcv() t_snd() t_rcvudata() t_sndudata()

adattvitel (kapcsolat recvfrom() sendto() nlkli)recvmsg() sendmsg()

kapcsolat lezrs

close() shutdown()

t_close() t_sndrel()

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -4-

TCP/IP socket programozi interfszt_snddis()

5

Ezenkvl a kvetkez programozskor:ioctl() fcntl() select()

rendszerhvsokat

szoks

hasznlni

hlzati

eszkzvezrl funkci filelert vezrel funkci szinkron/aszinkron multiplexelt I/O belltssa s

vrakozs egy I/O esemnyre Ezekre rszletesen a multiplexelt, aszinkron I/O s nem blokkold I/O fejezetekben trnk ki.

1.4 A SOCKET INTERFSZ LTALNOS LERSA1.4.1.1 A socket egy "communications domain" -hoz kapcsoldik a ltrehozskor:

Loklis vagy UNIX domain (AF_LOCAL vagy AF_UNIX): gpen belli kommunikcihoz Internet domain (AF_INET, AF_INET6): hlzaton t, a kvetkez protokollokkal: TCP: Transmission Control Protocol UDP: User Datagram Protocol IP: Internet Protocol ICMP: Internet Control Message Protocol (Ezeket egytt szoks TCP/IP -nek is nevezni.) Egyb lehetsges protokollok: ATM, IPX, Appletalk, DECNET, XNS, OSI, de egyes esetekben IPSec kulcsmenedzsment (PF_KEY), hlzati krtyaszint (Netlink)1.4.1.2 Az tvitel tpusai:

stream socket (SOCK_STREAM): kapcsolat-orientlt byte-stream: sorrendtart, megbzhat, ismtlds nlkli, nincs zenethatr. Tnyleges adatklds eltt a kapcsolatot fel kell pteni. datagram socket (SOCK_DGRAM) : kapcsolat nlkli, zenet-alap, nem megbzhat egyszer (raw) socket (SOCK_RAW) : kzvetlen hozzfrs a protokollhoz, annak adminisztrcijhoz, gy a felhasznl pthet sajt rtegeket sorrendes socket (SOCK_SEQPACKET) hasonl a streamhez, de BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -5-

TCP/IP socket programozi interfsz

6

zenethatrokat is kzvetti, kapcsolat-orientlt, megbzhat megbzhat zenet socket (SOCK_RDM: reliably delivered message socket): megbzhat, kapcsolat nlkli, zenet-orientlt Nem minden domain tartalmaz minden socket tpusra megvalstst. tvitel tpusa SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET SOCK_RDM Kapcsolat -orientlt nlkli -orientlt nlkli sorrendtart megbzhat i n i n i n i i ismtls nlk. i n i n zenethatr n i i i

1.4.1.3

Protokoll-default-ok Internet protokollok (AF_INET s AF_INET6) esetn:

AF_LOCAL SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET1.4.1.4 A kapcsolat-orientlt iddiagram:Kliens socket () bind () connect () Kapcsolat felvtel write () send() sendto() sendmsg() Hlzat

AF_INET TCP UDP Protokolltl fggen TCP UDP

AF_INET6

+ +

Protokolltl fggen

IPv4/ICMPv4/IGMPv4 IPv6/ICMPv6

Szerver socket () bind () listen () accept() Blokkoldik, mg krst nem kap

read () recv() recvfrom() recvmsg() write ()

feldolgozs

read ()

2. bra: Kapcsolatorientlt mkds iddiagramja

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -6-

TCP/IP socket programozi interfsz1.4.1.5 A kapcsolat-nlkli iddiagram:Kliens socket() bind() sendto() sendmsg() Krs + adat recvfrom() recvmsg() ... sendto() SSI :SocketSer ce I er ace vi nt f Hlzat Szerver socket() bind()

7

recvfrom() SSI

3. bra: Kapcsolat nlkli mkds iddiagramja Minden "kapcsolatot" egy 5-s azonost: {Protokoll, helyi gpcm, helyi processz portszm, tvoli gpcm, tvoli processz portszm} Az 5-s csoport megvltoztatsra a a kvetkez rendszerhvsok llnak rendelkezsre attl fggen, hogy milyen szerepet jtszik a program: protokoll helyi gpcm, helyi tvoli gpcm, tvoli process portszm processz portszm Kapcsolat orientlt szerver Kapcsolat orientlt kliens Kapcsolat nlkli szerver Kapcsolat nlkli klienssocket() socket() socket() socket() bind() bind() bind() bind() listen(),accept() connect() recvfrom() sendto()

Lekrdezsre a getsockname() s a getpeername() rendszerhvsok szolglnak. Az accept() rendszerhvs eltt a szerver socket tvoli gpcme s tvoli processz portszma egy "mindent elfogad rtket" tartalmaz. Az accept() hatsra egy jabb socket keletkezik, s a rgi socket akr kpes lehet jabb krs kiszolglsra.

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -7-

TCP/IP socket programozi interfsz

8

1.5 PROGRAMOZI INTERFSZ1.1.1 Socket ltrehozsa1.5.1.1 Socket

#include #include int socket (int family, int type, int protocol);

= file ler: OK, -1: hiba (kdja: errno) family: communications domain: kt konstans-kszlet adhatja meg, melyek pronknt azonosak: address family: cm formtuma protocol family: hlzati architektra : UNIX/Local domain: PF_UNIX = AF_UNIX Internet domain: PF_INET = AF_INET type: socket tpusa: jelenleg csak SOCK_STREAM, SOCK_DGRAM, SOCK_RAW van. protocol: a hasznland protokoll tpusa: 0: a default a family s a type szerint, vagy IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_TCP, IPPROTO_UDP,stb. ( -ban) 1.5.2 Socket hozzrendelse hlzati cmhez Ltrehozsa utn, elssorban szervernl kell, e nlkl (pl. a kliensnl) automatikusan egy egyedi cmhez rendeldik.

1.5.2.1

Bindint alen);

int bind (int fd, struct sockaddr *addrp, Fd: File ler, melyet socket() adott, Addrp: Cmler struktra cme:

struct sockaddr { ushort_t char };

sa_family;

/* mint socket()-ben 2 byte */ sa_data [14];

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -8-

TCP/IP socket programozi interfsz vagy BSD4.4-ben:struct sockaddr { u_char sa_len; u_char sa_family; char sa_data [14]; }

9

De igazbl 16 byte-nl hosszabb is lehet, de ilyenn kell a cmt cast-olni. A socket hossznak lekrdezsre s belltsra a BSD 4.4-ben sa_len szolgl.

1.5.3 Socket lezrsa1.5.3.1 Close

close (int fd)

Ekkor a mg t nem adott adatok elveszhetnek, vagy mg tvehetek, lsd SO_LINGER opci.1.5.3.2 Shutdown

Csak kapcsolat-orientlt (connected) socket-re egyirny lezrsa socketnek.int shutdown (int fd, int how); /* =0 :OK, -1 :hiba how = 0: nem lehet tbb adatot tvenni a socket-tl, = 1: nem lehet tbb adatot tadni a socket-nek, = 2: egyik sem megy (ekvivalens a close()-al)

*/

1.5.4 Opcik belltsa ill. lekrdezse Melyeket a socket rteg dolgoz fel, gy protokoll-fggetlenek.int setsocketopt (int fd, int level, int cmd, char *arg, int len); int getsocketopt (int fd, int level, int cmd, char *arg, int *lenp); level: milyen szint mkdst lltunk be (pl. SOL_SOCKET: sockett) Pl. ha cmd = SO_ERROR, arg ltal mutatott int-be leteszi a hibakdot. Kvetkezkben a

legfontosabbakat soroljuk fel: opcinv get set Lers md adat

level

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -9-

TCP/IP socket programozi interfszIP_OPTIONS IPPROTO_IP IP_INCLFDR TCP_MAXSEG IPPROTO_TCP TCP_NODELAY + SO_BROADCAS + T SO_DEBUG SO_DONTROU TE SO_ERROR SO_KEEPALIV E + + + + + + + + + + + + IP opcikval hozzfrs teljes IP header hozzfrhet maximlis TCP szegmens mret TCP adat azonnali elkldse (nagy ksleltets hlzaton ne alkalmazzuk) Broadcast engedlyezse/tiltsa Debuggols engedlyezse (Kernel specifikus zenetek) Ne routold az zenetet. A socket hibalekrdezse. Akkor is kldj, ha nincs mit kldeni, klnben a socket lebomlik. close() utn mennyi ideig problkozzon az elkldetlen adat elkldsvel. Az OOB adatok is kerljenek az inputra, vagy kln kelljen feldolgozni. Az olvassi buffer mretnek belltsa (A teljestmny vltoztatsnak eszkze) Az irsi buffer mretnek belltsa (A teljestmny vltoztatsnak eszkze) olvassi buffer alsrtke (byte-ban), ami meghatrozza, hogy mikor kell a socketnek feladni a megrkezett adatot irsi buffer alsrtke (byte-ban), ami meghatrozza, hogy mikor kell a hlzatnak tadni az elkldend adatot olvassi buffer alsrtke (idben), ami meghatrozza, hogy mikor kell a socketnek feladni a megrkezett adatot irsi buffer alsrtke bellt/leolvas engedlyez/tilt bellt/leolvas

10

void * int int

engedlyez/tilt

int

SOL_SOCKET

+ + +

engedlyez/tilt engedlyez/tilt engedlyez/tilt bellt/leolvas engedlyez/tilt

int int int int int

SO_LINGER

+

+

bellt/leolvas

struct linger

SO_OOBINLIN E

+

+

engedlyez/tilt

int

SO_RCVBUF

+

+

bellt/leolvas

int

SO_SNDBUF

+

+

bellt/leolvas

int

SO_RCVLOWA T

+

+

bellt/leolvas

int

SO_SNDLOWA T

+

+

bellt/leolvas

int

SO_RCVTIMEO +

+

bellt/leolvas

struct timeval

SO_SNDTIMEO +

+

bellt/leolvas

struct timeval

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 10 -

TCP/IP socket programozi interfsz(idben), ami meghatrozza, hogy mikor kell a hlzatnak tadni az elkldend adatot engedlyezi, hogy az 5st azonnal jra lehessen + hasznlni ami azonostja a kapcsolatot. A socket tpusnak IPv lekrdezse ill. cm 6 konvertlsa

11

SO_REUSEADD + R

engedlyez/tilt

int int

SO_TYPE

+

bellt/leolvas

1.5.5 Kapcsolat ltrehozsa Kt socket kztti kapcsolat ltrehozsa, tipikusan kliensben; stream: virtulis ramkr jn tre datagram: megjegyzi a clcmet, azt nem kell az egyes tviteleknl ksbb kln megadni, ill. tvenni csak a megadott cmrl jtt adatokat lehet. (Ha nincs bind-elve, connect() egy j cmhez rendeli hozz a socket-et.)1.5.5.1 Connect

int connect (int fd, struct sockaddr *addrp, int alen); addrp: cl-cm (cmzett cme) fd, alen: mint bind() -nl

= 0: OK, -1 : hiba, de a cm hozzrendelse (bind) ekkor is megmarad.1.5.5.2 Connect krsek elfogadsi szndknak jelzse s a queue mretnek belltsa(a szerver oldalon):

Csak kapcsolat-orientlt socket-nl (SOCK_STREAM, SOCK_SEQPACKET)int listen (int fd, int backlog); backlog: hny feldolgozatlan connect

krst trol (Nem teljesen, hanem egy

exponencilis kplet szerint szmolja ki.) Ilyenkor egy n. passzv socket keletkezik.1.5.5.3 Connect elfogadsa (a szerver oldalon):

Csak kapcsolat-orientlt socket-nl.int accept (in fd, struct sockaddr *addrp, int *alenp); addrp:ide teszi le a kliens cmt, ha nem rdekel, NULL

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 11 -

TCP/IP socket programozi interfsz*alenp:hvskor:

12

az addrp-knt tadott buffer hossza, visszatrskor: a kapott cm hossza. Ha nem rdekel, alenp==NULL = -1, ha hiba, = j file ler, ha sikeres, mely a kapott connect hvsnak felel meg, rkli a bemeneti fd tulajdonsgait, pl. tpus, protokoll. A bemeneti fd nem vesz rszt az gy elfogadott hvs tovbbi mveleteiben, hanem jabb accept hvsok fogadsra hasznlhat. Ha nincs ppen vrakoz connect krs, accept felfggeszti a hv processt. Nem tud eleve elutastani bizonyos hvsokat, de elfogads (accept) utn azonnal lezrhatjuk azokat. 1.5.6 Adatok kldse Kapcsolat-orientlt esetben hasznlhat a write() is, ezzel az tvitel a filemveletekhez hasonlan vgezhet, st a processz esetleg nem is tudja, hogy ppen socket-en t kommunikl. Tovbbi eszkzk csak kapcsolat-orientlt socket-re:

1.5.6.1

Sendint flags);

int send (int fd, char *buf, int len, = -1: hiba, >= 0: tvitt byte-szm

flags: MSG_OOB: out-of-band: nagyobb prioritssal viszi t, ha a protokoll tmogatja ezt MSG_DONTROUTE: ha lehet, kzvetlenl a cmzettnek kldi, nem hasznl tvonal valasztst (csak loklis hlzaton mkdik). Kapcsolat nlkli socket-re is:1.5.6.2 Sendto

int sendto (int fd, char *buf, int len, int flags, /* mint send() */ struct sockaddr *addrp, int alen); /* mint connect() */

= -1: hiba, >= 0 : tvitt byte-szm

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 12 -

TCP/IP socket programozi interfsz Legltalnosabb:1.5.6.3 Sendmsgint flags);

13

int sendmsg (int fd, struct msghdr *msgp, Visszatrsi rtk, fd, flags: mint send()-nlstruct msghdr { caddr_t msg_name; int msg_namelen; iovec_t *msg_iov; int msg_iovlen; caddr_t int }; msg_accrights; msg_accrno;

/* cl-cm, elhagyhat (char *) */ /* ennek hossza */ /* tviend terletek lersa */ /* ennek elemszma, =0: kapott byte-szm, = -1: hibaflags:

MSG_OOB: csak ilyen flag-el kldtt adatokat vesz t, egybknt brmelyiket, az ilyennel kldtteket elbb kapja meg, mint a tbbit MSG_PEEK: az tvett adatokat nem trli a bufferbl, csak jabb, ilyen flag nlkli hvsnl Datagram socket esetn ezzel nem tudhat meg, ki kldte. BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 13 -

TCP/IP socket programozi interfsz1.5.7.2 Recvfromchar *buf, int maxlen, int flags, /* mint recv() */ struct sockaddr *addrp, int *alenp); /* mint accept() */

14

int recvfrom (inf fd,

= mint recv() *addrp: innen jtt, ide lehet a vlaszt kldeni1.5.7.3 Recvmsg

int recvmsg (int fd, struct msghdr *msgp, int flags); Paramterek: mint sendmsg(), visszatrsi rtk: mint recv()

1.5.8 Sajt socket-cm lekrdezse (pl. gyerek-folyamatban):1.5.8.1 Getsocknamestruct sockaddr *addrp, int *alen);

int getsockname (int fd,

= 0 :OK, =-1: hiba; paramterek: mint accept() 1.5.9 Partner socket-cmnek lekrdezse:1.5.9.1 Getpeernamestruct sockaddr *addrp, int *alen);

int getpeername (int fd,

= 0: OK, =-1: hiba; paramterek: mint accept() A 0 ... 1023 port-cmeket ltalban privilegizlt felhasznlk kaphatjk csak meg. 1.5.10 Nv cm fordts Rutinkszlet, a cm egyes rszeinek fordtsra, az /etc knyvtrban tallhat megfelel file-ok alapjn s a DNS alapjn. Mindegyik valamilyen struktra cmt adja vissza, amely a rutinban definilt statikus adatra mutat. jabb hvs e terletet fellrja, ezrt ha ksbb is szksg van r, le kell msolni.1.5.10.1 Host nv host Internet cm fordts:

File: /etc/hosts Ha van DNS a hlzaton, akkor ott is keresheti. BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 14 -

TCP/IP socket programozi interfsz Paramterek tvtelhez:struct hostent { char * h_name; char ** h_aliases; int int char }; h_addrtype; h_length; ** h_addr_list; /* defincija -ban */ /* host hivatalos neve */ /* host-nv alias lista, vgn 0 pointer */ /* cm-tpus, ksbbi bvtshez, most: AF_INET */ /* ksbbi bvtshez, most: 4 */ /* hlzati cmek listja, egy hostnak tbb is lehet, binrisan, nagy-kicsi byte-sorrendben */

15

1.5.10.2 Gethostent#include #include #include struct hostent * gethostent (void); /etc/hosts file megnyitsa, ha els hvs,

els ill. kvetkez bejegyzs olvassa,

vgl, vagy hiba esetn 0-t ad.1.5.10.3 Endhostentvoid endhostent (void); /etc/hosts file olvassnak

lezrsa

1.5.10.4 Gethostbyaddrstruct hostent * gethostbyaddr (char *addrp, int len, int type); Cm szerinti keress /etc/hosts file-ban,

= struct cm, ha megvan, =0, ha nincs, ekkor h_errno = HOST_NOT_FOUND jelzi az egyetlen lehetsges hibaokot, de ha van egy un. DNS is, mely domain name service-t csinl, akkor azt is hasznlja a keresshez, ekkor h_errno = TRY_AGAIN: tmeneti hiba, NO_RECOVERY: fatlis hiba, NO_DATA: ez sem tallja Utna lezrja a file-t, ha a stayopen rtke nulla volt sethostent()-ben, ezrt jabb hostent() hvs ismt ellrl kezdi olvasni a file-t.1.5.10.5 Gethostbynamestruct hostent * gethostbyname (char *name); Nv szerinti keress /etc/hosts file-ban, nv

eredeti vagy brmelyik alias is lehet BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 15 -

TCP/IP socket programozi interfsz = mint gethostbyaddr() esetn, ez is lezrja, ha ...1.5.10.6 Sethostentvoid sethostent (int stayopen);

16

Visszall a file elejre, s ha a stayopen != 0 egyszer is, a kvetkez endhostent() hvsig nem zrja majd le gethostbyaddr() ill. gethostbyname() vgrehajtsa utn, azaz az elz stayopen !=0 hatsa megmarad.

1.5.10.7 getaddrinfo

(megrand)1.5.10.8 Hlzat nv hlzat-szm fordts:

File: /etc/networks vagy DNS

1.5.10.9 Lekrdezsek: mint ...host... fv.-eknl:struct netent * getnetent (void); void endnetent (void); struct netent * getnetbyaddr (long net, int type); struct netent * getnetbyname (char *name); void setnetent (int stayopen);

1.5.10.10 Protocol nv protocol-szm fordts:

File: /etc/protocols Paramterek tvtelhez:struct protent { char * p_name; char ** p_aliases; int }; p_proto; /* defincija -ban */ /* hivatalos protocol-nv */ /* protocol-nv alias lista, vgn 0 pointer */ /* protocol szm */

1.5.10.11 Lekrdezsek: mint ...host... fv.-eknl:struct protent * getprotent (void); void endprotent (void); struct protent * getprotbynumber (int protno); struct protent * getprotbyname (char *name); void setprotent (int stayopen);

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 16 -

TCP/IP socket programozi interfsz1.5.10.12 Szolgltats nv port-szm fordts:

17

File: /etc/services Paramterek tvtelhez:struct servent { char * s_name; char ** s_aliases; int char }; s_port; * s_proto; /* defincija -ban */ /* hivatalos szolgltats-nv */ /* szolg.-nv alias lista, vgn 0 pointer */ /* port szm */ /* hasznland protokoll, ha NULL, csak szolgltats-nevet hasznl */

1.5.10.13 Lekrdezsek: mint ...host... fv.-eknl:struct protent * getservent (void); void endservent (void); struct servent * getservbyport (int port, char *proto); struct servent * getservbyname (char *name, char *proto); void setservent (int stayopen);

ahol proto: protokoll nvre mutat Pl. a helyi hlzaton lv gpek nevnek, cmnek lekrdezse:typedef struct in_addr { /* Internet address */ union { struct { uchar_t s_b1, s_b2, s_b3, s_b4; } S_un_b; /* bytes */ struct { ushort_t s_w1, s_w2; } S_un_w; /* 2-B words */ ulong_t S_addr; /* 4-B word */ } S_un; /* union nv */ } in_addr_t; /* tpusnv */ typedef struct hostelement { struct hostelement * next; char * name; in_addr_t inaddr; } hostelement_t; struct char char char char char }; utsname { /* host rendszer adatai sysname [SYS_NMLN]; nodename [SYS_NMLN]; release [SYS_NMLN]; version [SYS_NMLN]; machine [SYS_NMLN]; /* /* /* /* /* Lnc egy eleme */ => kvetkez */ host neve */ internet cm */ tpusnv */

[26] 382. old. */ /* rendszer neve */ /* host neve */ /* op. r. neve */ /* verzi */ /* gptpus */

hostelement_t * gethosts (void) /* Host-ok adatainak kigyjtse */ { struct hostent *hp; /* => egy bejegyzs a host listban */ hostelement_t *rhp, *nhp; /* => lnc eleje, j lncelem */ struct utsname u; /* sajt nv megszerzshez */ in_addr_t *ip; /* => internet address */ rhp=0; /* res lnc */

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 17 -

TCP/IP socket programozi interfsz

18

if (uname(&u) < 0) error("uname() hiba"); /* sajt adatok lekrd. */ while ((hp=gethostent()) !=0) { /* kvetkez host olvassa */ if ( !strcmp(hp->h_name, "localhost") || /* sajt maga, visszahurkolshoz */ !strcmp(hp->h_name, "anyhost") || /* broadcast zenethez */ !strcmp(hp->h_name, u.nodename)) /* sajt maga */ continue; if ( ! (nhp = (hostelement_t*) malloc (sizeof(hostelement_t))) ) error ("Nincs elg memria"); ip = (in_addr_t*) *(hp->h_addr_list); /* 1. Internet cm cme */ nhp->inaddr.s_addr = ip->S_addr; /* In. cm a lncelembe */ nhp->name = strdup(hp->h_name); /* host nv msol. */ nhp->next = rhp; rhp = nhp; /* belncols elre */ } /* while */ endhostent(); return rhp; } /* olvass lezrsa */

1.6 I/O MULTIPLEXELSA file illetve socket rsi-olvassi krsek egytt multiplexelhetek szinkron mdon a select() rendszerhvssal, amelynek formtuma a kvetkez:

#include #include int select(int nfds, fd_set *readfds, fd_set *exceptfds, struct timeval *timeout);

*writefds,fd_set

A fggvny nfds argumentum az utna kvetkez hrom argumentumban elfordul file lerk maximlis szma. A msodik, harmadik s negyedik argument hrom fileler halmazra mutat: az elsbe azok a filelerk vannak belltva, amelyekre olvassi felttel bekvetkeztt vrjuk, a msodikba az rsi, a harmadikba a kivteles mveletre vr filelerk vannak bemaszkolva. Kivteles mveletek alatt Out-of-Band adatok rkezst, vagy signal rkezst kell rteni, errl az Out-of-Band cm alfejezetben lesz sz. Akrmelyik maszk lehet NULL is. A maszkok long integer rtkek, bennk a file lerk bitek. Ha az adott gpen a long integer 32 bites, akkor maximum 32 file lert tudunk a select() hvssal szinkron mdon multiplexelni. Ennek kikerlsre tbb trkks megolds ltezik. A file lerk maszkolsra az albbi makrk szolglnak: void FD_SET(int fd, fd_set &fdset);a fileler belltsa a maszkban void FD_CLR(int fd, fd_set &fdset);a fileler trlsre a maszkbl int FD_ISSET(int fd, fd_set &fdset);a fileler szerepel-e a maszkban void FD_ZERO(fd_set &fdset);az egsz maszk trlse, inicializlsa BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 18 -

TCP/IP socket programozi interfsz

19

A timeout argumentum a hvsban az esemnyekre val maximlis vrakozs idejt hivatott belltani. Ha nincs definilva (NULL), akkor a select() blokkoldik brmelyik belltott filelern egy esemny bekvetkeztig, vagy egy SIGIO illetve SIGURG signal rkezsig. A SIGIO s SIGURG szignlok az aszinkron multiplexelst hivatottak biztostani, errl majd az Aszinkron socket-ek cm fejezetben lesz sz. Ha a timeout 0, akkor a select() lekrdezi a belltott filelerkra rkezett esemnyeket s azonnal visszatr.

1.7 OUT-OF-BAND ADATOKTCP hasznlata esetn lehetsg van kt processz kztt a ktirny (duplex) csatorna mellet egy logikailag kln kezelt "jelzsi csatornt" hasznlni, gynevezett Out-of-Band (OOB) adatokat kldeni. Az OOB adatok a tbbi adattl fggetlenl kldhetek, send(3N) rendszer-hvs harmadik, flags argumentumnak MSG_OOB flag belltsval. Ezt a jelzsi csatornt hasznlja a telnet s az rlogin vezrl adatok tovbbtsra.

1.8 NEM-BLOKKOLD SOCKET-EKNhny alkalmazsnl kvetelmny, hogy a socket-ekre vonatkoz rendszerhvsok ne blokkoldjanak. Egy olyan krs, amely nem tud vgrahajtdni azonnal, mert vrakozni kell a processznek a krs vgrehajtsra, nem mindig alkalmazhat real-time krlmnyek kztt. Egy mr ltrehozott s sszekttt socket-et az fcntl(2) rendszerhvssal tehetnk nem-blokkoldv. Az albbi plda e hvs hasznlatt mutatja be:#include #include int fileflags; int sock; ... sock= socket(AF_INET, SOCK_STREAM, 0); ... if(fileflags= fcntl(sock, F_GETFL, 0)== -1) { perror(Get file flags); exit(-1); } if(fcntl(sock, F_SETFL, fileflags | FNDELAY)== -1) {

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 19 -

TCP/IP socket programozi interfszperror(Set file to non-nlocking); exit(-1); }

20

... Ha egy nem-blokkold socket-en I/O trtnik, ellenrizni kell az errno hibavltoz tartalmt, EWOULDBLOCK hiba keletkezhet egy olyan hvsnl, amelyik rendesen (ezen opci belltsa nlkl) blokkoldna. Az accept(3N), connect(3N), send(3N), recv(3N), read(2) s write(2) hvsoknl fordulhat el. Ha pldul a write() hvs nem tud teljesen befejezdni (nem tudja az adott socketre kirni az sszes byte-ot), a visszatrsi rtk a sikeresen elkldtt byte-ok szma lesz. A nem blokkold tulajdonsgot brmikor be lehet lltani s el lehet venni.

1.9 INTERRUPT/ESEMNY VEZRELT SOCKET-EK (ASZINKRON SOCKETEK)Nhny esetben szksg lehet esemnyvezrls jelleg hlzati kommunikcira. Erre szolglnak az aszinkron socket-et. A processz ilyenkor SIGIO szignlt kap, ha a socket (vagy file) befejezte az adott I/O mveletet. E szignl elkapshoz s feldolgozshoz hrom dolgot kell megtenni: 1. Meg kell adni, hogy a processzben a SIGIO szignlt melyik fggvny fogja lekezelni. Ezt a signal(2), sigset(2), (sigvec(2B) a BSD kompatibilis UNIX rendszerek esetn) rendszerhvsokkal tehetjk meg. 2. Hozz kell rendelni az adott socket-hez a processz ID, vagy processz csoport ID az fcntl(2) hvssal. 3. t kell lltani a socket-et aszinkron zemmdba. A kvetkez plda egy sock socket-re lltja be, hogy a vtel pillanatban az alkalmazs a my_handler() fggvnnyel kezelje a berkez SIGIO szignlt:#include #include #include ... signal(SIGIO, my_handler); sigset(SIGIO, my_handler); if(fcntl(sock, F_SETOWN, getpid())< 0) { perror(Set file to asynchronous); exit(-1); }

Out-of-Band adatok aszinkron kezelshez hasonlan be kell lltani a SIGURG szignl fogadst is programunkban. A kvtekz plda socket-et aszinkron zemmdba lltst mutatja be: BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 20 -

TCP/IP socket programozi interfsz#include #include int fileflags; int sock; ... sock= socket(AF_INET, SOCK_STREAM, 0); ... if(fileflags= fcntl(sock, F_GETFL, 0)== -1) { perror(Get file flags); exit(-1); } if(fcntl(sock, F_SETFL, fileflags | FNDELAY | FASYNC)== -1) { perror(Set file to non-blocking and asynchronous); exit(-1); }

21

Az aszinron zemmdba helyezs utn a send(3N), recv(3N), read(2) s write(2) hvsokat hasznlhatjuk, ha belltottuk a SIGIO szignl lekezelst programunkban.

1.10 A HLZATI KONFIGURCI MEGHATROZSAA UNIX ioctl(2) rendszerhvsa SIOCGIFCONF, SIOCGIFBRDADDR s SIOCGIFFLAGS belltsai lehetsget nyjtanak az interfszek paramtereinek lekrdezsre,az sszes kapcsold hlzat broadcast cmnek lekrdezsre, ezzel kiderthetjk, tmogatja-e az adott hlzati interfsz a broadcast zenetek kldst, vagy sem, ha igen milyen broadcast cmre kldhetnk broadcast zeneteket a sendto(3N) rendszerhvs segtsgvel.

1.11 BROADCAST ZENETEK KLDSEInternet domain datagram tpus socket-ek broadcast s multicast zeneteket is kldhetnek, hogy a kapcsold hlzat sszes host-jt vagy a gpek egy csoportjt elrjk. A broadcast zenetek igen leterhelhetik a hlzatot, hiszen minden hlzatban lev gpet az zenetek feldolgozsra knyszertenek. Ha egy host tbb hlzatra is csatlakozik, akkor a send(3N) csak az egyik hlzatra tud broadcast zeneteket kibocstani, kivve, ha a specilis INADDR_BROADCAST cmhez rendeljk hozz a socket-et (bind(3N)). Az INADDR_ANY s az BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 21 -

TCP/IP socket programozi interfsz

22

INADDR_BROADCAST konstansok a netinet/in.h header file-ban vannak definilva.

1.12 MULTICAST ZENETEK KLDSE S FOGADSA(megrand)

2 pldk:

2.1 UNICAST PLDAPROGRAMOK2.1.1 Datagram Szerver plda:#include #include #include #include

/* * This program creates a datagram socket, binds a name to it, then reads * from the socket. */ main() { int sock, length; struct sockaddr_in name; char buf[1024];

/* Create socket from which to read. */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror("opening datagram socket"); exit(1);

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 22 -

TCP/IP socket programozi interfsz} /* Create name with wildcards. */ name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = 0; if (bind(sock, &name, sizeof(name))) { perror("binding datagram socket"); exit(1); } /* Find assigned port value and print it out. */ length = sizeof(name); if (getsockname(sock, &name, &length)) { perror("getting socket name"); exit(1); } printf("Socket has port #%d\n", /* Read from the socket */ if (read(sock, buf, 1024) < 0) perror("receiving datagram packet"); printf("-->%s\n", buf); close(sock); } ntohs(name.sin_port));

23

2.1.2 Datagram kliens plda#include #include #include #include #include

#define DATA "The sea is calm tonight, the tide is full . . ."

/* * Here I send a datagram to a receiver whose name I get from the command * line arguments. * * */ The form of the command line is

dgr_cli hostname portnumber message

main(argc, argv) int argc; char *argv[]; {

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 23 -

TCP/IP socket programozi interfszint sock; struct sockaddr_in name; struct hostent *hp, *gethostbyname();

24

/* Create socket on which to send. */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror("opening datagram socket"); exit(1); } /* * Construct name, with no wildcards, of the socket to send to. * Gethostbyname() returns a structure including the network address * of the specified host. * line. */ hp = gethostbyname(argv[1]); if (hp == 0) { fprintf(stderr, "%s: unknown host\n", argv[1]); exit(2); } bcopy(hp->h_addr, &name.sin_addr, hp->h_length); /* Get IP address BSD 4.2 way, indeed we receive a pointer to pointer */ name.sin_family = AF_INET; name.sin_port = htons(atoi(argv[2])); /* Send message. */ if (sendto(sock, argv[3], strlen(argv[3]), 0, &name, sizeof(name)) < 0) perror("sending datagram message"); close(sock); } The port number is taken from the command

2.1.3 Stream szerver plda#include #include #include #include #include #define TRUE 1

/* * This program creates a socket and then begins an infinite loop. Each time * through the loop it accepts a connection and prints out messages from it.

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 24 -

TCP/IP socket programozi interfsz* When the connection breaks, or a termination message comes through, the * program accepts a new connection. */

25

main() { int sock, length; struct sockaddr_in server; int msgsock; char buf[1024]; int rval; int i;

/* Create socket */ sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("opening stream socket"); exit(1); } /* Name socket using wildcards */ server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = 0; if (bind(sock, &server, sizeof(server))) { perror("binding stream socket"); exit(1); } /* Find out assigned port number and print it out */ length = sizeof(server); if (getsockname(sock, &server, &length)) { perror("getting socket name"); exit(1); } printf("Socket has port #%d\n", ntohs(server.sin_port));

/* Start accepting connections */ listen(sock, 5); do { msgsock = accept(sock, 0, 0); if (msgsock == -1) perror("accept"); else do { bzero(buf, sizeof(buf));

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 25 -

TCP/IP socket programozi interfszif ((rval = read(msgsock, buf, 1024)) < 0) perror("reading stream message"); i = 0; if (rval == 0) printf("Ending connection\n"); else printf("-->%s\n", buf); } while (rval != 0); close(msgsock); } while (TRUE); /* * Since this program has an infinite loop, the socket "sock" is * never explicitly closed. However, all sockets will be closed

26

* automatically when a process is killed or terminates normally. */ }

2.1.4 Stream kliens plda#include #include #include #include #include

/* * This program creates a socket and initiates a connection with the socket * given in the command line. One message is sent over the connection and

* then the socket is closed, ending the connection. The form of the command * line is streamwrite hostname portnumber */

main(argc, argv) int argc; char *argv[]; { int sock; struct sockaddr_in server; struct hostent *hp, *gethostbyname(); char buf[1024];

/* Create socket */ sock = socket(AF_INET, SOCK_STREAM, 0);

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 26 -

TCP/IP socket programozi interfszif (sock < 0) { perror("opening stream socket"); exit(1); } /* Connect socket using name specified by command line. */ server.sin_family = AF_INET; hp = gethostbyname(argv[1]); if (hp == 0) { fprintf(stderr, "%s: unknown host\n", argv[1]); exit(2); } bcopy(hp->h_addr, &server.sin_addr, hp->h_length); /* Get IP address BSD 4.2 way, indeed we receive a pointer to pointer */ server.sin_port = htons(atoi(argv[2]));

27

if (connect(sock, &server, sizeof(server)) < 0) { perror("connecting stream socket"); exit(1); } if (write(sock, argv[3], strlen(argv[3])) < 0) perror("writing on stream socket"); close(sock);

}

2.2 MULTICAST PLDA PROGRAMOK2.2.1 Kld Program

/* * sender.c -- multicasts "hello, world!" to a multicast group once a second * */ #include #include #include #include #include #include

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 27 -

TCP/IP socket programozi interfsz#include #define HELLO_PORT 6789 #define HELLO_GROUP "225.0.0.111" main(int argc, char *argv[]) { struct sockaddr_in addr; int fd, cnt; struct ip_mreq mreq; char *message="Hello, World!"; /* create what looks like an ordinary UDP socket */ if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) { perror("socket"); exit(1); } /* set up destination address */ memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_addr.s_addr=inet_addr(HELLO_GROUP); addr.sin_port=htons(HELLO_PORT); /* now just sendto() our destination! */ while (1) { if (sendto(fd,message,sizeof(message),0,(struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("sendto"); exit(1); } sleep(1); } }

28

2.2.2 Hallgat Program

/* * listener.c -- joins a multicast group and echoes all data it receives from * the group to its stdout... * */ #include #include #include #include #include #include #include

#define HELLO_PORT 6789

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 28 -

TCP/IP socket programozi interfsz#define HELLO_GROUP "225.0.0.111" #define MSGBUFSIZE 256 main(int argc, char *argv[]) { struct sockaddr_in addr; int fd, nbytes,addrlen; struct ip_mreq mreq; char msgbuf[MSGBUFSIZE]; /* create what looks like an ordinary UDP socket */ if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) { perror("socket"); exit(1); } /* set up destination address */ memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */ addr.sin_port=htons(HELLO_PORT); /* bind to receive address */ if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) { perror("bind"); exit(1); }

29

/* use setsockopt() to request that the kernel join a multicast group */ mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP); mreq.imr_interface.s_addr=htonl(INADDR_ANY); if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) { perror("setsockopt"); exit(1); } /* now just enter a read-print loop */ while (1) { addrlen=sizeof(addr); if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0, (struct sockaddr *) &addr,&addrlen)) < 0) { perror("recvfrom"); exit(1); } puts(message); } }

BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 29 -


Top Related