Áttekintés Felhasználói réteg Kliens-szerver Felhasználás igényei Háttér TCP vs. UDP Byte sorrend Socket I/O TCP/UDP szerver és kliens I/O multiplexing
Számítógépes Hálózatok 2010 2. Hálózati felhasználások -- socket programozás Bruce Maggs és Srinivasan Seshan (CMU) fóliái alapján
Hálózatok, 2010
1
Lukovszki Tamás
Hálózatok, 2010
3
application transport network data link physical
application transport network data link physical
2
Lukovszki Tamás
Kliens-szerver paradigma
Felhasználások és a felhasználói réteg protokolljai Felhasználások (hálózati) : kommunikáló elosztott processzek A hálózat végrendszerein (host) futnak (ugyanazon vagy különbözı végrendszeren) Üzeneteket cserélnek ki Pl. email, file transfer, Web Felhasználói réteg protokolljai Definiálják az üzeneteket, melyeket a felhasználások kicserélnek és az akciókat, amiket akkor végrehajtanak A kommunikáció megvalósítása alacsonyabb rétegek protokolljai által történik
Hálózatok, 2010
application transport network data link physical
Lukovszki Tamás
Tipikus hálózati felhasználásnak két része van: kliens és szerver Kliens: application transport Kezdeményezi a kapcsolatot a network data link szerverrel physical Tipikusan egy szolgáltatást igényel a request szervertıl, Web esetén a kliens a böngészıben implementált; e-mail esetén a mail olvasó programban Szerver: Az igényelt szolgáltatást bocsátja rendelkezésre a kliens számára pl. a web-szerver elküldi a kért weboldalt; a mail-szerver az e-mailt Hálózatok, 2010
4
reply application transport network data link physical
Lukovszki Tamás
FTP: File Transfer Protocol
FTP user interface user at host
FTP: Elkülönített kontroll- és adatkapcsolat
file transfer
FTP client
FTP server remote file system
local file system
Távol lévı végrendszertıl/végrendszerre szállít file-t Kliens/szerver modell Kliens: az az oldal, amely a file transzfert kezdeményezi Szerver: távoli végrendszer ftp: RFC 959 ftp server: port 21
Hálózatok, 2010
5
Lukovszki Tamás
Ftp-kliens a 21-es porton lép kapcsolatba az ftp-szerverrel és TCP-t adja meg szállítói protokollként Két párhuzamos TCP kapcsolat kerül megnyitásra: Kontroll: parancsok és válaszok kicserélésére a kliens és a szerver között “out of band control” Adat: file a szerverhez/szervertıl Az ftp-szerver státusz-információkat tárol: aktuális könyvtár, korábbi autentifikáció
Hálózatok, 2010
TCP control connection port 21
FTP client
TCP data connection port 20
6
FTP server
Lukovszki Tamás
Milyen szolgáltatásokra van a felhasználásoknak szüksége a szállítói rétegtıl?
Ftp parancsok, válaszok parancs példák: A kontroll csatornán küldött ASCII szöveg USER username PASS password LIST az aktuális könyvtár file-jainak a listájával tér vissza RETR filename letölti a file-t (get) STOR filename tárolja a file-t a távoli végrendszeren (put)
válasz példák status code és válasz szövegek 331 Username OK, password required 125 data connection already open; transfer starting 425 Can’t open data connection 452 Error writing file
Adat vesztés Néhány felhasználás eltőr valamennyi adatvesztést (pl. audio) Más felhasználások (pl. file transfer, telnet) 100% megbízható adatátvitelt igényelnek
Idızítés Néhány felhasználás (pl. Internet telefon, interaktív játékok) rövid késést (delay) igényelnek
Sávszélesség Néhány felhasználás (pl. multimedia) igényel egy minimálisan rendelkezésre álló sávszélességet Más felhasználások (“elastic apps”) azt a sávszélességet használják amit éppen kapnak Hálózatok, 2010
7
Lukovszki Tamás
Hálózatok, 2010
8
Lukovszki Tamás
Gyakori felhasználások igényei a szállítói réteg szolgáltatásaira
Application file transfer e-mail web documents real-time audio/ video stored audio/video interactive games financial apps
Áttekintés
Data loss
Bandwidth
Time Sensitive
no loss no loss no loss loss-tolerant
elastic elastic elastic audio: 5Kb-1Mb video:10Kb-5Mb same as above few Kbps elastic
no no no yes, 100’s msec
loss-tolerant loss-tolerant no loss
Hálózatok, 2010
9
yes, few secs yes, 100’s msec yes and no
Lukovszki Tamás
Szerver és Kliens
Hálózatok, 2010
10
Lukovszki Tamás
User Datagram Protocol(UDP)
Szerver és kliens a hálózaton üzeneteket cserélnek ki egymással a közös socket API által Socket-ek által a hálózati I/O hasonló a file I/O-hoz Rendszerfüggvény hívása a kontrollhoz és a kommunikációhoz A hálózat kezeli a routingot, szegmentálást, stb…
Hálózatok, 2010
Felhasználói réteg Kliens-szerver Felhasználás igényei Háttér TCP vs. UDP Byte sorrend Socket I/O TCP/UDP szerver és kliens I/O multiplexing
11
Lukovszki Tamás
UDP
UDP
Egyszerő socket üzenetek küldésére/fogadására Nincs garancia a megérkezésre Nem szükségszerően sorrendtartó Datagram – független csomagok Minden csomagot meg kell címezni Analógia: postai levél…
Hálózatok, 2010
12
Példa UDP felhasználásokra: Multimedia, voice over IP
Lukovszki Tamás
Transmission Control Protocol (TCP)
Hálózat címzési analógia Telefon hívás
TCP Megbízható – megérkezés garantált Byte folyam – sorrendtartó Kapcsolat-orientált – egy socket kapcsolatonként A kapcsolat felépítése után adatátvitel Analógia: telefon hívás
Példa TCP felhasználásokra: Web, Email, Telnet
Hálózati programozás
ELTE oktatók 209 0555 mellék: 8477
Felhasználások/Szerverek 209 0555 mellék: 8478
mellék
Port szám
Telefonszám
IP cím
Számítógépes hálózatok hallgatók Hálózatok, 2010
13
Lukovszki Tamás
Hálózati címzés
Hálózatok, 2010
Kliensek 14
Lukovszki Tamás
Port, mint szolgáltatás azonosítója
Az IP cím a socket-ben azonosítja a végrendszert (pontosabban egy adaptert a végrendszerben) A (jól ismert) port a szerver socket-ben azonosítja a szolgáltatást, ezáltal implicit azonosítja a végrendszerben a processzt, ami végrehajtja a szolgáltatatást Port szám lehet „Jól ismert” port (well-known port) (port 0-1023) Dinamikus vagy privát port (port 1024-65535) Szerverek/daemonok általában a jól ismert portokat használják Minden kliens azonosíthatja a szervert/szolgáltatást HTTP = 80, FTP controll = 21, Telnet = 23, mail = 25,... /etc/services tartalmazza a jól ismert portok listáját Linux rendszerben Kliensek általában dinamikus portokat használnak A kernel által futási idıben hozzárendelt Hálózatok, 2010
Mail Port 25
Web Port 80
15
Lukovszki Tamás
Server host 157.181.161.32 Client host
Service request for 157.181.161.32:80 (i.e., the Web server)
Web server (port 80) Kernel
Client
Echo server (port 7)
Client
Service request for 157.181.161.32:7 (i.e., the echo server)
Web server (port 80) Kernel Echo server (port 7)
Hálózatok, 2010
16
Lukovszki Tamás
Nevek és címek
Internet címzési adatstruktúra
Az Interneten minden kapcsolódási pontnak van egy egyértelmő címe amely az elhelyezkedésen alapul – a telefonszámokhoz hasonlóan Az ember jobban tud neveket kezelni mint címeket pl. www.inf.elte.hu DNS (domain name system) nevek címekre való leképezését bocsátja rendelkezésre A név a végrendszer adminisztrációs hovatartozásán alapul
#include
/* Internet address structure */ struct in_addr { u_long s_addr; /* 32-bit IPv4 address */ }; /* network byte ordered */ /* Socket address, Internet style. */ struct sockaddr_in { u_char sin_family; /* Address Family */ /* UDP or TCP Port# */ u_short sin_port; /* network byte ordered */ struct in_addr sin_addr; /* Internet Address */ char sin_zero[8]; /* unused */ }; sin_family = AF_INET
Hálózatok, 2010
17
Lukovszki Tamás
Byte sorrend
Hálózatok, 2010
18
Lukovszki Tamás
Byte sorrend függvények host byte order és network byte order közötti konvertálás ‘h’ = host byte order ‘n’ = network byte order ‘l’ = long (4 bytes), IP címet konvertál ‘s’ = short (2 bytes), port számot konvertál
union { u_int32_t addr; /* 4 bytes address */ char c[4]; } un; /* 157.181.161.32 */ un.addr = 0x9db5a120; /* c[0] = ? */
c[0] c[1] c[2] c[3] Big Endian Sun Solaris, PowerPC, ... Little Endian i386, alpha, ... Hálózat byte sorrend = Big Endian
Hálózatok, 2010
/*selects Internet address family*/
19
157
181
161
20
20
161
181
157
Lukovszki Tamás
#include unsigned unsigned unsigned unsigned
Hálózatok, 2010
long int htonl(unsigned long int hostlong); short int htons(unsigned short int hostshort); long int ntohl(unsigned long int netlong); short int ntohs(unsigned short int netshort);
20
Lukovszki Tamás
Áttekintés
Socket Egy socket egy file leíró, amin keresztül a felhasználás a hálózatba ír / hálózatból olvas
Felhasználói réteg Kliens-szerver Felhasználás igényei Háttér TCP vs. UDP Byte sorrend Socket I/O TCP/UDP szerver és kliens I/O multiplexing
int fd; /* socket descriptor */ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) } perror(“socket”); exit(1); } socket egy egész számot ad vissza (socket descriptor: fd) fd < 0 jelzi, hogy hiba lépett fel socket leíró (socket descriptor) hasonló a file leíróhoz, a fı különbség az, ahogy a felhasználás megnyitja a socket leírót AF_INET: a socket-et az Internet protokoll családhoz rendeli SOCK_STREAM: TCP protokoll SOCK_DGRAM: UDP protokoll
Hálózatok, 2010
21
Lukovszki Tamás
Hálózatok, 2010
22
Lukovszki Tamás
Socket I/O: socket()
TCP Szerver
Mivel a web forgalom TCP-t használ, a web-szervernek létre kell hozni egy socket-et SOCK_STREAM tipussal
Például: web-szerver (port 80) Mit kell a web-szervernek tenni, hogy egy web-kliens kapcsolatot létesíthessen vele?
int fd;
/* socket descriptor */
if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror(“socket”); exit(1); } socket egy egész számot ad vissza (socket descriptor: fd) fd < 0 jelzi, hogy hiba lépett fel AF_INET: a socket-et az Internet protokoll családhoz rendeli SOCK_STREAM: TCP protokoll
Hálózatok, 2010
23
Lukovszki Tamás
Hálózatok, 2010
24
Lukovszki Tamás
Socket I/O: bind()
Socket I/O: listen() listen jelzi, hogy a szerver kapcsolatot akar fogadni
Egy socket-et egy port-hoz lehet kötni int fd; struct sockaddr_in srv;
int fd; struct sockaddr_in srv;
/* socket descriptor */ /* used by bind() */
/* create the socket */ srv.sin_family = AF_INET;
/* use the Internet addr family */
srv.sin_port = htons(80);
/* bind socket ‘fd’ to port 80*/
/* bind: a client may connect to any of my addresses */ srv.sin_addr.s_addr = htonl(INADDR_ANY);
/* socket descriptor */ /* used by bind() */
/* 1) create the socket */ /* 2) bind the socket to a port */ if(listen(fd, 5) < 0) { perror(“listen”); exit(1); }
listen második paramétere a queue maximális hossza a függıben lévı kapcsolatkéréseknek (lásd késıbb) Még mindig nem tud kommunikálni a klienssel...
if(bind(fd, (struct sockaddr*) &srv, sizeof(srv)) < 0) { perror("bind"); exit(1); }
Még nem tud kommunikálni a klienssel... Hálózatok, 2010
25
Lukovszki Tamás
Socket I/O: accept()
26
Lukovszki Tamás
Socket I/O: accept() folytatás...
accept blokkolja (felfüggeszti) a szervert, várakozik a kapcsolatkérésre int fd; struct sockaddr_in srv; struct sockaddr_in cli; int newfd; int cli_len = sizeof(cli);
/* /* /* /* /*
socket descriptor */ used by bind() */ used by accept() */ returned by accept() */ used by accept() */
/* 1) create the socket */ /* 2) bind the socket to a port */ /* 3) listen on the socket */ newfd = accept(fd, (struct sockaddr*) &cli, &cli_len); if(newfd < 0) { perror("accept"); exit(1); }
accept egy új socket-et ad vissza (newfd) ugyanolyan tulajdonságokkal, mint az eredeti socket (fd) newfd < 0 jelzi, ha hiba történt Hálózatok, 2010
Hálózatok, 2010
27
Lukovszki Tamás
struct sockaddr_in cli; int newfd; int cli_len = sizeof(cli);
/* used by accept() */ /* returned by accept() */ /* used by accept() */
newfd = accept(fd, (struct sockaddr*) &cli, &cli_len); if(newfd < 0) { perror("accept"); exit(1); } Honnan tudja szerver, melyik kliens kapcsolódik hozzá? cli.sin_addr.s_addr tartalmazza a kliens IP címét cli.sin_port tartalmazza a kliens port számát Mostmár a szerver adatokat tud kicserélni a klienssel read és write funkciókat használva a newfd leírón. Miért kell, hogy accept egy új leírót adjon vissza? (gondoljunk egy szerverre, ami több klienst szimultán szolgál ki) Hálózatok, 2010
28
Lukovszki Tamás
Socket I/O: read()
TCP Kliens
read egy socket-tel használható read blokkol, a szerver az adatokra várakozik a klienstıl, de nem garantálja, hogy sizeof(buf) byte-ot olvas
int fd; char buf[512]; int nbytes; /* /* /* /*
1) 2) 3) 4)
Példa: web kliens Hogy kapcsolódik egy web-kliens a web-szerverhez?
/* socket descriptor */ /* used by read() */ /* used by read() */
create the socket */ bind the socket to a port */ listen on the socket */ accept the incoming connection */
if((nbytes = read(newfd, buf, sizeof(buf))) < 0) { perror(“read”); exit(1); } Hálózatok, 2010
29
Lukovszki Tamás
IP címek kezelése
30
Lukovszki Tamás
Nevek címre fordítása
IP címeket “157.181.161.32” sztringként szokás írni, de a programok az IP címeket egész számként kezelik Sztringek egész címmé konvertálása: struct sockaddr_in srv; srv.sin_addr.s_addr = inet_addr(“157.181.161.32”); if(srv.sin_addr.s_addr == (in_addr_t) -1) { fprintf(stderr, "inet_addr failed!\n"); exit(1); }
Egész címek sztriggé konvertálása: struct sockaddr_in srv; char *t = inet_ntoa(srv.sin_addr); if(t == 0) { fprintf(stderr, “inet_ntoa failed!\n”); exit(1); } Hálózatok, 2010
Hálózatok, 2010
31
Lukovszki Tamás
gethostbyname DNS-hez bocsát rendelkezésre interfészt Egyéb hasznos hívások gethostbyaddr – visszatér hostent-el, ami az adott sockaddr_in-hez tartozik getservbyname szogáltatás leírás lekérdezésére szokták használni (tipikusan port szám) visszatérı érték: servent a név alapján #include struct hostent *hp; /*ptr to host info for remote*/ struct sockaddr_in peeraddr; char *name = “www.inf.elte.hu”; peeraddr.sin_family = AF_INET; hp = gethostbyname(name) peeraddr.sin_addr.s_addr = ((struct in_addr*)(hp->h_addr))->s_addr; Hálózatok, 2010
32
Lukovszki Tamás
Socket I/O: connect()
Socket I/O: write()
connect: a kliens blokkolódik, amíg a kapcsolat létre nem jön Miután folytatódik, a kliens kész üzeneteket kicserélni a szerverrel az fd leíróval. int fd; struct sockaddr_in srv;
/* socket descriptor */ /* used by connect() */
int fd; struct sockaddr_in srv; char buf[512]; int nbytes;
/* create the socket */ /* connect: use the Internet address family */ srv.sin_family = AF_INET;
socket descriptor */ used by connect() */ used by write() */ used by write() */
/* Example: A client could “write” a request to a server */ if((nbytes = write(fd, buf, sizeof(buf))) < 0) { perror(“write”); exit(1); }
/* connect: connect to IP Address “157.181.161.52” */ srv.sin_addr.s_addr = inet_addr(“157.181.161.52”); if(connect(fd, (struct sockaddr*) &srv, sizeof(srv)) < 0) { perror(”connect"); exit(1); } 33
Lukovszki Tamás
TCP kliens-szerver interakció
/* /* /* /*
/* 1) create the socket */ /* 2) connect() to the server */
/* connect: socket ‘fd’ to port 80 */ srv.sin_port = htons(80);
Hálózatok, 2010
write egy socket leíróval használható
TCP Server
Hálózatok, 2010
34
Lukovszki Tamás
UDP szerver példa
socket()
Példa: NTP (Network Time Protocol) daemon (port 123)
bind() listen()
TCP Client socket() connect() write()
data request
read() data reply
read() close()
Mit kell egy UDP szervernek tenni, hogy egy UDP kliens kapcsolódhasson hozzá?
accept() blocks until connection connection establishment from client
end-of-file notification
write() read() close()
UNIX Network Programming Volume 1, figure 4.1 Hálózatok, 2010
35
Lukovszki Tamás
Hálózatok, 2010
36
Lukovszki Tamás
Socket I/O: socket()
Socket I/O: bind() Egy socket-et egy port-hoz köthetünk
A UDP szervernek létre kell hozni egy datagram socket-et int fd;
int fd; struct sockaddr_in srv;
/* socket descriptor */ /* used by bind() */
/* socket descriptor */ /* create the socket */
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror(“socket”); exit(1); }
/* bind: use the Internet address family */ srv.sin_family = AF_INET; /* bind: socket ‘fd’ to port 123*/ srv.sin_port = htons(123);
socket egy egészet ad vissza (socket descriptor fd ) fd < 0 jelzi, ha hiba történt
/* bind: a client may connect to any of my addresses */ srv.sin_addr.s_addr = htonl(INADDR_ANY);
AF_INET: a socketet az Internet protokoll családdal asszociálja SOCK_DGRAM: UDP protokoll
if(bind(fd, (struct sockaddr*) &srv, sizeof(srv)) < 0) { perror("bind"); exit(1); }
Ezután már a UDP szerver csomagokat tud fogadni… Hálózatok, 2010
37
Lukovszki Tamás
Hálózatok, 2010
38
Socket I/O: recvfrom()
Socket I/O: recvfrom() folytatás...
read nem bocsátja a kliens címét a UDP szerver rendelkezésére
nbytes = recvfrom(fd, buf, sizeof(buf), 0 /* flags */, (struct sockaddr*) cli, &cli_len);
int fd; struct sockaddr_in srv; struct sockaddr_in cli; char buf[512]; int cli_len = sizeof(cli); int nbytes;
/* /* /* /* /* /*
socket descriptor */ used by bind() */ used by recvfrom() */ used by recvfrom() */ used by recvfrom() */ used by recvfrom() */
Lukovszki Tamás
A recvfrom által végrehajtott akciók visszaadja az olvasott byte-ok számát (nbytes) nbytes adatot másol buf-ba visszaadja a kliens címét (cli) visszaadja cli hosszát (cli_len)
/* 1) create the socket */ /* 2) bind to the socket */
ne törıdjünk a flag-ekkel
nbytes = recvfrom(fd, buf, sizeof(buf), 0 /* flags */, (struct sockaddr*) &cli, &cli_len); if(nbytes < 0) { perror(“recvfrom”); exit(1); } Hálózatok, 2010
39
Lukovszki Tamás
Hálózatok, 2010
40
Lukovszki Tamás
UDP kliens példa
Socket I/O: sendto() write nem megengedett! Figyeljük meg, hogy a UDP kliensnél nincs port szám kötés (bind) egy port szám dinamikusan rendelıdik hozzá az elsı sendto hivásakor
Mit kell tenni egy UDP kliensnek, hogy kommunikálhasson egy UDP szerverrel?
int fd; struct sockaddr_in srv;
/* socket descriptor */ /* used by sendto() */
/* 1) create the socket */ /* sendto: send data to IP Address “157.181.161.32” port 123 */ srv.sin_family = AF_INET; srv.sin_port = htons(123); srv.sin_addr.s_addr = inet_addr(“157.181.161.32”); nbytes = sendto(fd, buf, sizeof(buf), 0 /* flags */, (struct sockaddr*) &srv, sizeof(srv)); if(nbytes < 0) { perror(“sendto”); exit(1); } Hálózatok, 2010
41
UDP kliens-szerver interakció
Lukovszki Tamás
Hálózatok, 2010
42
Lukovszki Tamás
UDP szerver
UDP Server socket()
Hogy tud a UDP szerver több klienst szimultán kiszolgálni?
bind()
UDP Client
recvfrom()
socket() sendto()
data request
data reply
blocks until datagram received from a client
sendto()
recvfrom() close() from UNIX Network Programming Volume 1, figure 8.1 Hálózatok, 2010
43
Lukovszki Tamás
Hálózatok, 2010
44
Lukovszki Tamás
UDP Szerver: két port kiszolgálása int s1; int s2; /* /* /* /*
1) 2) 3) 4)
Socket I/O: select()
/* socket descriptor 1 */ /* socket descriptor 2 */
select szinkron I/O multiplexálást enged meg int s1, s2; fd_set readfds;
create socket s1 */ create socket s2 */ bind s1 to port 2000 */ bind s2 to port 3000 */
/* create and bind s1 and s2 */ while(1) { FD_ZERO(&readfds); /* initialize the fd set */ FD_SET(s1, &readfds); /* add s1 to the fd set */ FD_SET(s2, &readfds); /* add s2 to the fd set */
while(1) { recvfrom(s1, buf, sizeof(buf), ...); /* process buf */
if(select(s2+1, &readfds, 0, 0, 0) < 0) { perror(“select”); exit(1); } if(FD_ISSET(s1, &readfds)) { recvfrom(s1, buf, sizeof(buf), ...); /* process buf */ } /* do the same for s2 */
recvfrom(s2, buf, sizeof(buf), ...); /* process buf */ } Milyen probléma ezzel a kóddal? Hálózatok, 2010
}
45
Lukovszki Tamás
Socket I/O: select()
Hálózatok, 2010
46
Lukovszki Tamás
Socket I/O: select()
int select(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); FD_CLR(int fd, fd_set *fds); FD_ISSET(int fd, fd_set *fds); FD_SET(int fd, fd_set *fds); FD_ZERO(fd_set *fds);
/* socket descriptors */ /* used by select() */
/* /* /* /*
clear the bit for fd in fds */ is the bit for fd in fds? */ turn on the bit for fd in fds */ clear all bits in fds */
maxfds: tesztelendı leírók (descriptors) száma (0, 1, ... maxfds-1) leírókat kell tesztelni readfds: leírók halmaza, melyet figyelünk, hogy érkezik-e adat visszaadja a leírók halmazát, melyek készek az olvasásra (ahol adat van jelen) Ha az input érték NULL, ez a feltétel nem érdekel writefds: leírók halmaza, melyet figyelünk, hogy írható-e
int select(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); struct timeval { long tv_sec; long tv_usec; }
/* seconds / /* microseconds */
timeout ha NULL, várakozzunk addig amíg valamelyik leíró I/O-ra kész különben várakozzunk a timeout-ban megadott ideig Ha egyáltalán nem akarunk várni, hozzunk létre egy timeout structure-t, melyben a timer értéke 0 Több információhoz: man page
visszaadja a leírók halmazát amelyek készek az írásra exceptfds: leírók halmaza, melyet figyelünk, hogy exception érkezik-e visszaadja a leírók halmazát amelyeken kivétel érkezik Hálózatok, 2010
47
Lukovszki Tamás
Hálózatok, 2010
48
Lukovszki Tamás
Socket I/O: select()
Néhány részlet egy web-szerverrıl
int fd, n=0; /* original socket */ int newfd[10]; /* new socket descriptors */ while(1) { fd_set readfds; FD_ZERO(&readfds); FD_SET(fd, &readfds);
Hogy tud egy web-szerver több kapcsolatot szimultán kezelni?
/* Now use FD_SET to initialize other newfd’s that have already been returned by accept() */ select(maxfd+1, &readfds, 0, 0, 0); if(FD_ISSET(fd, &readfds)) { newfd[n++] = accept(fd, ...); } /* do the following for each descriptor newfd[i], i=0,…,n-1*/ if(FD_ISSET(newfd[i], &readfds)) { read(newfd[i], buf, sizeof(buf)); /* process data */ } }
Ezután a web-szerver képes többb kapcsolatot kezelni... Hálózatok, 2010
49
Lukovszki Tamás
Socket programozás referenciák Man page használat: man Beej's Guide to Network Programming: http://beej.us/guide/bgnet/ W. R. Stevens: Unix Network Programming : Networking APIs: Sockets and XTI (Volume 1) 2, 3, 4, 6, 8 fejezet
Hálózatok, 2010
51
Lukovszki Tamás
Hálózatok, 2010
50
Lukovszki Tamás