next up previous
Next: About this document Up: CC51C Comunicación de Datos Previous: Pregunta 1

Pregunta 2

Este es el código de un emisor en Go-Back-N normal:

timeout = -1;
win_size = 0;
ExpectedAck = 0;
SeqN = 0;
for(;;)  {
    switch(Get_next_event(timeout))
      {
    case D_READY:
        size = FromUpperLayer(buf);
        <<Armo el paquete Data Link, con checksum y Header (incluye SeqN)>>
        <<Pongo el paquete en window[Last], con la hora actual>>
        Fwrite(window[Last].buf, window[Last].size);
        SeqN++;
        Last++;
        win_size++;
        if( win_size == WINDOW_SIZE )
            DisableUpperLayer();
        break;
    case F_TIMEOUT:
        for(i = First; i < Last; i++)
          {
           <<Pongo hora actual en el paquete>>
           Fwrite(window[i].buf, window[i].size);
          }
        break;
    case F_READY:
        Fread(Ackbuf, ACK_SIZE);
        if( Ackbuf[SEQN] == ExpectedAck )
          {
            win_size--;
            First++;
            ExpectedAck++;
            EnableUpperLayer();
          }
        break;
    }

    if( win_size > 0 ) timeout = window[First].time + TIMEOUT;
    else               timeout = -1;
  }

Adapte el código para que implemente timeouts adaptivos a la TCP, estimando RTT y desviación, con el algoritmo de Karn y con aumento exponencial del timeout. Supongo un timeout máximo de TIMEOUT ahora y un valor inicial de 3000 milisegundos.

/* Nuevo */
Timeout = 3000;
Rtt = 2000;
Mdev = 1000;

timeout = -1;
win_size = 0;
ExpectedAck = 0;
SeqN = 0;
for(;;)  {
    switch(Get_next_event(timeout))
      {
    case D_READY:
        size = FromUpperLayer(buf);
        <<Armo el paquete Data Link, con checksum y Header (incluye SeqN)>>
        <<Pongo el paquete en window[Last], con la hora actual>>
        window[Last].retransmit = FALSE;              /* Nuevo */
        Fwrite(window[Last].buf, window[Last].size);
        SeqN++;
        Last++;
        win_size++;
        if( win_size == WINDOW_SIZE )
            DisableUpperLayer();
        break;
    case F_TIMEOUT:
        for(i = First; i < Last; i++)
          {
           <<Pongo hora actual en el paquete>>
           window[i].retransmit = TRUE;               /* Nuevo */
           Fwrite(window[i].buf, window[i].size);
          }

    /* Nuevo */
        Timeout = Timeout * 2;
        if(Timeout > TIMEOUT) Timeout = TIMEOUT;

        break;
    case F_READY:
        Fread(Ackbuf, ACK_SIZE);
        if( Ackbuf[SEQN] == ExpectedAck )
          {
                /* Nuevo */
            if(!window[First].retransmit) {
                Rtt_sample = Time() - window[First].time;
                Diff = Rtt_sample - Rtt;
                Rtt = Rtt + alpha * Diff;
                Mdev = Mdev + alpha * (abs(Diff) - Mdev);
                Timeout = Rtt + Mdev;
            }
            win_size--;
            First++;
            ExpectedAck++;
            EnableUpperLayer();
          }
        break;
    }
    if( win_size > 0 ) timeout = window[First].time + Timeout;
    else               timeout = -1;
  }



José M. Piquer
Sun Jun 27 20:47:43 CLT 1999