GBN consente al mittente di spedire quanti pacchetti vuole, con il limite però che il buffer non può superare una certa soglia di pacchetti per cui si attende gli ACK.
L’immagine sopra offre una descrizione della finestra del mittente che utilizza GBN.
base
: più piccolo numero di sequenza di un pacchetto inviato ma che non ha ricevuto ACKnextseqnum
: più piccolo numero di sequenza di un pacchetto che può essere inviato, ma che non è stato inviato (prossimo pacchetto da inviare)Si delineano 4 intervalli:
La finestra che va da [base, N - 1] scorre lungo i numeri di sequenza.
N viene detta ampiezza della finestra.
GBN viene detto protocollo a finestra scorrevole.
In pratica, il numero di sequenza di un pacchetto, viene scritto in un campo a dimensione fissa dell'intestazione del pacchetto. Detto
La finestra è limitata per consentire il servizio del controllo della congestione (che verrà affrontato più avanti).
Presentiamo di seguito la macchina a stati finiti di GBN che risulta essere una estensione della macchina del mittente.
base = 1
e nextseqnum = 1
.rdt_send(data)
, qui GBN controlla che nextseqnum
(il numero di sequenza del pacchetto da inviare) sia inferiore a base + N
(dove N è la dimensione della finestra), in tal caso il pacchetto con numero nextseqnum
viene creato (make_pkt(...)
) e inviato. Dopo aver inviato il pacchetto viene fatto un altro controllo if(base == nextseqnum)
, ovvero si controlla se il pacchetto appena inviato è il primo pacchetto per cui non è stato ricevuto ACK, in tal caso si fa partire il timer e si incrementa il numero di sequenza (prossimo pacchetto). Nel caso in cui il pacchetto da inviare è maggiore della dimensione della finestra (la finestra è piena), il pacchetto viene rifiutato (refuse_data()
), cioè non viene inviato.base
a nextseqnum
devono essere ritrasmessi.base
diventa quello del pacchetto di ACK appena ricevuto incrementato di 1, ovvero grazie a questo ACK con un certo numero di sequenza, sappiamo che il pacchetto relativo a questo ACK e quelli numero di sequenza inferiore, sono arrivati correttamente, per cui adesso si attendono gli ACK per i pacchetti successivi al numero di sequenza dell'ACK appena ricevuto: base = getacknum(rcvpkt) + 1
. Poi si controlla se base == nextseqnum
, ovvero se l'ACK appena ricevuto corrisponde con l'ultimo pacchetto inviato, se è vero, il timer può fermarsi, poiché il mittente ha ricevuto ACK per tutti i pacchetti inviati, se è falso, vuol dire che il mittente deve resettare il timer e continuare a trasmettere pacchetti.base
a nextseqnum - 1
.Per comprendere meglio:
base = 1
nextseqnum = 1
, base == nextseqnum
, avvio del timer, nextseqnum + 1
e spedizione del pacchettobase = 1
(perché non è ancora arrivato l'ACK relativo a base = 1
(non sono ancora arrivati gli ACK per expectedseqnum = 1
rdt_rcv(rcv_pkt) && notcorrupt(rcvpkt) && hasseqnum(rcvpkt, expectedseqnum
) allora vengono estratti i dati e consegnati al livello superiore, dopo si invia l'ACK e si incrementa la variabile expecetedseqnum
.Notiamo che, trattandosi di pacchetti consegnati uno per volta, se il pacchetto
La figura sopra mostra come lavora GBN con una finestra di 4 pacchetti.
A causa di questo limite il mittente invia i pacchetti da 0 a 3, dopo di che deve attendere conferma per uno di questi 4 pacchetti inviati. Quando giungono gli ACK0 e ACK1, la finestra scorre in avanti e può trasmettere due nuovi pacchetti (4 e 5).
Lato ricevente il pacchetto 2 viene perso, dunque i pacchetti 3 e 4, giungono in un ordine inaspettato per il ricevente, che prontamente li rifiuta.