Professional Documents
Culture Documents
sszelltotta:
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk
1 TCP/IP
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -2-
1.2
C host
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
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-
a felhasznli program szinte mint egy filedescriptort ltja a socket-et. Br nem minden filedescriptor mvelet mkdik (pl. lseek -> ESPIPE zenet)
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-
rendszerhvsokat
szoks
hasznlni
hlzati
vrakozs egy I/O esemnyre Ezekre rszletesen a multiplexelt, aszinkron I/O s nem blokkold I/O fejezetekben trnk ki.
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-
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
AF_INET6
+ +
Protokolltl fggen
IPv4/ICMPv4/IGMPv4 IPv6/ICMPv6
feldolgozs
read ()
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -6-
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 kliens
socket() 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-
#include <sys/types.h> #include <sys/socket.h> 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. (<netinet/in.h> -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
Bind
int alen);
int bind (int fd, struct sockaddr *addrp, Fd: File ler, melyet socket() adott, Addrp: Cmler struktra cme:
sa_family;
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -8-
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.
Ekkor a mg t nem adott adatok elveszhetnek, vagy mg tvehetek, lsd SO_LINGER opci.
1.5.3.2 Shutdown
*/
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
level
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk -9-
10
engedlyez/tilt
int
SOL_SOCKET
+ + +
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 -
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
exponencilis kplet szerint szmolja ki.) Ilyenkor egy n. passzv socket keletkezik.
1.5.5.3 Connect elfogadsa (a szerver oldalon):
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 11 -
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
Send
int 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() */
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 12 -
13
int sendmsg (int fd, struct msghdr *msgp, Visszatrsi rtk, fd, flags: mint send()-nl
struct 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, <= MSG_MAXIOVLEN */ /* file lerk UNIX domain esetn */ /* ennek elemszma */
Ebben:
typedef struct iovec { caddr_t iov_base; int iov_len; } iovec_t; /* egy tviend terlet lersa */ /* terlet cme */ /* terlet hossza */ /* tpusnv */
Clcmet SOCK_STREAM esetn figyelmen kvl hagyja, eltte connect() kell. SOCK_DGRAM esetn a clcm szerintire kldi, ha nincs clcm (pl. write(), send()) s elzleg volt connect(), az ott megadottra. 1.5.7 Adatok tvtele Kapcsolat-orientlt esetben hasznlhat a read() is, lsd klds. Az itt ismertetend tbbi eszkz brmelyik fajta socket-hez hasznlhat. SOCK_STREAM esetn elbb connect()-elni kell. Ha adat elbb megrkezik, minthogy a cmzett bind()-eln a socket-jt, a datagram-ot eldobja.
1.5.7.1 Recv
char *buf, int maxlen, int flags);
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 -
14
int recvmsg (int fd, struct msghdr *msgp, int flags); Paramterek: mint sendmsg(), visszatrsi rtk: mint recv()
= 0 :OK, =-1: hiba; paramterek: mint accept() 1.5.9 Partner socket-cmnek lekrdezse:
1.5.9.1 Getpeername
struct sockaddr *addrp, int *alen);
= 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 -
15
1.5.10.2 Gethostent
#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> struct hostent * gethostent (void); /etc/hosts file megnyitsa, ha els hvs,
lezrsa
1.5.10.4 Gethostbyaddr
struct 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 Gethostbyname
struct 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 -
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:
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 16 -
17
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 -
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 */
#include <sys/time.h> #include <sys/select.h> 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 -
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.
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 19 -
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.
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 -
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.
22
2 pldk:
/* * 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 -
23
#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
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 23 -
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
/* * 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 -
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 -
26
/* * 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];
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 26 -
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);
/* * sender.c -- multicasts "hello, world!" to a multicast group once a second * */ #include #include #include #include #include #include <sys/types.h> <sys/socket.h> <netinet/in.h> <arpa/inet.h> <time.h> <string.h>
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 27 -
28
/* * 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 <sys/types.h> <sys/socket.h> <netinet/in.h> <arpa/inet.h> <time.h> <string.h> <stdio.h>
BME Szmtgphlzatok jegyzet. Csak bels hasznlatra. Minden jog fenn tartva. Copyright 2000, BME Irnytstechnika s Informatika Tanszk - 28 -
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 -