Esempio n. 1
0
int Task2(int speed, int delay, char* filename)
{
    pkg myPackage;
    msg* haos;
    msg t, aux;

    long bdp, window;
    int fdIn, count;
    char infoBuffer[PKGSIZE]; /* buffer citire fisier */
    int i, packNum = 0, timeout;
    TLista bufferMesaje; /* buffer pachete */
    int k, res;

    /* setare varibaila timeout */
    if(2 * delay > 1000)
        timeout = 2 * delay;
    else timeout = 1000;

    bdp = speed * delay * 1000;

    window = bdp / (FRAMESIZE * 8);
    printf("[SENDER]Window = %ld frames\n", window);


    printf("[SENDER]Sender starts.\n");
    printf("[SENDER]Filename=%s, task_index=%d, speed=%d, delay=%d\n", filename, 2, speed, delay);

    /* deschidere fisier */
    fdIn = open(filename, O_RDONLY);
    if(fdIn < 0) {
        perror("File openning error.\n");
        return -1;
    }


    /* pachet initializare retea */
    memset(t.payload, 0, sizeof(t.payload));
    memset(myPackage.payload, 0, sizeof(myPackage.payload));

    myPackage.messageType = TYPE_INIT;
    myPackage.packNum = window;
    memcpy(myPackage.payload, filename, strlen(filename));
    memcpy(t.payload, &myPackage, sizeof(pkg));

    t.len = strlen(myPackage.payload) + 1;

    printf("[SENDER]Sending init message.\n");
    if(send_message(&t)  < 0) {
        fflush(stdin);
        perror("Error sending init message.\n");
        fflush(stdin);
        return -1;
    }

    /* retrimit pachetul pana ce sunt sigur ca si receiverul este initializat */
    while (recv_message_timeout(&aux, timeout) < 0) {
        fflush(stdin);
        printf("[SENDER] receive error\nWill attempt to resend.\n");
        fflush(stdin);
        send_message(&t);
    }
    printf("[SENDER] Got reply with payload: %s\n", t.payload);


    /* trimitere efectiva mesaje */
    window--;/* se vor trimite mesajele de la 0 la window - 1*/
    printf("-----Commence filereading.-----\n");
    count = read(fdIn, infoBuffer, PKGSIZE);
    while(count > 0) {
        /* pregatire pachet date */
        memset(t.payload, 0, sizeof(t.payload));
        memset(myPackage.payload, 0, sizeof(myPackage.payload));
        /* actualizare tip pachet + numar de ordine */
        myPackage.messageType = TYPE_INFO;
        myPackage.packNum = packNum++;
        if(count < PKGSIZE)
            myPackage.messageType = TYPE_END;
        memcpy(myPackage.payload, infoBuffer, count);
        memcpy(t.payload, &myPackage, sizeof(myPackage));
        printf("[SENDER]Message number %i has been sent.\n", myPackage.packNum);
        t.len = count + 1;

        /* creare duplicat mesaj pentru a il salva in buffer */
        haos = mesageDup(&t);
        send_message(&t);
        InsSfL(&bufferMesaje, haos);

        if(window == 0)
        {
            /* daca (N)ACK-ul este primit la timp */
            if(recv_message_timeout(&aux, timeout) > 0)
            {
                /* cat timp primim NACK-uri, retrimitem pachetele in cauza */
                while((*(pkg*)aux.payload).messageType == TYPE_NACK)
                {
                    /* daca s-a primit NACK pentru un pachet care inca nu a
                    fost trimis */
                    if(k >= packNum)
                        break;
                    /* retinem numarul de ordine al pachetului pentru care
                    s-a primit NACK*/
                    k = (*(pkg*)aux.payload).packNum;
                    printf("[SENDER]Message %i has been resent.\n", k);

                    /* retrimit pachetul */
                    res = send_message(getPackNum(&bufferMesaje, k));
                    if(res < 0) {
                        perror("RESEND error\n");
                        return -1;
                    }
                    recv_message_timeout(&aux, timeout);
                }

                /* elimin pachetul confirmat din buffer */
                printf("[SENDER]Eliminating package %i from queue.\n", (*(pkg*)aux.payload).packNum);
                if(ElimPackNum(&bufferMesaje,(*(pkg*)aux.payload).packNum) < 0)
                {
                    printf("[SENDER]Error eliminating package.\n");
                    return -1;
                }
            }

            /* Daca timeout-ul a fost atins, retrimitem tot ce avem in buffer*/
            else {
                printf("[SENDER]Timeout reached.\n");

                do {
                    printf("[SENDER]Attempting resend.\n");
                    for(i = 0; i < ListLength(&bufferMesaje); i++)
                    {
                        send_message(getindex(&bufferMesaje,i));
                    }
                } while(recv_message_timeout(&aux, timeout) < 0);

            }
        }
        else window--;
        count = read(fdIn, infoBuffer, PKGSIZE);
    }

    /* s-a incheiat citirea din fisier; trimitem un pachet final */
    printf("[SENDER]Filereading has ended. Last file is: %i\n", packNum);
    myPackage.messageType = TYPE_END;
    myPackage.packNum = packNum++;
    memcpy(t.payload, &myPackage, sizeof(myPackage));
    t.len = 0;
    haos = mesageDup(&t);
    send_message(&t);
    InsSfL(&bufferMesaje, haos);
    send_message(&t);

    /* asteptam sa primim confirmarea tuturor pachetelor trimise */
    /* NOTA: mod de operare similar cu ce avem mai sus */
    printf("[SENDER]Will attempt resend for all the messages left in the buffer.\n");
    while(ListLength(&bufferMesaje) >= 1)
    {
        /* daca (N)ACK-ul este primit la timp */
        if(recv_message_timeout(&aux, timeout) > 0)
        {
            /* cat timp primim NACK-uri, retrimitem pachetele aferente */
            while((*(pkg*)aux.payload).messageType != TYPE_ACK)
            {
                printf("[SENDER]Message %i has been resent.\n", k);
                k = (*(pkg*)aux.payload).packNum;

                if(k >= packNum)
                    break;

                res = send_message(getPackNum(&bufferMesaje, k));

                if(res < 0) {

                    AfisareL(&bufferMesaje);
                    printf("[SENDER]RESEND error.\n");
                    return -1;
                }
                recv_message_timeout(&aux, timeout);
            }
            /* cand am primit un ACK, eliminam pachetul respectiv din buffer*/
            printf("[SENDER]Eliminating package %i from queue.\n", (*(pkg*)aux.payload).packNum);
            if(ElimPackNum(&bufferMesaje,(*(pkg*)aux.payload).packNum) < 0)
            {
                /* eroare care nu afecteaza puternic activitatea programului,
                dar trebuie semnalata */
                printf("[SENDER]Error eliminating package.\n");
            }
        }

        else {
            printf("[SENDER]Timeout reached.\n");
        }
        /* daca a mai ramas doar mesajul de final, ne oprim */
        if(ListLength(&bufferMesaje) == 1)
            if( (*(pkg*)(bufferMesaje->info).payload).messageType == TYPE_END)
                break;
    }
    printf("[SENDER]Job done.\n");

    close(fdIn);
    return 0;
}
Esempio n. 2
0
int main(int argc, char *argv[])
{
	char *filename;
	int task_index, speed, delay, filesize;
	int i, fd, timeout, res, COUNT;
	int bdp, window, FRAME_SIZE;
	char read_buffer[MSGSIZE];
	struct stat f_status;

	task_index = atoi(argv[1]);
	filename = argv[2];
	speed = atoi(argv[3]);
	delay = atoi(argv[4]);
	
	printf("[SENDER] Sender starts.\n");
	printf("[SENDER] Filename=%s, task_index=%d, speed=%d, delay=%d\n", filename, task_index, speed, delay);

	/* miliseconds for delay & megabits for speed */
	bdp = speed * delay * 1000;
	printf("[SENDER] BDP = %d b(bits).\n", bdp);

	fd = open(filename, O_RDONLY);
	fstat(fd, &f_status);

	filesize = (int) f_status.st_size;
	printf("[SENDER] File size: %d\n", filesize);

	/* miliseconds for timeout */
	if(2*delay > 1000)
		timeout = 2*delay;
	else
		timeout = 1000;
	printf("[SENDER] timeout = %d\n", timeout);	

	init(HOST, PORT1);

	if(task_index == 0 || task_index == 1) {

		msg t;
		my_pkt p;
		int SCAN, bsize;
		queue *buffer;
		buffer = (queue *) malloc(sizeof(queue));
		create_queue(buffer, sizeof(msg));
		FRAME_SIZE = MSGSIZE + 4;

		printf("[SENDER] Each frame has %d B(bytes).\n", FRAME_SIZE);
		COUNT = filesize / FRAME_SIZE;
		printf("[SENDER] Gonna send %d frames.\n", COUNT);
		/* window = number of frames in the 'network', unacked */
		window = bdp / (FRAME_SIZE * BITS_NO);
		printf("[SENDER] window = %d frames\n", window);

		/* Len in message 
			= size(msg payload)
			= amount of data in the my_pkt structure
			= size(type) + data in (pkt payload)
			= sizeof(int) + number of used bytes in (pkt payload)
		*/

		/* Gonna send filename - SEQ = -2 message */
		memset(t.payload, 0, sizeof(t.payload));
		memset(p.payload, 0, sizeof(p.payload));
	
		p.SEQ = -2;	
		memcpy(p.payload, filename, strlen(filename));
		t.len = sizeof(int) + strlen(filename) + 1;
		memcpy(t.payload, &p, t.len); 
		while(1) {
			/* send msg */
			while(1) {
				res = send_message(&t);
				if (res < 0) {
					perror("[SENDER] Send error. Resending");
					continue;
				}
				break;
			}
			printf("[SENDER] Filename sent.\n");

			/* Wait for filename ACK */	
			if (recv_message_timeout(&t, timeout) < 0) {
				perror("[SENDER] Receive error: TIMEOUT. Resending");
				continue;
			}
			p = *((my_pkt *) t.payload);
			if (p.SEQ != -2) {
				perror("[SENDER] Receive error: WRONG ACK. Resending");
				continue;
			}
			printf("[SENDER] Got reply with ACK: %d (Filename)\n", p.SEQ);
			break;
		}

		/* Gonna send filesize - SEQ = -1 message */
		memset(t.payload, 0, sizeof(t.payload));
		memset(p.payload, 0, sizeof(p.payload));
	
		p.SEQ = -1;
		memcpy(p.payload, &filesize, sizeof(int));
		t.len = sizeof(int) * 2;
		memcpy(t.payload, &p, t.len);
		while(1) {
			/* send msg */
			while(1) {
				res = send_message(&t);
				if (res < 0) {
					perror("[SENDER] Send error. Resending");
					continue;
				}
				break;
			}
			printf("[SENDER] Filesize sent.\n");
	
			/* Wait for filesize ACK */	
			if (recv_message_timeout(&t, timeout) < 0) {
				perror("[SENDER] Receive error: TIMEOUT. Resending");
				continue;
			}
	
			p = *((my_pkt *) t.payload);
			if (p.SEQ != -1) {
				perror("[SENDER] Receive error: WRONG ACK. Resending");
				continue;
			}
			printf("[SENDER] Got reply with ACK: %d (Filesize)\n", p.SEQ);
			break;
		}

		/* Send file contents - (SEQ = 0 -> COUNT) messages */
		int seq = 0;
		/* Fill the link = send window messages */
		for (i = 0; i < window; i++) {
			if((SCAN = read(fd, read_buffer, MSGSIZE - sizeof(int))) > 0) {
				memset(t.payload, 0, sizeof(t.payload));
				memset(p.payload, 0, sizeof(p.payload));
	
				p.SEQ = seq;
				memcpy(p.payload, read_buffer, SCAN);
				t.len = sizeof(int) + SCAN;
				memcpy(t.payload, &p, t.len);
				printf("[SENDER] Sending message with SEQ: %d\n", seq);

				/* put msg in buffer */
				enqueue(buffer, &t);

				/* send msg */
				while(1) {
					res = send_message(&t);
					if (res < 0) {
						perror("[SENDER] Send error. Resending");
						continue;
					}
					break;
				}
				seq++;
			}
			else
				break;
		}

		/* From now on, ack clocking, i.e., a new ack will inform 
		   us about the space released in the link */
		while(1) {
			/* wait for ACK */
			if (recv_message_timeout(&t, timeout) < 0) {
				perror("[SENDER] Receive error: TIMEOUT. Resending buffer");
				bsize = buffer->size;
				while(bsize) {
					/* clear msg from buffer */
					dequeue(buffer, &t);

					/* send msg */
					while(1) {
						res = send_message(&t);
						if (res < 0) {
							perror("[SENDER] Send error. Resending");
							continue;
						}
						break;
					}

					/* reput msg in buffer, in case it will be lost again */
					enqueue(buffer, &t);
					bsize--;				
				}
				continue;
			}
			else {
				p = *((my_pkt *) t.payload);
				printf("[SENDER] Got reply with ACK: %d\n", p.SEQ);

				/* clear succesfully sent msg from buffer */
				dequeue(buffer, &t);

				if((SCAN = read(fd, read_buffer, MSGSIZE - sizeof(int))) > 0) {
					memset(t.payload, 0, sizeof(t.payload));
					memset(p.payload, 0, sizeof(p.payload));
		
					p.SEQ = seq;
					memcpy(p.payload, read_buffer, SCAN);
					t.len = sizeof(int) + SCAN;
					memcpy(t.payload, &p, t.len);
					printf("[SENDER] Sending message with SEQ: %d\n", seq);

					/* put msg in buffer */
					enqueue(buffer, &t);

					/* send msg */
					while(1) {
						res = send_message(&t);
						if (res < 0) {
							perror("[SENDER] Send error. Resending");
							continue;
						}
						break;
					}
					seq++;
				}
				else
					if(buffer->size == 0)
						break;
			}
		}

		destroy_queue(buffer);
		free(buffer);
	}
	
	printf("[SERVER] File transfer has ended.\n");

	close(fd);
	
	return 0;
}