Example #1
0
/* Transmit the file using Selective Repeat protocol
 ****************************************************
 */
void transmit(char* filename, int speed, int delay, double loss,
            double corrupt) {

    /* Compute window size */
    int window_sz = (int) ( (double) ( ( (double)(speed * delay) / 8) \
                        * (1 << 20)  ) / (1000 * 1408) + 1 );

    /* Attempt to get stats of the file */
    struct stat buf;
    if ( stat(filename, &buf) < 0 ) {
        perror("Stat failed");
        return;
    }

    /* Open the file */
    int file = open(filename, O_RDONLY);

    if (file < 0) {
        perror("Couldn't open file");
        return;
    }

    charge t, *ok = NULL;;
    memset(&t, 0, sizeof(charge));
    int not_sent = 1;

    /* Type 1: Handshake message; filename + filesize */
    t.msg.type = 1;
    sprintf(t.pack.load, "%s\n%d\n", filename, (int) buf.st_size);
    t.msg.len = strlen(t.pack.load) + 1;

    t.pack.id = (unsigned int) window_sz;   /* window size in place of id */

    /* Compute CRC of the handshake message */
    compcrc(t.crc.payload, CRC_LOAD_SZ, &t.crc.crc);

    /* Make sure the first frame containing filename and its size is recieved */
    while (not_sent) {
        send_message((msg *)&t);
        fprintf(stderr, "Handshake message attempted\n");
        ok = (charge *)receive_message_timeout(delay * 2 + 20);

        if(!ok) {
            fprintf(stderr, "Handshake message receive failure\n");
            continue;
        }

        if (ok->msg.type == 1000 && ok->crc.crc == t.crc.crc)
            not_sent = 0;

        free(ok);
    }

    /* Get window size from reciever */
    charge *win_rec = NULL;
    win_rec = (charge *)receive_message();
    if (!win_rec) {
        fprintf(stderr, "Window size not recieved\n");
    }

    if (win_rec->msg.type != 2000)
        fprintf(stderr, "Error, window size from reciever expected\n");

    /* Reciever's window size */
    const int win_recv = win_rec->pack.id;
    free(win_rec);

    /* Recompute the window size */
    if (win_recv != 0 && window_sz > win_recv)
        window_sz = win_recv;

    if (window_sz < 10)
        window_sz = 10;

    /* Transmit the content of the file
     **********************************
     */
    unsigned int seq = 0;
    unsigned int front = 0, count = 0;
    charge *buff = (charge *) calloc(window_sz, sizeof(charge));
    charge tr, *rr;
    memset(&tr, 0, sizeof(charge));
    int flen = (int) buf.st_size;

    /* While there are ACKs to wait */
    while (flen) {
        if ( (tr.msg.len = read(file, &tr.pack.load, PCK_LOAD_SZ) ) > 0 ) {
            tr.msg.type = 2;    /* Data */
            tr.pack.id = seq;
            compcrc(tr.crc.payload, CRC_LOAD_SZ, &tr.crc.crc);

            /* Send message and push it into the queue */
            send_message((msg *) &tr);
            push(buff, tr, front, &count, window_sz);

            seq++;

            if ( count < window_sz && tr.msg.len == PCK_LOAD_SZ ) {
                memset(&tr, 0, sizeof(charge));
                continue;   /* Fulfill buffer */
            }

        }

        read:
        /* Read ACK or NAK */
        rr = NULL;
        rr = (charge *)receive_message_timeout(delay * 2 + 20);
        charge nkd, ackd;


        if (rr != NULL)
            switch (rr->pack.type) {
            /* Case for NAK */
            case 4:
                t_out:
                /* Timeout situations are handled here too */
                nkd = pop(buff, &front, &count, window_sz);
                send_message((msg *) &nkd);
                push(buff, nkd, front, &count, window_sz);

                free(rr);
                goto read;
                break;

            /* Case for ACK */
            case 3:
                ackd = pop(buff, &front, &count, window_sz);

                while ( ackd.pack.id != rr->pack.id ) {
                    send_message((msg *) &ackd);
                    push(buff, ackd, front, &count, window_sz);

                    ackd = pop(buff, &front, &count, window_sz);
                }

                flen -= ackd.pack.len;
                free(rr);
                break;

            default:
                break;
            }
            else
                goto t_out;
    }

    close(file);
    free(buff);
}
Example #2
0
int main(int argc, char** argv){
	init(HOST,PORT);
	msg m1, *m2;
	frame f;
	
	//fisierul de log
	FILE* log_file;
	log_file = fopen ("log.txt","w");
	fclose(log_file);
	
	// fisierul de intrare	
	int in = open(argv[1], O_RDONLY);
	lseek(in, 0, SEEK_SET);
	
	struct stat s;
	fstat (in, &s);
	int file_size = (int) s.st_size;
	
	unsigned char checksum;
	int got_correct_ack = 1;
	int size;
	unsigned char nr_frame = 0;
	char str[80];
	
	while (file_size != 0)
	{
		log_file = fopen ("log.txt","a");
		
		// daca s-a primit ACK corect se intra pe aceasta ramura
		if (got_correct_ack)
		{
			// se trimite marimea fisierului de intrare, am considerat acest 
			// mesaj ca fiind un caz separat  
			if (nr_frame == 0)
			{
				m1.len = sizeof(int);
				f.payload = malloc(sizeof(int));
				memcpy(&m1.data[0], &nr_frame, 1);
				sprintf(&m1.data[1],"%d", file_size);
				sprintf((char*)f.payload,"%d", file_size);
				checksum = get_checksum(m1);
				memcpy(&m1.data[5], &checksum, 1);
				send_message(&m1);
				
				char to_binary[9];
				strcpy(to_binary, byte_to_binary(checksum));
				fprintf (log_file, "%s", currentDateTime(str));
				fprintf(log_file, "[%s] Am trimis pachetul cu:\n\tSeq no:" 
						"%d\n\tPayload: %s\n\tChecksum: %s\n", argv[0], 0, 
						f.payload, to_binary); 
				fprintf(log_file,"------------------------------------------"
					"-----------------------------------------------------\n");
			}
			// daca a fost trimisa marimea fisierului atunci se intra numai pe 
			// aceasta ramura
			else
			{
				int payload_size = (rand() % (60 + 1 - 1)) + 1;
				if (file_size <= payload_size)
				{
					payload_size = file_size;
					f.payload = malloc(payload_size);
					read(in, f.payload, file_size);
				}
				else
				{
					f.payload = malloc(payload_size);
					read(in, f.payload, payload_size);
				}
				
				m1.len = payload_size;
				size = m1.len;
				memcpy(&m1.data[0], &nr_frame, 1);
				memcpy (&m1.data[1], &f.payload[0], payload_size);
				checksum = get_checksum(m1);
				memcpy(&m1.data[1 + payload_size], &checksum, 1);
				send_message(&m1);
				
				char to_binary[9];
				strcpy(to_binary, byte_to_binary(checksum));
				fprintf (log_file, "%s", currentDateTime(str));
				fprintf(log_file, "[%s] Am trimis pachetul cu:\n\tSeq no:" 
						"%d\n\tPayload: %s\n\tChecksum: %s\n", argv[0], 
						nr_frame, f.payload, to_binary); 
				fprintf(log_file,"------------------------------------------"
					"-----------------------------------------------------\n");
			}
		}
		
		// daca nu s-a primit ACK corect se retrimite ultimul pachet
		else
		{
			send_message(&m1);
		}
		
		// verific daca s-a primit timeout
		if ((m2 = receive_message_timeout(50)) == NULL)
		{
			got_correct_ack = 0;
			fprintf (log_file, "%s", currentDateTime(str));
			fprintf(log_file, "[%s] Am primit timeout, retrimit pachetul" 
				"cu no_seq: %d\n", argv[0], nr_frame); 
			fprintf(log_file,"------------------------------------------"
					"-----------------------------------------------------\n");
			fflush(log_file);

		}
		// daca nu s-a primit timeout verific daca s-a primit ACK corect
		else 
		{
			memcpy(&f.no_seq, m2->data, 1);
			memcpy(&f.checksum, m2->data + 1, 1);
			if (f.no_seq == f.checksum)
			{
				fprintf (log_file, "%s", currentDateTime(str));
				fprintf(log_file, "[%s] Am primit ACK corect pentru " 
						"pachetul cu no_seq: %d, trimit urmatorul pachet\n", 
						argv[0], nr_frame); 
				fprintf(log_file,"------------------------------------------"
					"-----------------------------------------------------\n");
				fclose(log_file);
				got_correct_ack = 1;
				file_size -= size;
				nr_frame ++;
				free(f.payload);
			}
			else
			{
				fprintf (log_file, "%s", currentDateTime(str));
				fprintf(log_file, "[%s] Am primit ACK gresit, retrimit " 
						"pachetul cu no_seq: %d", argv[0], nr_frame); 
				fprintf(log_file,"------------------------------------------"
					"-----------------------------------------------------\n");
				fclose(log_file);
				got_correct_ack = 0;
			}
		}
	}
	
	log_file = fopen ("log.txt","a");
	fprintf (log_file, "%s", currentDateTime(str));
	fprintf(log_file, "[%s] Am trimis tot fisierul %s\n", argv[0], argv[1]); 
	fclose(log_file);
	return 0;
}
Example #3
0
/*
=======================================================
  metoda trimite mesaje de confirmare/neconfirmare 
  inapoi catre sender pentru toate pachetele primite
========================================================
*/
void send_data(unsigned short int BUF)
{
  unsigned short int new_seq = 0, far = BUF;
	int i;
  msg *buffer=calloc(1000,sizeof(msg));
	int *arrived_messages=calloc(BUF,sizeof(int));
	unsigned short int crc;
	unsigned short payload_crc;
	/*cat timp nu am primit intreg continutul fisierului*/
	for (;size > 0;)
  	{
  	  /*primesc mesaj de la sender*/
			r = receive_message_timeout( delay);
			if (r != NULL) 
			{
			    /*daca nu este mesaj de tip 2 (de date) trimit nak*/
			    if (r->type != DATA) 
					{			
							msg m = message((new_seq + MAX_SEQ) % (MAX_SEQ + 1),"NAK");
							send_message(&m);
					
			    }
				 	else
					 {
					    /*altfel verfici dac numarul de secventa se incadreaza in fereastra curenta
					      si daca bufferul este liber pe acea pozitie
					    */
							memcpy(&next_seq, r->payload + 2, 2);
							if (between(new_seq, next_seq, far))
							if(arrived_messages[next_seq % BUF] == 0)
							{
							  /*calculez crc-ul*/
								crc = calc_crc(r, crc_table);
					    	memcpy(&payload_crc, r->payload, 2);
					    	/*daca am primit un mesaj nedeteriorat*/
						    if ((payload_crc == crc)) 
								{
								    /*marchez bufferul ca fiind ocupat pe acea pozitie*/
										arrived_messages[next_seq % BUF] = 1;
								    buffer[next_seq % BUF] = *r;
										while (arrived_messages[new_seq % BUF])
										{
										size =size- buffer[new_seq % BUF].len;							
								    arrived_messages[new_seq % BUF] = 0;
								    /*scriu datele in fisier*/
								    write(fd, buffer[new_seq % BUF].payload + 4,buffer[new_seq % BUF].len);
								    /*deplasez fereastra*/
			    					increment(&new_seq, MAX_SEQ);
			    					increment(&far, MAX_SEQ);
											}
                /*trimit mesaj de confirmare*/
								msg m = message((new_seq + MAX_SEQ) % (MAX_SEQ + 1),"ACK");
								send_message(&m);
								if (size == 0) break;

			    		} 
							else 
							{
							  /*mesaj corupt*/
								msg m = message((new_seq + MAX_SEQ) % (MAX_SEQ + 1),"NAK");
								send_message(&m);
					    }
					} 
					else 
					{
					  /* nu se incadreaza in limitele ferestrei*/
						msg m = message((new_seq + MAX_SEQ) % (MAX_SEQ + 1),"NAK");
						send_message(&m);
					}
	    }
	}
	 else
	 {	/*am primit mesaj gol*/			
			msg m = message((new_seq + MAX_SEQ) % (MAX_SEQ + 1),"NAK");
			send_message(&m);

	}

}

}
Example #4
0
int main(int argc,char** argv){
	init(HOST,PORT);
	msg t, *r;
	char nr_secv_sender = 0;
  	
	FILE *fd = fopen("date_intrare", "r");	
	
	//variabile folosite pentru a scrie data si ora in fisierul log.txt;    
	time_t timp = time(NULL);
	struct tm timp_str = *(localtime(&timp));

	//alegem o dimensiune de pachet aleatoare, care imi intoarca un numar intre 1 si 60;
	int rnd = rand() % 61;
	
	//cat timp mai citesc din fisier;
	while(fgets(t.payload, rnd, fd) != NULL){
		//pun textul in payload;
		t.len = strlen(t.payload);
		//calculez CheckSum
		char CheckSum = getXor(t.payload);	
		
		//printez data, ora, numarul secventei, payloadul si CheckSumul cadrului trimis;		
		printf("[sender] %d-%02d-", timp_str.tm_year + 1900, timp_str.tm_mon + 1);
		printf("%d %2d:%2d:%02d\n", timp_str.tm_mday, timp_str.tm_hour, timp_str.tm_min, timp_str.tm_sec);
		printf("Am trimis urmatorul pachet:\n");
		printf("Seq_No: %d\n", nr_secv_sender);
		printf("Payload: %s\n", t.payload);
		printf("CheckSum: %s\n", toBin(CheckSum));
		printf("--------------------------------------------------------------------\n");
		
		//pun paritatea pe penultima pozitie
		t.payload[t.len + 2] = CheckSum;
		//pun seq_nr pe ultima pozitie
		t.payload[t.len + 3] = nr_secv_sender;

		//trimit mesajul
		send_message(&t);

		//resetez dimensiunea pachetului de trimis  	
		rnd = rand() % 61;

		//primesc ack; setez valoarea de timeout la 200 ms
		r = receive_message_timeout(200);
		
		//cat timp nu am trimis pachetul in timp util;
		while(r == NULL){
			//printez data, ora, numarul secventei, payloadul si CheckSumul cadrului trimis;	
			printf("[sender] %d-%02d-", timp_str.tm_year + 1900, timp_str.tm_mon + 1);
			printf("%d %2d:%2d:%02d\n", timp_str.tm_mday, timp_str.tm_hour, timp_str.tm_min, timp_str.tm_sec);
			printf("Am trimis urmatorul pachet:\n");
			printf("Seq_No: %d\n", nr_secv_sender);
			printf("Payload: %s\n", t.payload);
			printf("CheckSum: %s\n", toBin(CheckSum));
			printf("--------------------------------------------------------------------\n");
			send_message(&t);
			r = receive_message_timeout(200);
		}	
		
		char nr_secv_receiver = r->payload[0];
		
		//cat timp primesc ack pentru acelasi pachet, il retrimit
		//si reprimesc ack pentru a ma asigura ca a fost trimis bine
		while(nr_secv_receiver == nr_secv_sender || r == NULL){
			//printez data, ora, numarul secventei, payloadul si CheckSumul cadrului trimis;
			printf("[sender] %d-%02d-", timp_str.tm_year + 1900, timp_str.tm_mon + 1);
			printf("%d %2d:%2d:%02d\n", timp_str.tm_mday, timp_str.tm_hour, timp_str.tm_min, timp_str.tm_sec);
			printf("Am trimis urmatorul pachet:\n");
			printf("Seq_No: %d\n", nr_secv_sender);
			printf("Payload: %s\n", t.payload);
			printf("CheckSum: %s\n", toBin(CheckSum));
			printf("--------------------------------------------------------------------\n");
			send_message(&t);
			r = receive_message_timeout(200);
			nr_secv_receiver = r->payload[0];
		}
		//incrementez numarul secventei;
		nr_secv_sender++;
	}

	return 0;
}
Example #5
0
/*
=======================================================================
  trimit primul frame
=======================================================================
*/
void send_first_frame(int window)
{
	unsigned short int crc;
	unsigned short payload_crc;
	for(;;)
		{
			r = receive_message_timeout(2*delay);
			if (r != NULL)
			 {
			    /*daca a sosot un mesaj care nu este de tipul FIRSt trimit NAK */
			    if (r->type != FIRST) 
					{
						msg m=message(FIRST_FRAME,"NAK");
						send_message(&m);

			    }
				 else
					{
			      /*calculez crc-ul si verfic daca mesajul este sau nu deteriorat*/
						crc = calc_crc(r, crc_table);
    				memcpy(&payload_crc, r->payload, 2);
						if ((payload_crc == crc)) 
						{
						      int len=r->len;
						      /*determin valorile pentru 
						        - delay
                    - numele fisierului 
                    - MAX_SEQ 
                    - dimensiunea fisierului*/
							    memcpy(&delay, r->payload + len + 8, 4);
							    memcpy(filename, r->payload + 4, len);
							    memcpy(&MAX_SEQ, r->payload + 2, 2);
							    memcpy(&size, r->payload + len + 4, 4);
							    /* 
							      determin minminimul dintre valoarea parametrului window si dimensiunea ferestrei senderului
							     */
							     int min ;
									if(window != 0) min= ((MAX_SEQ+1)/2>window)?window:(MAX_SEQ+1)/2;
									if(window!=0)MAX_SEQ =min *2 - 1; 
							    send_ack2(FIRST_FRAME, crc_table, MAX_SEQ);
							    break;
						} 
						else
						 {
						      /*daca mesajul este corupt trimit nak*/
									msg m=message(FIRST_FRAME,"NAK");
									send_message(&m);

		
					}
	    		}
			}	
			else
			{ 
  			  /*daca am primt un mesaj gol trimit nak*/
					msg m=message(FIRST_FRAME,"NAK");
					send_message(&m);
			}
    }

}