GBN sembra risolvere i problemi che ci portiamo dietro da protocolli stop-and-wait. Tuttavia anche l'efficienza di GBN potrebbe essere migliorata. Se la larghezza della finestra del mittente è ampia, esso può spedire un elevato numero di pacchetti. Inoltre se la distanza tra gli host comunicanti è estesa c'è da aspettarsi un certo ritardo. Queste condizioni combinate possono portare all'invio di un elevato numero di pacchetti, che viaggiano su un lungo percorso. Se un solo pacchetto si perde o è corrotto, il mittente è costretto a ritrasmettere numerosi pacchetti.
Un protocollo a ripetizione selettiva evita la ritrasmissione di pacchetti che è inutile ritrasmettere, per esempio quei pacchetti che in GBN il ricevente rifiuta. Questa tecnica costringe il ricevente a inviare ACK per pacchetti specifici sia per quelli che giungono in ordine, sia per quelli che giungono fuori sequenza. Il mittente conserverà i pacchetti ricevuti in modo corretto in un buffer finché non sono stati ricevuti tutti i pacchetti con numero di sequenza inferiore.
In figura abbiamo:
send_base
, la base della finestra si muove verso il pacchetto che non ha ricevuto ACK con il più piccolo numero di sequenza (al prossimo pacchetto giallo in figura). Se la finestra si sposta e ci sono pacchetti non ancora trasmessi con numero di sequenza che rientra nella finestra, allora essi vengono trasmessi.[rcv_base, rcv_base + N - 1]
viene ricevuto correttamente, allora il pacchetto ricevuto ricade all'interno della finestra del ricevente e al mittente viene restituito un ACK selettivo. Se il pacchetto non era già stato ricevuto veniva salvato nel buffer del ricevente. Se presenta un numero di sequenza uguale alla base della finestra di ricezione (rcv_base
), allora questo pacchetto e tutti i pacchetti nel buffer vengono consegnati al livello superiore (partendo da rcv_base
). Si veda esempio alla fine di questa lista.[rcv_base - N, rcv_base - 1]
, ovvero se si riceve un pacchetto già ricevuto (verde in figura), allora si deve inviare un ACK anche se il pacchetto è già stato ricevuto.Il pacchetto di ACK viene inviato anche se è già stato ricevuto lo stesso pacchetto da parte del destinatario, perché le finestre del mittente e del ricevente potrebbero non essere allineate. Infatti il ricevente sa di aver ricevuto per la seconda volta lo stesso pacchetto, ma magari il mittente no.
La sincronizzazione delle finestre è fondamentale quando si ha a che fare con dei numeri di sequenza finiti, quando i numeri di sequenza sono saturi essi ricominciano da capo.
Immaginiamo il seguente scenario:
Dato che si possono riutilizzare i numeri di sequenza, si deve prestare attenzione alla duplicazione dei pacchetti. L'approccio utilizzato nella pratica è assicurarsi che prima di riutilizzare i numeri di sequenza ci si deve assicurare che il pacchetto non possa più essere in giro per la rete. Tale lasso di tempo nelle reti TCP ad alta velocità è stimato essere 3 minuti.