Exemple #1
0
void reliablyTransfer(char* hostname, unsigned short int hostUDPport, char* filename, unsigned long long int bytesToTransfer)
{

	//printf("%s %hu %s %llu\n",hostname ,hostUDPport,filename,bytesToTransfer);
	/*
		make a udp socket. reach the host and the destination port. waiting for receive ack. if ok, send part 2. otherwise nack send last part again.
	*/
	
	int socket_fd;
	//data
	struct addrinfo * dest;
	
	log_init(&data_to_send);
	
	
	if( (socket_fd = socket_init(hostname, hostUDPport, &dest)) < 0){
		return;
	}
	
	if( (Convert_File_To_List(&data_to_send , filename, bytesToTransfer)) < 0){
		return;
	}

	a = data_to_send.head;///////
	int rv = 1;
	//rv = slow_start(socket_fd, dest, &data_to_send);
	ack_r = calloc(total,sizeof(int));///
	
	while(data_to_send.head != NULL){
		//printf("timeout or dup or other?\n");
		switch(rv){
			case -1:{
				free(ack_r);
				freeaddrinfo(servinfo);
				return;
			}
			case 1:{
				rv = slow_start(socket_fd, dest, &data_to_send);
				break;
			}				
				//rv = slow_start(socket_fd, dest, &data_to_send);							
			//case 2:
			//	rv = slow_start(socket_fd, dest, &data_to_send);
			//	break;
			case 2:{
				//rv = slow_start(socket_fd, dest, &data_to_send);
				rv = congestion_avoidance(socket_fd, dest, &data_to_send);
				break;
			}
			//default:
			//	break;//rv = slow_start(socket_fd, dest, &data_to_send);
			
		}	
	}
	free(ack_r);
	freeaddrinfo(servinfo);
	/*
		after part 1, add the function of trafic control which includes increase window size and decrease window size. 
	*/
}
Exemple #2
0
void process_filename_request(){

  int n;

  n = recvfrom(socket_d,filename,20,0,(struct sockaddr *)&client,&length);

  if( n < 0 ){
    perror("Didn't get the filename!");
    exit(0);
  }else{
    printf("Reading the file:%s",filename);
  }


  int i;
  fp = fopen(filename,"r");

  if( fp == NULL ){
    perror("File does not exist!");
  }

  slow_start();

}
Exemple #3
0
void * rcvMessage(void * arg) {		// receive message in chat from thread
	int sock = (int)arg;			// client socket variable
	int seq_tmp = 0, data_tmp = 0;	// sequence number, data_size variable
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;
	FILE *fp;						// file transfer pointer variable
	int i = 0, j = 0, cnt = 0;		// normal variable(i = recv, j = for loop, cnt = acknowledge size
	while(1) {
		if((i = recv(sock, rcv_buf, sizeof(rcv_buf), 0)) > 0) {	// recv message(i = 1024)
			rcv_buf[i] = '\0';			// last message buffer, close array
			fflush(stdout);				// if buffer value exist, print it
			if(cnt > 0) {
				if(ack[cnt-1] > rwnd_size) {	// if rwnd is full, don't receive message
					sprintf(snd_buf, "oversize");
					send(sock, snd_buf, strlen(snd_buf), 0);
					continue;
				}
			}
			pthread_mutex_lock(&mutx);	// rcvCnt is public variable in stack. so using lock&unlock
			rcvCnt += 1;
			pthread_mutex_unlock(&mutx);
			if(!strncmp(rcv_buf, "file", 4)) {	// if recv message is 'file'
				printf("\n## Client wants file transport...\n");
				i = recv(sock, rcv_buf, sizeof(rcv_buf), 0);	// one more receive message
				rcv_buf[i] = '\0';
				fflush(stdout);
				if((fp = fopen(rcv_buf, "r")) == NULL) {	// and second message check
					printf("## File Not Found!!\n");
					sprintf(snd_buf, "failed");
					send(sock, snd_buf, strlen(snd_buf), 0);
					fp = NULL;
					continue;
				}
				else {									// if second message is correct file name,
					printf("## File Found!! Transporting ...\n");
					while(!feof(fp)) {
						fgets(rcv_buf,1024,fp);
						if(feof(fp))
							break;
						strcat(file_buffer,rcv_buf);	// file open and read each sentence, and append it 'file_buffer'
					}
					fclose(fp);
					sprintf(snd_buf, "success");
					send(sock, snd_buf, strlen(snd_buf), 0);	// signal "file transfer success"
					sleep(3);
					send(sock, file_buffer, strlen(file_buffer), 0);	// give to client file content
					sleep(3);
					printf("\n## Server >> File IO is finish. New client waiting...\n");
					printf("#####################################################\n");
					fp = NULL;
					continue;
				}
			}
			else if(!strncmp(rcv_buf, "flowStart", 9)) {	// if client message is 'flowStart'
				pthread_mutex_lock(&mutx);
				rcvCnt -= 1;				// it isn't seq-data & ack relation, so rcvCnt value - 1
				pthread_mutex_unlock(&mutx);
				printf("\n## Client wants flow control...\n");
				i = recv(sock, rcv_buf, sizeof(rcv_buf), 0);	// recv client size
				rcv_buf[i] = '\0';
				fflush(stdout);
				printf("## server's size is 102, client's size is %s.\n## starting flow control !!\n", rcv_buf);
				sleep(1);
				flow_start(rcv_buf, (void *)sock);
			}
			else if(!strncmp(rcv_buf, "cgstStart", 9)) {	// if client message is 'cgstStart'
				printf("\n## Client wants congestion control...\n");
				while(1) {
					i = slow_start((void *)sock);	// slow start !!
					if(i != 0) {		// i variable is number when cwnd >= ssthresh, break
						printf("\n## Slow Start Finished. Congestion Avoid Start..\n");
						while(1) {
							cgst_avoid((void *)sock);
							if(cgst_cnt >= 3)	// in cgst_avoid method, cgst_cnt value + 1 when 1/10 MSS * 10 times run
								break;
						}
						printf("\n## Congestion Avoid Finished. Recovery Start...\n");
						pthread_mutex_lock(&mutx);
						rcvCnt -= 1;
						cgst_cnt = 0;
						pthread_mutex_unlock(&mutx);
						while(1) {
							recovery((void *)sock);	// fast recovery run!!
							if(cgst_cnt >= 3)
								break;
						}
					}
					i = 0;
					if(cgst_cnt >= 3)
						break;
				}
			}
			else if(!strncmp(rcv_buf, "quit", 4)) {	// if receive message 'quit'
				pthread_mutex_lock(&mutx);
				clnt_number--;
				pthread_mutex_unlock(&mutx);
				printf("\n%s", rcv_buf);
				close(sock);		// client socket closed
			}
			else {
				j = MSS;		// give enough size to j value
				for(i = 0; i < strlen(rcv_buf); i++) {	// client send (abcdefasdcasd sequence number = XX data size = XX)
					if(!isdigit(rcv_buf[i]) && rcv_buf[i] == '=') {	// if not digit and correct = signal
						for(j = i+1; j < strlen(rcv_buf); j++) {	// give next to = size to j value
							if(!isdigit(rcv_buf[j]) && rcv_buf[j] == '=') {
								i = j+1;		// secondly correct = signal, give next to = size to i value, break
								break;
							}
							else if(isdigit(rcv_buf[j])) {	// after first = signal, sequence number save to seq_tmp variable
								seq_tmp *= 10;
								seq_tmp += (rcv_buf[j] - '0');
							}
						}
					}
					if(isdigit(rcv_buf[i]) && i > j) {		// after second = signal, data size save to data_tmp variable
						data_tmp *= 10;
						data_tmp += (rcv_buf[i] - '0');
					}
				}
				pthread_mutex_lock(&mutx);
				ack[cnt] = seq_tmp + data_tmp;	// acknowledge save(ack is public variable in stack)
				rwnd_tmp[cnt] = data_tmp;	// for increase rwnd threshold
				pthread_mutex_unlock(&mutx);
				cnt++;
				seq_tmp = 0;
				data_tmp = 0;
				printf("\n%s", rcv_buf);
			}
		}
	}
}
Exemple #4
0
void listen_for_ack(){

  int recv_check;
  //getting back the header
  int sequence_no;

  char temp_seqno[4];
  int acknow_no;
  char temp_ackno[4];
  char FLAG[1];
  char recv_data[1400];
  int recv_data_length;
  char temp_datalen[4];
  tv.tv_sec = 2;
  tv.tv_usec = 0;

  setsockopt(socket_d,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv));

  printf("\nListening for ACK's");


  while((recv_check = recvfrom(socket_d,recv_buffer,200,0,(struct sockaddr *)&client,&length)) > 0){

  strcpy(temp_seqno,strtok(recv_buffer,":"));
  strcpy(temp_ackno,strtok(NULL,":"));

  acknow_no = atoi(temp_ackno);
  ack_recv_array[k] = acknow_no;
  printf("\nACK RECEIVED ARRAY:%d",ack_recv_array[k]);
  k++;
  printf("\n--------------");
  printf("\nACKNOWLEDGMENT");
  printf("\n%d",acknow_no);
  //printf("\n%d\n%d:K:",acknow_no,k);
  strcpy(temp_datalen,strtok(NULL,":"));
  strcpy(FLAG,strtok(NULL,":"));
  printf("\nFLAG");
  printf("%s",FLAG);
  memset(recv_buffer,0,200);

}//end of while

  k=0;
  //once you get an ack traverse the expected ACK NUMBER ARRAY to see if it is present
  int j;
  int m;
  int p;

  //check if you have received the expected ACK's
  // if NO then retransmit and call listen_for_ack again
/**  for(j=0; j<4; j++){

    p =  expected_ack_array[j];
    if( ack_recv_array[j] ==  p){
      printf("j:%d",j);
      printf("Do i come here!");
      expected_ack_array[j] = '\0';
      ack_recv_array[j] = '\0';
    }
  }

  for(m=0;m<4;m++){
    if(expected_ack_array[m] != '\0'){
      p = expected_ack_array[m];
      printf("RETRANSMITTING!");
      retransmit_flag = true;
      retransmit(p);
    }
  }

  printf("RETRANSMITTING ENDS!");

  if(retransmit_flag){
    listen_for_ack();
  } else{**/
      //go back to slow_start if you have received all the ACK's
      slow_start();
  

}