Upload
shawn
View
34
Download
0
Embed Size (px)
DESCRIPTION
010990001 - Tietoliikennetekniikan jatko-opintokurssi 2. Unix Network Programming Sockets Networking API Chapter 6 - I/O Multiplexing: the select and poll functions. I/O-tyypit. Kun asiakasohjelman pitää hoitaa useita syötteitä ja tulostuksia, jonkinlaista kanavointia tulisi käyttää niissä - PowerPoint PPT Presentation
Citation preview
010990001 - Tietoliikennetekniikan jatko-
opintokurssi 2Unix Network Programming
Sockets Networking API
Chapter 6 - I/O Multiplexing: theselect and poll functions
I/O-tyypit
• Kun asiakasohjelman pitää hoitaa useita syötteitä ja tulostuksia, jonkinlaista kanavointia tulisi käyttää niissä
• Unix-järjestelmässä 5 eri I/O-mallia:– blocking I/O– nonblocking I/O– I/O multiplexing (select, poll)– signal driven I/O (SIGIO)– asynchronous I/O (POSIX aio_ -funktiot)
Blocking I/O
• Yleisin malli, oletuksena kaikki socketit ovat blokkaavia
Nonblocking I/O
• Kun socket on asetettu nonblocking-tilaan, kernel palauttaa virheen, mikäli socketia käyttävä pyyntö ei onnistu välittömästi
I/O Multiplexing
• I/O multiplexing -mallissa käytetään select- ja/tai poll-funktioita
• blocking I/O -mallissa lukittuvan read/write/connect -kutsun sijasta select on se lukittuva funktio, mutta se odottaa useiden syötteiden tapahtumia
• Yhtä syötettä käyttäessä huonompi vaihtoehto kuin tavallinen blocking I/O
Signal-Driven I/O
• Kernel välittää SIGIO-signaalin, kun I/O-operaatio voidaan aloittaa
Asynchronous I/O
• POSIX:ssa määritelty aio_-alkuisia funktioita, mutta tuki on aika rajoittunutta
• aio_ -kutsun (esim. aio_read) yhteydessä kerrotaan kernelille signaali, joka sen tulee palauttaa, kun I/O-operaatio on valmis (vrt. signal-driven)
• Funktio palaa välittömästi, ja prosessi jatkaa suoritustaan sillä aikaa. Kun määritelty signaali tulee kerneliltä, luetaan syötteestä
Asynchronous I/O
I/O-mallien vertailu
waitfordata
copydatafromkerneltouser
select-funktio
• select-kutsulla voidaan seurata, milloin– kuvaaja (fd) on luettavissa– kuvaaja on kirjoitettavissa– kuvaajan kohteessa tapahtuu jokin poikkeus
• Eri joukot luettavuus-,kirjoitettavuus- ja poikkeustarkastuksille
#include <sys/select.h> #include <sys/time.h>
int select (int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);
select-funktio• timeval-rakenteessa 2 komponenttia,
sekunnit ja mikrosekunnit struct timeval { long tv_sec; /* seconds. */ long tv_usec; /* microseconds */ };
• Odotusajassa 3 vaihtoehtoa– odottaa ikuisesti (timeval *timeout = NULL)
– odottaa tietyn aikaa (asetetaan timeval)– palaa välittömästi
(timeout.tv_sec = 0, timeout.tv_usec = 0)
select-funktio• Luku-, kirjoitus- ja poikkeusjoukkoja
voidaan käsitellä 4 makrolla:void FD_ZERO (fd_set *readset);
void FD_SET (int fd, fd_set *readset);
void FD_CLR (int fd, fd_set *readset);
int FD_ISSET (int fd, fd_set *readset);
• Ensimmäinen nollaa joukon, toinen lisää sinne yhden kuvaajan, kolmas poistaa ja neljäs tarkistaa, sisältyykö kuvaaja tiettyyn joukkoon
select-funktio
• select-funktion ensimmäinen argumentti maxfdp1 on (joukkojen suurin fd) + 1 (huom. ei kuvaajien määrä + 1)
select-funktio
• valmiusehdot lukujoukolle, eli milloin select-funktio palaa: – dataa on luettavissa enemmän kuin ”low-water
mark”, oletuksena low-water mark on 1– lukupuoli on suljettu (esim. TCP:ssä saatu
FIN), lukuoperaatio palauttaa 0– kuuntelevassa socketissa valmiita yhteyksiä– virhe odotettavissa, lukuoperaatio palauttaa -1
ja err_no :n arvo asetetaan
select-funktio
• valmiusehdot kirjoitusjoukolle:– lähetysbufferissa dataa enemmän kuin ”low-
water mark” ja socket a) yhdistetty b) ei tarvitse yhdistämistä (esim. UDP)
– kirjoituspuoli suljettu, kirjoitusoperaatio luo SIGPIPE -signaalin
– non-blocking connect-funktiota käyttävä yhteys on valmis tai connect epäonnistunut
– socket-virhe odotettavissa, kirjoitusoperaatio palauttaa -1 ja err_no-arvo asetetaan
select-funktio
void str_cli(FILE *fp, int sockfd){
int maxfdp1;fd_set rset;char sendline[MAXLINE], recvline[MAXLINE];
FD_ZERO(&rset);for ( ; ; ) {
FD_SET(fileno(fp), &rset);FD_SET(sockfd, &rset);maxfdp1 = max(fileno(fp), sockfd) + 1;Select(maxfdp1, &rset, NULL, NULL, NULL);
if (FD_ISSET(sockfd, &rset)) { /* socket is readable */if (Readline(sockfd, recvline, MAXLINE) == 0) err_quit("str_cli: server terminated
prematurely");Fputs(recvline, stdout);
}if (FD_ISSET(fileno(fp), &rset)) { /* input is readable */
if (Fgets(sendline, MAXLINE, fp) == NULL)return; /* all done */
Writen(sockfd, sendline, strlen(sendline));} } }
Batch mode
shutdown-funktio
• Batch-mode voi aiheuttaa ongelmia, jos funktio palaa ja fd suljetaan liian aikaisin– ratkaisu sulkemalla puolet TCP-yhteydestä,
mutta pitämällä socketin fd yhä luettavana
• Tämä voidaan tehdä shutdown-funktiollaint shutdown (int sockfd, int howto);
• howto voi olla SHUT_RD, SHUT_WR, SHUT_RDWR
shutdown-funktio & TCP
voidstr_cli(FILE *fp, int sockfd){ int maxfdp1, stdineof; fd_set rset; char buf[MAXLINE]; int n;
stdineof = 0; FD_ZERO(&rset); for ( ; ; ) { if (stdineof == 0) FD_SET(fileno(fp), &rset); FD_SET(sockfd, &rset); maxfdp1 = max(fileno(fp),
sockfd) + 1; Select(maxfdp1, &rset, NULL,
NULL, NULL);
if (FD_ISSET(sockfd, &rset)) { if ( (n = Read(sockfd, buf,
MAXLINE)) == 0) { if (stdineof == 1) return; else err_quit("str_cli: server
terminated prematurely"); } Write(fileno(stdout), buf, n); }
if (FD_ISSET(fileno(fp), &rset)) { if ( (n = Read(fileno(fp), buf,
MAXLINE)) == 0) { stdineof = 1; Shutdown(sockfd, SHUT_WR);
FD_CLR(fileno(fp), &rset); continue; } Writen(sockfd, buf, n); } }}
pselect-funktio• int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
• 2 muutosta select-funktioon verrattuna– Käyttää timespec-rakennetta timeval:n sijasta,
toisena jäsenenä nanosekunnit– Signaalimaski-osoitin, jolla
• Käsitellään tarkemmin myöhemmin (kappaleessa 20)
poll-funktioint poll(struct pollfd *fdarray, unsigned int nfds, int
timeout);
struct pollfd {
int fd;
short events;
short revents;
};
• Poll-funktiolla voidaan määritellä halutut tapahtumat, joita odotetaan kuvaajasta (vain stream-tyyppiset inputit)