void sender3(void) { seq_nr next_frame_to_send; /* seq number of next outgoing frame */ frame s; /* scratch variable */ packet buffer; /* buffer for an outbound packet */ event_type event; next_frame_to_send = 0; /* initialize outbound sequence numbers */ from_network_layer(&buffer); /* fetch first packet */ while (true) { init_frame(&s); s.info = buffer; /* construct a frame for transmission */ s.seq = next_frame_to_send; /* insert sequence number in frame */ to_physical_layer(&s); /* send it on its way */ start_timer(s.seq); /* if answer takes too long, time out */ wait_for_event(&event); /* frame_arrival, cksum_err, timeout */ if (event == frame_arrival) { from_physical_layer(&s); /* get the acknowledgement */ if (s.ack == next_frame_to_send) { from_network_layer(&buffer); /* get the next one to send */ inc(next_frame_to_send); /* invert next_frame_to_send */ } } } }
void protocol6(void) { seq_nr ack_expected; /* lower edge of sender's window */ seq_nr next_frame_to_send; /* upper edge of sender's window + 1 */ seq_nr frame_expected; /* lower edge of receiver's window */ seq_nr too_far; /* upper edge of receiver's window + 1 */ int i; /* index into buffer pool */ frame r; /* scratch variable */ packet out_buf[NR_BUFS]; /* buffers for the outbound stream */ packet in_buf[NR_BUFS]; /* buffers for the inbound stream */ boolean arrived[NR_BUFS]; /* inbound bit map */ seq_nr nbuffered; /* how many output buffers currently used */ event_type event; enable_network_layer(); /* initialize */ ack_expected = 0; /* next ack expected on the inbound stream */ next_frame_to_send = 0; /* number of next outgoing frame */ frame_expected = 0; /* frame number expected */ too_far = NR_BUFS; /* receiver's upper window + 1 */ nbuffered = 0; /* initially no packets are buffered */ for (i = 0; i < NR_BUFS; i++) arrived[i] = false; while (true) { wait_for_event(&event); /* five possibilities: see event_type above */ switch(event) { case network_layer_ready: /* accept, save, and transmit a new frame */ nbuffered = nbuffered + 1; /* expand the window */ from_network_layer(&out_buf[next_frame_to_send % NR_BUFS]); /* fetch new packet */ send_frame(data, next_frame_to_send, frame_expected, out_buf); /* transmit the frame */ inc(next_frame_to_send); /* advance upper window edge */ break; case frame_arrival: /* a data or control frame has arrived */ from_physical_layer(&r); /* fetch incoming frame from physical layer */ if (r.kind == data) { /* An undamaged frame has arrived. */ if ((r.seq != frame_expected) && no_nak) send_frame(nak, 0, frame_expected, out_buf); else start_ack_timer(); if (between(frame_expected, r.seq, too_far) && (arrived[r.seq%NR_BUFS] == false)) { /* Frames may be accepted in any order. */ arrived[r.seq % NR_BUFS] = true; /* mark buffer as full */ in_buf[r.seq % NR_BUFS] = r.info; /* insert data into buffer */ while (arrived[frame_expected % NR_BUFS]) { /* Pass frames and advance window. */ to_network_layer(&in_buf[frame_expected % NR_BUFS]); no_nak = true; arrived[frame_expected % NR_BUFS] = false; inc(frame_expected); /* advance lower edge of receiver's window */ inc(too_far); /* advance upper edge of receiver's window */ start_ack_timer(); /* to see if (a separate ack is needed */ } } } if((r.kind==nak) && between(ack_expected,(r.ack+1)%(MAX_SEQ+1),next_frame_to_send)) send_frame(data, (r.ack+1) % (MAX_SEQ + 1), frame_expected, out_buf); while (between(ack_expected, r.ack, next_frame_to_send)) { nbuffered = nbuffered - 1; /* handle piggybacked ack */ stop_timer(ack_expected % NR_BUFS); /* frame arrived intact */ inc(ack_expected); /* advance lower edge of sender's window */ } break; case cksum_err: if (no_nak) send_frame(nak, 0, frame_expected, out_buf); break; /* damaged frame */ case timeout: send_frame(data, get_timedout_seqnr(), frame_expected, out_buf); break; /* we timed out */ case ack_timeout: send_frame(ack,0,frame_expected, out_buf); /* ack timer expired; send ack */ } if (nbuffered < NR_BUFS) enable_network_layer(); else disable_network_layer(); } }
main(int argc, char *argv[]) { int fd,n_carac,n,retardo,i; /*Para Tx */ int fin_f=0; FILE *arch; struct termios oldtio,newtio; packet paquete; frame trama,trama_r;// trama_r es de retransmision /*Para el autoamata */ TAutomat *automata = NULL; TEntity entidad1; TEntity *active_en = &entidad1; Argumentos argu1; Argumentos *argu= &argu1; int n_rtx;//numero de retransmisiones argu->paquete= &paquete; //con esto evito hacer un malloc /*Para la RX, es la se�l*/ struct sigaction saio; /* definicion de accion de segnal */ printf("abre archivo \n" ); /* Abre el dispositivo modem para lectura y escritura y no como controlador tty porque no queremos que nos mate si el ruido de la linea envia un CRTL-C Se debe usar O_NONBLOCK ????????? */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/); if (fd <0) {perror(MODEMDEVICE); exit(-1); } /***********SIGIO************************************************************************/ /* instala el manejador de segnal antes de hacer asincrono el dispositivo */ saio.sa_handler = signal_handler_IO; /* especifica la acci� que se va a asociar con SIGIO*/ saio.sa_flags = SA_NOMASK; /*especifica un cjto de opciones que modifican el comportamiento del proceso de manejo de se�l*/ saio.sa_restorer = NULL; /*es algo caduco ya no se usa*/ sigaction(SIGIO,&saio,NULL);/*sigaction, permite especificar explicitamente el comportamiento de los gestores de se�les el reiniciado de las llamadas del sistemaesta deshabilitado por defecto, pero puede activarse si se especica el flag de se�l SA RESTART*/ /*int fcntl(int fd, int ope, long arg); fcntl realiza una ope de control sobre el fichero refenciado por fd*/ /* permite al proceso recibir SIGIO */ fcntl(fd, F_SETOWN, getpid());/*F_SETOWN Establece el ID de proceso o el grupo de procesos que recibir�las se�les SIGIO para los eventos sobre el descriptor fd.*/ /* Hace el descriptor de archivo asincrono*/ fcntl(fd, F_SETFL, FASYNC); /*F_SETFL Asigna a las banderas de descriptor el valor asignado por FASYNC que se correspondan*/ /********FIN_SIGIO***************************************************************************/ tcgetattr(fd,&oldtio); /* Almacenamos la configuracion actual del puerto */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /* Ignore bytes with parity errors and make terminal raw and dumb. No hace falta ICRNL xk aki transmito, no recibo */ /***********************Debo usar ICRNL?????*/ newtio.c_iflag = IGNPAR /*| ICRNL*/; /* Raw output. */ newtio.c_oflag = 0; /* Don't echo characters because if you connect to a host it or your modem will echo characters for you. Don't generate signals. ********************************Se debe usar ICANON ????? */ newtio.c_lflag = ICANON;// 0; /* blocking read until 1 char arrives */ newtio.c_cc[VMIN]=1; newtio.c_cc[VTIME]=0; /* Ahora limpiamos la linea del modem y activamos la configuracion del puerto */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* terminal settings done, now handle output */ printf("abre archivo : %s \n",argv[3]); arch = fopen(argv[3],"r"); if (arch == NULL) {printf("Error al abrir el fichero \n"); exit(-1); } /* guardamos el numero de n*/ printf(" arch = %i \n", arch ); retardo= *argv[2]; retardo= retardo * 100000; n = atoi(argv[1]); printf(" n = %i \n", n); if (n>260){ perror("Lo siento sale del rango de SDU \n");exit(-1); } /*Guardo el n de retransmisiones*/ n_rtx =atoi(argv[4]); /*Guardo temporizador*/ argu->tempo =atoi(argv[5]); /*Inicalizo variables de estadisticas*/ argu->tr_perdidas =0; argu->tra_retx = 0; /* Define automata */ /*Se inicializa la matriz de mi automata */ automata = s1_automat_define( ); /*Empieza en el estado inicial */ entidad1.myCurrentState= STATE_INITIAL; printf(" ***************** Se ha creado el automata y se inicializa \n"); //printf("Estoy en el estado = %i ",argu->active_en->myCurrentState); /* ********************** */ /*Se envia primera trama*/ if ( (argu->trama_e = (frame *) malloc(sizeof(frame)) )== NULL) { perror("No hay suficiente espacio de memoria \n"); exit (-1); } argu->paquete->n = n; argu->n_rtx=n_rtx; /*Se le pasa el puerto*/ argu->fde = fd; /*argu.paquete.data== argu y paquete son pteros a struct */ memset(argu->paquete->data,'\0',sizeof(argu->paquete->data)); /*devuelve el nde caract leidos*de arch */ n_carac= from_network_layer (argu->paquete,arch); /*============================================================== /*=======================================================*/ /* */ argu->retardo = retardo; argu->sec_actual= 'A'; argu->sec_siguiente='B'; printf(" Empieza el retardo \n" ); //usleep(retardo); printf(" 1) el retardo1 es = %i \n", retardo ); //usleep(argu->retardo); printf(" 2) Retardo2 es = %i \n", argu->retardo ); argu->active_en=active_en; printf("Estoy en el estado = %i \n",argu->active_en->myCurrentState); printf(" Secuencia antes enviar %c\n", argu->trama_e->address); /* entidad , automata, evento, argumentos de evento */ automat_transit(argu->active_en,automata,EV_INI, argu); printf(" Secuencia despues de enviar %c \n", argu->trama_e->address); trama_r = trama; printf("Estoy en el estado = %i \n",argu->active_en->myCurrentState); printf(" va al bucle \n"); fin_f=feof(arch); while (feof(arch)==0) { printf("entra en el bucle \n"); /*se guarda el n de caracte que queremos leer*/ paquete.n = n; /*argu.paquete.data== argu y paquete son pteros a struct */ memset(argu->paquete->data,'\0',sizeof(argu->paquete->data)); /*devuelve el nde caract leidos*de arch */ n_carac= from_network_layer (argu->paquete,arch); // automat_transit(argu->active_en,automata,ACK, argu); /* ===========================================================================*/ //espero ACK recibe_ACK(argu, automata,fin_f); fin_f=feof(arch); //******************************************************* } //while recibe_ACK(argu, automata,fin_f); /* //Se envia la trama de finalizacion trama.data[0]='\0'; trama.control='T';//0x09; printf("Se envia la trama vacia %s: ,tam : %d \n",trama.data,strlen(trama.data)); to_physical_layer(&trama,fd); automat_transit(active_en,automata,ACK_0, argu); */ //usleep(retardo); usleep(100000); tcsetattr(fd,TCSANOW,&oldtio); /* restore old modem setings */ close(fd); fclose(arch); /*Se impirmen las estadisticas*/ printf(" ************************************************** \n"); printf(" (TX) Numero de Tramas Retransmitidas es : %i \n",argu->tra_retx); printf(" (TX/RX) Numero de Tramas Perdidas es : %i \n",argu->tr_perdidas); argu->active_en=active_en; free (argu->trama_e); automat_destroy( automata ); }