void receiver(int socket, char *filename) { fd_set read, write; char readed[520]; int f; if(filename==NULL) f=STDOUT_FILENO; else f=open(filename,O_WRONLY|O_CREAT|O_TRUNC); while(1){ FD_ZERO(&read); FD_ZERO(&write); FD_SET(socket,&write); FD_SET(socket,&read); FD_SET(f,&write); if(select(socket+1,&read,&write, NULL,NULL)==-1) { fprintf(stderr,"Error selectreceiver\n"); return; } if(FD_ISSET(socket,&write) && FD_ISSET(socket,&read)) { printf("receiver readwritesocket\n"); int rd=readSocket(socket,readed,520); if(rd>=0) { pkt_t *pkt=pkt_new(); pkt_status_code errdec=pkt_decode((const char *)readed,(size_t)rd,pkt); printf("lu : %s\n",pkt_get_payload(pkt)); if(errdec==PKT_OK) { if(pkt_get_type(pkt)==PTYPE_DATA) { printf("On doit créer ACK/NACK\n"); } } else { fprintf(stderr,"Error receiver decode\n"); return; } pkt_del(pkt); printf("after del\n"); } } else if(FD_ISSET(f,&write)) { printf("Write file\n"); break; } } }
void getFile(const int sfd, char *filename, int out){ //Ouverture fichier pour ecriture int fichier; if(out) fichier= fileno(stdin); else{ fichier= open(filename, O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if(fichier==-1){ fprintf(stderr, "%s coudn't be opened.\n", filename); return; } } //Initialisations fd_set readfds,writefds; fcntl(sfd, F_SETFL, fcntl(sfd, F_GETFL, 0) | O_NONBLOCK); char *buffer; struct timeval timeout; timeout.tv_sec = 5; timeout.tv_usec = 0; pkt_t **stock; stock= malloc(sizeof(pkt_t)*WINSIZE); if(stock==NULL){ fprintf(stderr, "window allocation\n"); if(out!=1) close(fichier); return; } int k; for(k=0; k<=WINSIZE; k++) stock[k]= pkt_new(); uint8_t seq= 0, win= (uint8_t) WINSIZE-1; int ack= 0, err= 0, gotEof= 0; ssize_t bytes_read= 0; pkt_t *acquis; struct timeval rtt; struct timezone zone; while(1){ int ret= 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_SET(sfd, &readfds); FD_SET(sfd, &writefds); if((ret=select(sfd+1,&readfds,&writefds,NULL,&timeout))<0){ fprintf(stderr, "select()\n"); if(out!=1) close(fichier); return; } double tmp= getRtt(rtt); if(gotEof && win==WINSIZE-1 && tmp>MAXRTT) return; acquis= pkt_new(); //Socket vers fichier if(FD_ISSET(sfd,&readfds) && win>=0){ //Paquet recu buffer= malloc(sizeof(char)*BUFSIZE); if(buffer==NULL){ fprintf(stderr, "buffer allocation\n"); } bytes_read= read(sfd, (void *) buffer, BUFSIZE); if(bytes_read==0){ //Fin. si buffer encore rempli, attend d'avoir tout recu if(win==WINSIZE-1) return; gotEof= 1; } else if(bytes_read<0){ fprintf(stderr, "read(socket)\n"); } else{ pkt_t *paquet= pkt_new(); pkt_status_code state= pkt_decode(buffer, bytes_read, paquet); if(state!=PKT_OK){ //normalement decode contient le header si != E_NOHEADER fprintf(stderr, "corrupted packet\n"); if(bytes_read<=4 && state!=E_NOHEADER){ //Congestion //pkt_copy(acquis, paquet); acquis= paquet; acquis->type= PTYPE_NACK; acquis->window= win; ack= 2; } else //n'envoie rien pkt_del(paquet); } else{ if(paquet->length==0) gotEof= 1; if(paquet->seqnum==seq){ //bon paquet recu err= write(fichier, (void *) paquet->payload, paquet->length); if(err==-1){ fprintf(stderr, "write(fichier)\n"); return; } seq++; pkt_del(paquet); } else{ //stocke le paquet en attendant le bon stock[paquet->seqnum%WINSIZE]= paquet; win--; } ack= 1; } } free(buffer); } // vider le buffer contenant les paquets recus et ecrire le contenu dans un fichier SI le paquet a le bon numero de sequence int j, nomiss= 1; for(j=seq%WINSIZE; j<WINSIZE && nomiss; j= (j+1)%WINSIZE){ if(stock[j]->payload!=NULL){ err= write(fichier, (void *) stock[j]->payload, stock[j]->length); if(err==-1){ fprintf(stderr, "write(fichier)\n"); return; } fprintf(stderr, "\tn°%d ecrit.\n", stock[j]->seqnum); pkt_del(stock[j]); stock[j]= pkt_new(); seq++; win++; } else nomiss= 0; } //Confirmation vers Socket if(FD_ISSET(sfd,&writefds) && ack>0){ //Envoi acquis if(ack){ //acquis cumulatif acquis->type= PTYPE_ACK; acquis->window= win; acquis->seqnum= seq; } char *p; p= malloc(bytes_read*sizeof(char)); pkt_encode(acquis, p, (size_t *) &bytes_read); write(sfd, (void *) p, bytes_read); pkt_del(acquis); if(gotEof && win==WINSIZE-1) //dernier acquis à envoyer gettimeofday(&rtt,&zone); } ack= 0; waitFor(0); } if(out) close(fichier); return; }