Académique Documents
Professionnel Documents
Culture Documents
Reti di Calcolatori
A.A. 2007-2008
LABORATORIO
Lezione
Obiettivo
Autunno 2007
LABORATORIO
Ambiente di sviluppo
LINUX
Compilatore C
Socket per la comunicazione in rete
Autunno 2007
Desktop grafico
LABORATORIO
Desktop grafico
Usare solo per scaricare gli esempi
Terminale testuale
CTRL-ALT-F1
CTRL-ALT-F6
Linea di comando
Autunno 2007
LABORATORIO
Terminale testuale
Line di comando
Prompt
robdep@zircone:~/Corsi/Reti/C> gmake
gcc -g -O0 -Werror -c lib-errori.c
gcc -g -O0 -Werror -c lib-corso-reti.c
compiling daytimesrv.c with rule 1
robdep@zircone:~/Corsi/Reti/C>
Comandi
ls, cd, pwd, cp, rm, mv, cat, mkdir
man <comando>
Shell
Autunno 2007
LABORATORIO
Shell
il programma che interpreta i comandi
BASH
la shell standard di Linux
Echo $SHELL
File
Autunno 2007
LABORATORIO
Editor di file
vi
emacs
Manuali
Una ricerca su Internet vi fornir numerosi fonti
manuale editor vi
Programmi in C
Autunno 2007
LABORATORIO
#include <stdio.h>
int main(int argc, char **argv) {
union {
short s;
char c[sizeof(short)];
} un;
un.s = 0x0102;
printf("CPU = %s - byte ordering: ",getenv("CPU"));
if (sizeof(short) == 2) {
if ( un.c[0] == 1 && un.c[1] == 2 )
printf ("big("big-endian\
endian\n");
else if ( un.c[0] == 2 && un.c[1] == 1 )
printf ("little("little-endian\
endian\n");
else
printf("unknown\
printf("unknown\n");
}
else
printf("size of short: %d.\
%d.\n",sizeof(short));
exit(0);
}
Compilazione e Makefile
Autunno 2007
LABORATORIO
Il sorgente C va compilato
Compilare un programma consiste nel
gcc ls1.c
gcc o ls1 ls1.c
gcc Lmylibpath lmylib Imyincpath O DDEBUG ...
Makefile
Makefile
Autunno 2007
LABORATORIO
#Makefile
ALL = lib-errori lib-corso-reti \
daytimesrv daytimecli daytimesrv-ric \
echosrv echocli echosrv-sigh
all: $(ALL)
.c:
lib-errori.o lib-corso-reti.o
@echo compiling $< with rule 1
gcc $< -g -O0 Werror -o $@ lib-errori.o lib-corso-reti.o
lib-errori: lib-errori.c
gcc -g -O0 -Werror -c lib-errori.c
lib-corso-reti: lib-corso-reti.c
gcc -g -O0 -Werror -c lib-corso-reti.c
clean:
rm -f $(ALL)
rm -f *~
rm -f *.o
Esempio
Autunno 2007
LABORATORIO
10
robdep@zircone:~/Corsi/Reti/C> gmake
gcc -g -O0 -Werror -c lib-errori.c
gcc -g -O0 -Werror -c lib-corso-reti.c
compiling daytimesrv.c with rule 1
gcc daytimesrv.c -g -O0 -Werror -o daytimesrv lib-errori.o
lib-corso-reti.o
compiling daytimecli.c with rule 1
gcc daytimecli.c -g -O0 -Werror -o daytimecli lib-errori.o
lib-corso-reti.o
compiling daytimesrv-ric.c with rule 1
gcc daytimesrv-ric.c -g -O0 -Werror -o daytimesrv-ric liberrori.o lib-corso-reti.o
compiling echosrv.c with rule 1
gcc echosrv.c -g -O0 -Werror -o echosrv lib-errori.o libcorso-reti.o
Autunno 2007
LABORATORIO
11
#include <nome.h>
Cerca il file da includere nelle directory di ricerca
standard del compilatore
/usr/include, /usr/lib/include, ...
# include nome.h
Cerca il file da includere nella cwd
Autunno 2007
Basic.h
#ifndef __BASIC__
#define __BASIC__
#include
<sys/types.h>
#include
<sys/socket.h>
#include
<sys/time.h>
#include
<time.h>
#include
<netinet/in.h>
#include
<arpa/inet.h>
#include
<errno.h>
LABORATORIO
12
#include
#include
#include
#define
#define
#define
#define
<unistd.h>
<sys/wait.h>
<sys/un.h>
MAXLINE 256
PORT 12345
BACKLOG 5
MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
Autunno 2007
LABORATORIO
13
File lib-errori.c
err_msg
err_quit, err_sys
Autunno 2007
LABORATORIO
14
reti_writen
reti_readline
Reti di Calcolatori
A.A. 2007-2008
Socket TCP
Lezione
Socket
Autunno 2007
LABORATORIO
16
Autunno 2007
LABORATORIO
17
socket()
bind()
CLIENT
socket()
accept()
Aspetta una
connessione
connect()
write()
read()
Dati (richiesta)
read()
Dati (risposta)
close()
Notificazione di fine comunicazione
SERVER
listen()
write()
read()
close()
Autunno 2007
Sockaddr_in
struct in_addr {
in_addr_t
}
s_addr;
struct sockaddr_in {
uint8_t
sin_len;
sa_family_t
sin_family;
in_port_t
sin_port;
struct in_addr
sin_addr;
char
sin_zero[8];
}
struct sockaddr {
uint8_t
sa_family_t
char
}
sin_len;
sin_family;
sa_data[14];
LABORATORIO
18
sin_zero
Utilizzata per far si che la grandezza della struttura sia almeno 16 byte
sin_len
Funzione socket
Autunno 2007
LABORATORIO
19
Autunno 2007
LABORATORIO
20
#include <sys/socket.h>
int socket(int family, int type, int protocol );
Valore di ritorno: -1 se errore
un socket descriptor se OK
10
Funzione socket
Autunno 2007
LABORATORIO
21
int family
AF_INET
AF_INET6
AF_LOCAL
AF_ROUTE
altri
IPv4
IPv6
prot. locale (client e server sullo stesso host)
Sockets per routing
int type
int protocol
Funzione connect
Autunno 2007
LABORATORIO
22
#include <sys/socket.h>
int connect(int sd, struct sockaddr *servaddr, socklen_t addrlen);
Valore di ritorno: -1 se errore, 0 se OK
11
Autunno 2007
Funzione bind
LABORATORIO
23
#include <sys/socket.h>
int bind(int sd, struct sockaddr*myaddr, socklen_t addrlen);
Valore di ritorno: -1 se errore, 0 se OK
Funzione listen
Autunno 2007
LABORATORIO
24
#include <sys/socket.h>
int listen(int sd, int backlog);
Valore di ritorno: -1 se errore, 0 se OK
Usata solo da un server TCP, serve a
1. Convertire il socket da attivo a passivo, per far s che il
kernel accetti connessioni sul socket
Per default un socket creato attivo, e il kernel si aspetta che sia
il socket di un client
Nel diagramma a stati TCP fa muovere da CLOSED a LISTEN
12
Autunno 2007
Backlog
Server
LABORATORIO
25
CODA connessioni
completate
(stato ESTABLISHED)
accept
apertura
conn. completata
CODA connessioni
incomplete
(stato SYN_RCVD)
SYN apertura
connessione
Funzione accept
Autunno 2007
LABORATORIO
26
#include <sys/socket.h>
int accept(int sd, struct sockaddr*cliaddr, socklen_t addrlen);
Valore di ritorno: -1 se errore, socked descriptor se OK
13
Daytime server
Autunno 2007
LABORATORIO
27
#include
"basic.h
daytimesrv.c
#include
<time.h>
int main(int argc, char **argv) {
pid_t
pid;
int
listenfd, connfd;
struct sockaddr_in
servaddr;
char
buff[MAXLINE];
time_t
ticks;
if (argc != 2) err_quit("usage: daytimesrv <porta>");
if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family
= AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port
= htons(atoi(argv[1]));
if( (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0)
err_sys("bind error");
if( listen(listenfd, 5) < 0 ) err_sys("listen error");
for ( ; ; ) {
if( (connfd = accept(listenfd, (struct sockaddr *) NULL, NULL)) < 0)
err_sys("accept error");
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
write(connfd, buff, strlen(buff));
close(connfd);
}
}
Server iterativo
Autunno 2007
LABORATORIO
28
14
Autunno 2007
Funzione inet_pton
LABORATORIO
29
#include <sys/socket.h>
int inet_pton(int af, const char* stringa, void* dest);
Valore di ritorno: 0 se errore, > 0 se OK
Presentazione: stringa
192.41.218.1
Autunno 2007
Daytime client
#include
"basic.h"
int main(int argc, char **argv) {
int
sockfd, n;
char
recvline[MAXLINE + 1];
struct sockaddr_in
servaddr;
LABORATORIO
30
daytimecli.c
15
Autunno 2007
Server ricorsivi
LABORATORIO
31
pid;
listenfd, connfd;
listenfd = socket(.);
/* riempi la struttura sockaddr_in (es. numero di porta) */
bind(listenfd,.)
listen(listenfd, LISTENQ)
for ( ; ; ) {
connfd = accept(listenfd,);
if ( (pid = fork()) == 0) {
close(listenfd); /* figlio chiude il socket di ascolto */
DOIT(connfd);
/* serve la richiesta */
close(connfd);
/* chiude il socket */
exit(0);
/* il figlio termina */
}
close(connfd);
/* il padre chiude il socket della connessione */
}
Autunno 2007
Server iterativi
LABORATORIO
32
Client
Server
listensd
connect()
Richiesta di connessione
Server
listensd
connect()
Connessione stabilita
connsd
16
Autunno 2007
Server ricorsivi
Client
LABORATORIO
33
Server
listensd
Connessione stabilita
connect()
connsd
padre
Server
listensd
connsd
figlio
Autunno 2007
Server ricorsivi
Client
LABORATORIO
34
Server
listensd
connect()
connsd
Connessione stabilita
padre
Server
listensd
connsd
Il padre chiude il socket della connessione
figlio
17
Getsockname e getpeername
Autunno 2007
LABORATORIO
35
#include <sys/socket.h>
int getsockname(int sd, struct sockaddr*localaddr, socklen_t addrlen);
int getpeername(int sd, struct sockaddr*remoteaddr, socklen_t addrlen);
Valore di ritorno: -1 se errore, socked descriptor se OK
Ritornano
Serve perch
Un client che non chiama bind non sa quale porta stata usata
Un client non sa lindirizzo IP usato se ci sono pi interfaccie
Una chiamata a bind con porta=0 assegna una porta effimera
Stessa cosa per lindirizzo IP (INADDR_ANY)
Dopo una exec si pu risalire agli indirizzi della connessione
NB: un file descriptor rimane aperto quando si chiama exec
"basic.h"
"echo.h"
Autunno 2007
LABORATORIO
36
echosrv.c
18
Autunno 2007
LABORATORIO
37
for ( ; ; ) {
cliaddr_len = sizeof(cliaddr);
if( (connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &cliaddr_len)) < 0)
err_sys("accept error");
if( (childpid = fork()) == 0 ) {
close(listenfd);
str_echo(connfd);
exit(0);
}
close(connfd);
}
}
void str_echo(int sockfd) {
ssize_t
n;
char
line[MAXLINE];
for ( ; ; ) {
if ( (n = read(sockfd, line, MAXLINE)) == 0)
return;
/* connection closed by other end */
write(sockfd, line, n);
}
}
Autunno 2007
LABORATORIO
38
echocli.c
if (argc != 2)
err_quit("usage: echotcpcli <IPaddress>");
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
/* echo server */
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
str_cli(stdin, sockfd); /* svolge tutto il lavoro del client */
exit(0);
}
19
Autunno 2007
LABORATORIO
39
Autunno 2007
Echo server
LABORATORIO
40
Local address
0
*.9877
Foreign address
*.*
(state)
In unaltra finestra
prompt > netstat a
Proto RecvRecv-Q SendSend-Q
Tcp
0
Tcp
0
Tcp
0
Local address
Foreign address
0
localhost.9877
localhost.1052
0
localhost.1052
localhost.9877
0
*.9877
*.*
(state)
ESTABLISHED
ESTABLISHED
LISTEN
20
Autunno 2007
Echo server
prompt > echoclient 127.0.0.1
Ciao server
Ciao server
Arrivederci
Arrivederci
^D
prompt >
prompt > netstat a | grep 9877
0
Tcp
0
Tcp
0
0
LABORATORIO
41
Digitata al terminale
Risposta del server
Digitata al terminale
Risposta del server
Digitata al terminale
localhost.1052
*.9877
localhost.9877
*.*
TIME_WAIT
LISTEN
Mantenere informazioni nel caso lultimo ACK viene perso e laltro lato
rispedisce lultimo FIN
Permettere a vecchi pacchetti di essere eliminati dalla rete in modo da non
farli interferire con successive connessioni
Echo server
Autunno 2007
LABORATORIO
42
21
Segnale SIGCHLD
Autunno 2007
LABORATORIO
43
zombie
Autunno 2007
LABORATORIO
44
22
Signal handler
Autunno 2007
LABORATORIO
45
Autunno 2007
LABORATORIO
46
23
Autunno 2007
LABORATORIO
47
for ( ; ; ) {
clilen = sizeof(cliaddr);
if ( (connfd = accept(listenfd, &cliaddr, &clilen)) < 0) {
if (errno = EINTR)
continue;
else {
perror(accept error);
exit(1);
}
}
}
Autunno 2007
LABORATORIO
48
24
Autunno 2007
LABORATORIO
49
SIGPIPE
Autunno 2007
LABORATORIO
50
25
Autunno 2007
LABORATORIO
51
Autunno 2007
LABORATORIO
52
26
Server somma
Autunno 2007
LABORATORIO
53
Client somma
sommasrv.c
Autunno 2007
LABORATORIO
54
27
Autunno 2007
Problema
LABORATORIO
55
Reti di Calcolatori
A.A. 2007-2008
Socket UDP
Lezione
28
Autunno 2007
UDP
LABORATORIO
57
TCP
Trasporto orientato alla connessione, affidabile
UDP
Senza connessione, inaffidabile
Autunno 2007
socket()
recvfrom()
Aspetta un
datagram
Dati (richiesta)
recvfrom()
Aspetta un
datagram
close()
SERVER
CLIENT
58
socket()
sendto()
LABORATORIO
sendto()
Dati (risposta)
close()
29
Autunno 2007
LABORATORIO
59
const
Autunno 2007
LABORATORIO
60
echoudpsrv.c
30
Autunno 2007
LABORATORIO
61
"basic.h"
"echo.h"
echoudpcli.c
sockfd;
servaddr;
if (argc != 2)
err_quit("usage: udpclient <IPaddress>");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
err_sys("socket error");
client_echo_udp(stdin, sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
exit(0);
}
Autunno 2007
LABORATORIO
62
socklen_t servlen) {
p_replyaddr = malloc(servlen);
while (fgets(sendline, MAXLINE, fp) != NULL) {
sendto(sockfd, sendline, strlen(sendline), 0, p_servaddr, servlen);
len = servlen;
if( (n = recvfrom(sockfd, recvline, MAXLINE, 0, p_replyaddr, &len)) < 0 )
err_sys("recvfrom error");
if( (len != servlen) || memcmp(p_servaddr, p_replyaddr, len) != 0 ) {
struct sockaddr_in *sin = (struct sockaddr_in *) p_replyaddr;
err_msg("risposta da %s ignorata\
ignorata\n",
inet_ntop(AF_INET, &sin&sin->sin_addr, buff, sizeof(buff)));
continue;
}
recvline[n] = 0;
fputs(recvline, stdout);
}
}
31
Autunno 2007
LABORATORIO
63
Esercizio
Provare a creare una situazione del genere
Sul sito c il codice di spedisce_dg.c
Permette di spedire un datagram verso una porta UDP
Datagrammi perduti
Autunno 2007
LABORATORIO
64
32
Connect e UDP
Autunno 2007
LABORATORIO
65
Autunno 2007
LABORATORIO
66
33
Autunno 2007
connect
LABORATORIO
67
Autunno 2007
LABORATORIO
68
void client_echo_udp_conn(FILE *fp, int sockfd, const struct sockaddr *p_servaddr, socklen_t servlen) {
int
char
n;
sendline[MAXLINE], recvline[MAXLINE + 1];
/* null terminate */
}
}
echoudpcliechoudpcli-connect.c
34
Autunno 2007
Inaffidabilit di UDP
LABORATORIO
69
"basic.h"
"echo.h"
Autunno 2007
LABORATORIO
70
echoudpcliechoudpcli-count.c
35
Autunno 2007
LABORATORIO
71
Autunno 2007
2000
/* #datagrams to send */
1400
/* length of each datagram */
LABORATORIO
72
echoudpcliechoudpcli-count.c
void client_echo_udp_count(FILE *fp, int sockfd, const struct sockaddr *pservaddr, socklen_t servlen) {
int
i;
char
sendline[MAXLINE];
for (i = 0; i < NDG; i++) {
sendto(sockfd, sendline, DGLEN, 0, pservaddr, servlen);
}
}
36
Autunno 2007
LABORATORIO
73
Reti di Calcolatori
A.A. 2007-2008
I/O Multiplexing
Lezione
37
Autunno 2007
Problema
LABORATORIO
75
Autunno 2007
Modelli di I/O
LABORATORIO
76
Blocking
Nonblocking
I/O multiplexing
Guidato dai segnali
Asincrono
sincroni
38
Autunno 2007
Blocking I/O
LABORATORIO
77
applicazione
kernel
System call
Recvfrom
BLOCCATA
FASE 1:
attesa
datagram pronto
Copia datagram
FASE 2:
copia
Processo continua (elabora il
datagram)
Ritorna OK
Copia completata
Autunno 2007
Nonblocking I/O
LABORATORIO
78
applicazione
kernel
System call
Recvfrom
EWOULDBLOCK
Recvfrom
System call
FASE 1:
attesa
EWOULDBLOCK
System call
Recvfrom
datagram pronto
BLOCCATA
Copia datagram
FASE 2:
copia
Ritorna OK
Copia completata
39
Autunno 2007
I/O multiplexing
LABORATORIO
79
applicazione
kernel
System call
BLOCCATA
select
FASE 1:
attesa
Ritorna pronto
Recvfrom
datagram pronto
Copia datagram
BLOCCATA
System call
FASE 2:
copia
Ritorna OK
Copia completata
Autunno 2007
LABORATORIO
80
kernel
System call
signal
FASE 1:
attesa
SEGNALE
datagram pronto
System call
Copia datagram
BLOCCATA
GESTORE SEGNALE
Recvfrom
FASE 2:
copia
Ritorna OK
Copia completata
40
Autunno 2007
I/O asincrono
LABORATORIO
81
applicazione
kernel
System call
aio_read
FASE 1:
attesa
datagram pronto
Copia datagram
FASE 2:
copia
GESTORE SEGNALE
Processo continua (elabora il
datagram)
SEGNALE
Copia completata
Funzione select
Autunno 2007
LABORATORIO
82
#include <sys/select.h>
#include <sys/time.h>
int select(int maxfd, fd_set readset, fd_set writeset,
fd_set exceptionset, const struct timeval *timeout);
Valore di ritorno: -1 se errore, 0 se timeout, numero di descrittori pronti
41
Parametri select
Autunno 2007
LABORATORIO
83
Timeout
1. Puntatore nullo: aspetta senza timeout (fino a che un descrittore
pronto)
2. Struttura con un timeout non zero: aspetta fino al timeout, poi
ritorna anche se non ci sono descrittori pronti
Anche se possiamo specificare i microsecondi alcuni kernel
arrotondano a multipli di 10 microsecondi
Alcuni sistemi Linux modificano la struttura timeout (vale il tempo
rimanente al momento del ritorno)
Parametri select
Autunno 2007
LABORATORIO
84
42
Descrittori pronti
Autunno 2007
LABORATORIO
85
Descrittori pronti
Autunno 2007
LABORATORIO
86
Socket in scrittura
Il numero di byte di spazio disponibile nel buffer del
kernel maggiore di 2048
La soglia si pu cambiare con le opzioni dei socket
Loperazione di scrittura ritorna il numero di byte effettivamente
passati al livello di trasporto
C un errore
Loperazione di scrittura ritorner -1 e errno specificher lerrore
43
Autunno 2007
LABORATORIO
87
echocliechocli-slct.c
FD_ZERO(&rset);
for( ; ; ) {
FD_SET(fileno(fp), &rset);
FD_SET(sockfd, &rset);
maxfdl = MAX(fileno(fp), sockfd) + 1;
if( select(maxfdl, &rset, NULL, NULL, NULL) < 0 )
err_sys("select error");
if( FD_ISSET(sockfd, &rset) ) {
if ( (n = reti_readline(sockfd, recvline, MAXLINE)) < 0) {
if( errno == EPIPE ) {
err_msg(%s [%d]: server disconnesso, __FILE__,__LINE__);
break;
}
else
err_sys("readline error");
}
Autunno 2007
LABORATORIO
88
if (n == 0)
err_quit(%s [%d]: server disconnesso,__FILE__,__LINE__);
fputs(recvline, stdout);
}
if( FD_ISSET(fileno(fp), &rset) ) {
if( fgets(sendline, MAXLINE, fp) == NULL)
return;
if( (reti_writen(sockfd, sendline, strlen(sendline))) < 0)
err_sys("write error");
}
}
}
44
Autunno 2007
echoclient e select
LABORATORIO
89
Data o EOF
socket
TCP
RST
data
FIN
Autunno 2007
Stop-and-wait
LABORATORIO
90
Tempo 4
dati
echo
Tempo 1
Tempo 5
dati
echo
Tempo 2
Tempo 6
dati
echo
Tempo 3
Tempo 7
dati
S
C
echo
45
Autunno 2007
Batch input
LABORATORIO
91
Si spediscono le richieste
consecutivamente senza aspettare le
risposte, che arriveranno dopo
Tempo 0
Tempo 4
d1
Tempo 1
d2
d3
d4
d3
d2
r1
S
S
d6
d5
d4
r1
d3
r2
S
S
d6
r1
d5
r2
d4
r3
S
S
d7
r2
d6
r3
d5
r4
S
S
Tempo 6
d2
d1
d3
d2
Tempo 3
d4
Tempo 5
d1
Tempo 2
d5
d7
Tempo 7
d1
C
C
d8
r1
Autunno 2007
LABORATORIO
92
46
Autunno 2007
LABORATORIO
93
echocliechocli-shtd.c
FD_ZERO(&rset);
for( ; ; ) {
FD_SET(fileno(fp), &rset);
FD_SET(sockfd, &rset);
maxfdl = MAX(fileno(fp), sockfd) + 1;
if( select(maxfdl, &rset, NULL, NULL, NULL) < 0 )
err_sys("select error");
if( FD_ISSET(sockfd, &rset) ) {
if ( (n = reti_readline(sockfd, recvline, MAXLINE)) < 0) {
if( errno == EPIPE ) {
err_msg("%s [%d]: server disconnesso",__FILE__,__LINE__);
break;
}
else
err_sys("readline error");
}
Autunno 2007
LABORATORIO
94
if (n == 0) {
if( stdineof == 1 )
return;
else {
err_msg("%s [%d]: server disconnesso",__FILE__,__LINE__);
exit(exit(-1);
}
}
fputs(recvline, stdout);
}
if( FD_ISSET(fileno(fp), &rset) ) {
if( fgets(sendline, MAXLINE, fp) == NULL) {
stdineof = 1;
shutdown(sockfd, SHUT_WR);
FD_CLR(fileno(fp), &rset);
continue;
}
if( (reti_writen(sockfd, sendline, strlen(sendline))) < 0)
err_sys("write error");
}
}
}
47
Autunno 2007
LABORATORIO
95
-1
-1
rset
fd0
-1
fd1
fd2
fd3
fd4
fd5
-1
FD_SETSIZEFD_SETSIZE-1
Autunno 2007
LABORATORIO
96
rset
fd1
fd2
fd3
fd4
fd5
48
Autunno 2007
LABORATORIO
97
client
1
2
3
FD_SETSIZEFD_SETSIZE-1
4
-1
-1
fd0
rset
fd1
fd2
fd3
fd4
fd5
-1
Autunno 2007
LABORATORIO
98
client
1
2
3
FD_SETSIZEFD_SETSIZE-1
4
5
-1
fd0
rset
fd1
fd2
fd3
fd4
fd5
-1
49
Autunno 2007
LABORATORIO
99
1
2
3
-1
5
-1
fd0
rset
FD_SETSIZEFD_SETSIZE-1
fd1
fd2
fd3
fd4
fd5
-1
Autunno 2007
LABORATORIO
100
echosrvechosrv-slct.c
50
Autunno 2007
LABORATORIO
101
Autunno 2007
LABORATORIO
102
51
Autunno 2007
LABORATORIO
103
Autunno 2007
LABORATORIO
104
Possibili soluzioni
Usare un singolo processo per ogni client
Utilizzare un timeout sulle operazioni di I/O
Usare I/O non-blocking
52
Autunno 2007
Esercizi
LABORATORIO
105
Reti di Calcolatori
A.A. 2007-2008
Lezione
53
Socket options
Autunno 2007
LABORATORIO
107
Autunno 2007
Livelli
LABORATORIO
108
SOL_SOCKET
IPPROTO_IP
IPPROTO_IPV6
IPPROTO_ICMPV6
IPPROTO_TCP
livello socket
livello IP
livello IP per la versione 6
livello messaggi di controllo
livello TCP
54
Autunno 2007
Opzioni
Livello:
SOL_SOCKET
Livello:
IPPROTO_IP
Livello:
IPPROTO_TCP
LABORATORIO
109
SO_BROADCAST
SO_DEBUG
SO_DONTROUTE
SO_ERROR
SO_KEEPALIVE
SO_LINGER
SO_RCVBUF
SO_SNDBUF
SO_RCVLOWAT
SO_SNDLOWAT
SO_RCVTIMEO
SO_SNDTIMEO
SO_REUSEADDR
SO_REUSEPORT
SO_TYPE
SO_USELOOPBACK
permette il broadcast
abilita le informazioni di debug
salta il lookup nella tavola di routing
legge lerrore corrente
controlla che la connessione sia attiva
controlla la chiusura della connessione
grandezza del buffer in ricezione
grandezza buffer in spedizione
soglia per il buffer in ricezione
soglia per il buffer in spedizione
timeout per la ricezione
timeout per la spedizione
permette riutilizzo indirizzi locali
permette riutilizzo porte locali
il tipo di socket
per i socket di routing (copia i pacchetti)
IP_HDRINCL
IP_OPTIONS
IP_TTL
TCP_KEEPALIVE
TCP_MAXRT
TCP_MAXSEG
TCP_NODELAY
getsockopt e setsockopt
Autunno 2007
LABORATORIO
110
#include <sys/socket.h>
int getsockopt(int sd, int level, int name, void *value, socklen_t *len);
int setsockopt(int sd, int level, int name, void *value, socklen_t len);
Valore di ritorno: -1 se errore, 0 se OK
Parametri:
setsockopt(3,SOL_SOCKET,SO_KEEPALIVE,1,sizeof(int));
attiva lopzione di keepalive per mantenere la connessione attiva
void* flag;
socklen_t* size;
getsockopt(3,SOL_SOCKET,SO_KEEPALIVE,*flag,*size);
ritorna la grandezza di un intero in size e flag sar 0 se lopzione
disabilitata, oppure diverso da 0 se lopzione abilitata
55
SO_BROADCAST
Autunno 2007
LABORATORIO
111
SO_ERROR
Autunno 2007
LABORATORIO
112
56
Autunno 2007
SO_KEEPALIVE
LABORATORIO
113
Autunno 2007
SO_LINGER
LABORATORIO
114
/* 0=off, nonzero=on */
/* tempo attesa in secondi */
l_onoff = 0,
l_onoff 0, l_linger = 0
l_onoff 0, l_linger 0
57
SO_RCVBUF e SO_SNDBUF
Autunno 2007
LABORATORIO
115
SO_RCVLOWAT e SO_SNDLOWAT
Autunno 2007
LABORATORIO
116
58
SO_RCVTIMEO e SO_SNDTIMEO
Autunno 2007
LABORATORIO
117
/* secondi */
/* microsecondi */
SO_TYPE
Autunno 2007
LABORATORIO
118
Ci d il tipo di socket
SOCK_STREAM
SOCK_DGRAM
59
Opzioni di IPv4
Autunno 2007
LABORATORIO
119
IP_HDRINCL
Se settata per un raw socket di IP allora lapplicazione
deve costruire anche lIP header che normalmente
scritto dal kernel
IP_OPTIONS
Permette di inserire le opzioni dellIP header
IP_TTL
Permette di specificare il Time-To-Live (in hops) del
datagram
Il default 64
Opzioni di TCP
Autunno 2007
LABORATORIO
120
TCP_KEEPALIVE
Permette di moficare le 2 ore di attesa usate da SO_KEEPALIVE
TCP_MAXRT
-1, ritrasmetti per sempre
0, usa il default di sistema
n > 0, ritrasmetti per n secondi prima di abbandonare la
connessione
TCP_MAXSEG
Permette di modificare il valore dellMSS della connessione
TCP_NODELAY
Diabilita lalgoritmo di Nagle che diminuisce i dati spediti in caso di
congestione
60
Autunno 2007
LABORATORIO
121
sockoptssockopts-set.c
61