Beispiel #1
0
int			check_notif(t_serv *udp_serv)
{
	int		n = 0;
	udp_serv->len = sizeof(udp_serv->cliaddr);
	n = timeout_recvfrom(udp_serv->sockfd, udp_serv->mesg, 1000, (struct sockaddr_in *)&udp_serv->cliaddr, 0, &udp_serv->len);
	if (n)
		return (1);
	return (0);

}
Beispiel #2
0
int main(int argc, char *argv[]) {
	int packet_size = sizeof(packet);
	int nbytes;
	int remote_len;
	struct timespec cur_time;
	// buffer
	packet packet_buffer[MAXPCKTBUFSIZE];	
	// ACK ack_buffer[MAXPCKTBUFSIZE];
	char log_line[1024];
	char tmpstr[256];
	time_t tmptime;
	int resend_cnt[MAXPCKTBUFSIZE];
	memset(resend_cnt, 0, sizeof(resend_cnt));

	/* check command line args. */
	if(argc<7)
	{
		printf("usage : %s <server_ip> <server_port> <error rate> <random seed> <send_file> <send_log> \n", argv[0]);
		exit(1);
	}
	

	/* Note: you must initialize the network library first before calling sendto_().  The arguments are the <errorrate> and <random seed> */
	init_net_lib(atof(argv[3]), atoi(argv[4]));
	printf("error rate : %f\n",atof(argv[3]));

	/* socket creation */
	int sd;
	if((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		printf("%s: cannot create socket \n",argv[0]);
		exit(1);
	}

	/* get server IP address (input must be IP address, not DNS name) */
	struct sockaddr_in remoteServAddr;
	bzero(&remoteServAddr, sizeof(remoteServAddr));               //zero the struct
	remoteServAddr.sin_family = AF_INET;                 //address family
	remoteServAddr.sin_port = htons(atoi(argv[2]));      //sets port to network byte order
	remoteServAddr.sin_addr.s_addr = inet_addr(argv[1]); //sets remote IP address
	printf("%s: sending data to '%s:%s' \n", argv[0], argv[1], argv[2]);
	remote_len = sizeof(remoteServAddr);

	/* Open log */
	FILE * sendlog = fopen(argv[6], "w");
	/* Open file to send */
	FILE * sendfile = fopen(argv[5], "rb");
	if (sendfile)
	{	
		// determine file size
		int fsize;
		char fsizechar[32];
		fseek(sendfile, 0, SEEK_END); // seek to end of file
		fsize = ftell(sendfile); // get current file pointer
		fseek(sendfile, 0, SEEK_SET); // seek back to beginning of file
		sprintf(fsizechar, "%d", fsize);
		printf("file size %s \n", fsizechar);

		// send file size & hand shake
		char msg[1024];
		ACK tmpack;
		strcpy(msg, argv[5]);
		strcat(msg, "\t");
		strcat(msg, fsizechar);
		nbytes = sendto(sd, msg, sizeof(msg), 0, (struct sockaddr*)&remoteServAddr, remote_len);
		// get ack
		nbytes = timeout_recvfrom(sd, &tmpack, sizeof(ACK), (struct sockaddr*)&remoteServAddr);  	
		SWS = tmpack.rws;
		// resend when timed out
		while (!nbytes)
		{
			nbytes = sendto(sd, msg, sizeof(msg), 0, (struct sockaddr*)&remoteServAddr, remote_len);
			// get ack
			nbytes = timeout_recvfrom(sd, &tmpack, sizeof(ACK), (struct sockaddr*)&remoteServAddr);
			// update SWS
			SWS = tmpack.rws;
		}
		
		int seq = 0;
		int buf_index = seq % MAXDATABUFSIZE;
		int remain = fsize;
		int total = fsize / MAXDATABUFSIZE;
		if (fsize % MAXDATABUFSIZE) total += 1;
		int readed, toread;
		LAR = -1; 
		LFS = -1;
		int last_frame_cnt = 0;
		while(LAR < total-1)
		{
			if (LFS < LAR + SWS)
			{
				buf_index = seq % MAXPCKTBUFSIZE;
				packet_buffer[buf_index].type = DATA_TYPE;
				packet_buffer[buf_index].seq = seq;
				toread = (MAXDATABUFSIZE) < (remain) ? (MAXDATABUFSIZE) : (remain);
				packet_buffer[buf_index].size = toread;
				readed = fread(packet_buffer[buf_index].data, sizeof(char), toread, sendfile);
				nbytes = sendto_(sd, &(packet_buffer[buf_index]), sizeof(packet), 0, (struct sockaddr*) &remoteServAddr, remote_len);

				// s/r/rs seq [freeslot] LAR LFS time
				strcpy(log_line, "Send\t");
			        sprintf(tmpstr, "%d\t\t", seq);
				strcat(log_line, tmpstr);
				sprintf(tmpstr, "%d\t", LAR);
				strcat(log_line, tmpstr);
				sprintf(tmpstr, "%d\t", LFS);
				strcat(log_line, tmpstr);
				time(&tmptime);
				strcat(log_line, ctime(&tmptime));
				// strcat(log_line, "\n");
				fwrite(log_line, sizeof(char), strlen(log_line), sendlog);
				printf("%s", log_line);
				LFS++; seq++; remain -= toread;
			}
			else 
			{
				nbytes = timeout_recvfrom(sd, &tmpack, sizeof(ACK), (struct sockaddr*)&remoteServAddr);
				// printf("nbytes: %d, tmpack.seq: %d, tmpack.rws: %d.\n", nbytes, tmpack.seq, tmpack.rws);
				if (nbytes)
				{// received

					if (LAR == tmpack.seq)
					{// duplicated, resend
						SWS = tmpack.rws;
					}	
					if (LAR < tmpack.seq)
					{// update LAR, SWS
						LAR = tmpack.seq;
						SWS = tmpack.rws;
					}	
					// s/r/rs seq [freeslot] LAR LFS time
					strcpy(log_line, "Receive\t");
					sprintf(tmpstr, "%d\t", tmpack.seq);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", tmpack.freeSlots);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LAR);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFS);
					strcat(log_line, tmpstr);
					time(&tmptime);
					strcat(log_line, ctime(&tmptime));
					//strcat(log_line, "\n");
					printf("%s", log_line);
					fwrite(log_line, sizeof(char), strlen(log_line), sendlog);
				}
				else 
				{// timed out, resend up to LFS
					if (LAR >= total - MAXPCKTBUFSIZE  )
					{
						resend_cnt[LAR - total + MAXPCKTBUFSIZE]++;
						if (resend_cnt[LAR - total + MAXPCKTBUFSIZE] >= 10) break;
					}
					int o = LAR + 1;
					int right_most = LFS < (LAR + SWS) ? LFS : (LAR + SWS);
					for (o = LAR + 1; o <= right_most; o++)
					{
						// printf("timed out, resend %d packet.\n", o);
						buf_index = o % MAXPCKTBUFSIZE;
						nbytes = sendto_(sd, &(packet_buffer[buf_index]), sizeof(packet),
								0, (struct sockaddr*) &remoteServAddr, remote_len);
						// resend log
						strcpy(log_line, "Resend\t");
						sprintf(tmpstr, "%d\t\t", packet_buffer[buf_index].seq);
						strcat(log_line, tmpstr);
						sprintf(tmpstr, "%d\t", LAR);
						strcat(log_line, tmpstr);
						sprintf(tmpstr, "%d\t", LFS);
						strcat(log_line, tmpstr);
						time(&tmptime);
						strcat(log_line, ctime(&tmptime));
						//strcat(log_line, "\n");
						fwrite(log_line, sizeof(char), strlen(log_line), sendlog);
						printf("%s", log_line);
					}       	
				}	
				
			}
			if (SWS == 0)
			{// solution to deadlock
			 // probe if RWS has been reset 
			 // and reset SWS
			 // retrieve ack
			 	printf("SWS = 0\n");
				strcpy(log_line, "SWS=0\n");
				fwrite(log_line, sizeof(char), strlen(log_line), sendlog);
			 	nbytes = timeout_recvfrom(sd, &tmpack, sizeof(ACK), (struct sockaddr*) &remoteServAddr);
				if (nbytes) 
				{

					// s/r/rs seq [freeslot] LAR LFS time
					strcpy(log_line, "Receive\t");
					sprintf(tmpstr, "%d\t", tmpack.seq);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", tmpack.freeSlots);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LAR);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFS);
					strcat(log_line, tmpstr);
					time(&tmptime);
					strcat(log_line, ctime(&tmptime));
					// strcat(log_line, "\n");
					fwrite(log_line, sizeof(char), strlen(log_line), sendlog);
					printf("%s", log_line);
					SWS = (tmpack.rws) > 0 ? (tmpack.rws) : 0;
				}	
			}

		}	
		fclose(sendfile);	
	}
	else
	{
		printf("Failed open file %s, please retry. \n", argv[5]);
	}	
	
	// close socket	
	close(sd);
	// close log file
	fclose(sendlog);
}
Beispiel #3
0
int main(int argc, char *argv[]) {	
	int upper_limit = LFRead +  MAXPCKTBUFSIZE;
	int free_slots = upper_limit - LFRcvd;
	RWS = free_slots;
	LAF = LFRcvd + RWS;
	int recv_cnt = 0;
	char log_line[1024];
	char tmpstr[256];
	time_t tmptime;
	
	// buffer
	packet packet_buffer[MAXPCKTBUFSIZE];
	packet tmppacket;
	/* check command line args. */
	if(argc<6) {
		printf("usage : %s <server_port> <error rate> <random seed> <send_file> <send_log> \n", argv[0]);
		exit(1);
	}

	/* Note: you must initialize the network library first before calling sendto_().  The arguments are the <errorrate> and <random seed> */
	init_net_lib(atof(argv[2]), atoi(argv[3]));
	printf("error rate : %f\n",atof(argv[2]));

	/* socket creation */
	int sd;
	if((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		printf("%s: cannot open socket \n",argv[0]);
		exit(1);
	}

	/* bind server port to "well-known" port whose value is known by the client */
	struct sockaddr_in servAddr;
	bzero(&servAddr,sizeof(servAddr));                    //zero the struct
	servAddr.sin_family = AF_INET;                   //address family
	servAddr.sin_port = htons(atoi(argv[1]));        //htons() sets the port # to network byte order
	servAddr.sin_addr.s_addr = INADDR_ANY;           //supplies the IP address of the local machine
	if(bind(sd, (struct sockaddr *)&servAddr, sizeof(servAddr)) <0)
	{
		printf("%s: cannot to bind port number %s \n",argv[0], argv[1]);
		exit(1); 
	}

	/* Open log */
	FILE * rcvlog = fopen(argv[5], "a");	// append trances to log

	/* Receive message from client */
	struct sockaddr_in cliAddr;
	int cliLen = sizeof(cliAddr);
	int nbytes;
	int window_decreasing_flag = 0;
	ACK tmpack;
	// initial shake, recv filename and filesize from client
	char recvmsg[1024];
        bzero(recvmsg,sizeof(recvmsg));
        cliLen = sizeof(cliAddr);
        nbytes = recvfrom(sd, &recvmsg, sizeof (recvmsg), 0, (struct sockaddr *) &cliAddr, &cliLen);
	printf("Client says:\n %s \n", recvmsg);
	
	// parse file name and size
	char fnamechar[256];
	char fsizechar[32]; 
	int fsize;
	char* sec_arg = strstr(recvmsg, "\t");
	strncpy(fnamechar, recvmsg, (sec_arg - recvmsg));
      	strcpy(fsizechar, sec_arg+1);
	fsize = atoi(fsizechar);
	int total = fsize / MAXDATABUFSIZE;
	if (fsize % MAXDATABUFSIZE) total += 1;
	// open file
	FILE * recvfile = fopen(argv[4], "wb");
	if (recvfile)
	{
		// send ack
		tmpack.type = ACK_TYPE;
		tmpack.seq = -1;
		tmpack.rws = RWS;
		nbytes = sendto(sd, &tmpack, sizeof(ACK), 0, (struct sockaddr*)&cliAddr, cliLen);
		
		// receiving file
		int seq = 0;
		int buf_index;
		int skip_recv = 0;
		LFRead = -1;
		LFRcvd = -1;
		LAF = RWS - 1;
		while (LFRcvd < total - 1)
		{	
			if (!skip_recv)
			{	
				nbytes = timeout_recvfrom(sd, &(tmppacket), sizeof(packet), (struct sockaddr*)&cliAddr);
			}
			else
			{
				skip_recv = 0;
			}	
			if (nbytes)
			{// received, check if out of order
				recv_cnt++;
				// force decrease receive window size
				if (recv_cnt >= 30 && recv_cnt <=39 ) 
				{
					RWS--;
					if (RWS < 0) {RWS = 0;}
				}
				// arriave in order
				if (tmppacket.seq == LFRcvd + 1)
				{// update LFRcvd, send ACK, write file,update LFRead
					// update window
					LFRcvd++;
					seq++;
					upper_limit = LFRead +  RWS + 1;
					free_slots = upper_limit - LFRcvd;
					// if (window_decreasing_flag == 0)
					// { RWS = free_slots; }
					LAF = LFRcvd + RWS;
					// construct ACK
					tmpack.seq = LFRcvd;
					tmpack.freeSlots = free_slots;
					tmpack.rws = RWS;

					// s/r/rs seq [freeslot] LFRead LFRcvd LAF time
					strcpy(log_line, "Receive\t");
					sprintf(tmpstr, "%d\t\t", tmppacket.seq);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFRead);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFRcvd);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LAF);
					strcat(log_line, tmpstr);
					time(&tmptime);
					strcat(log_line, ctime(&tmptime));
					// strcat(log_line, "\n");
					fwrite(log_line, sizeof(char), strlen(log_line), rcvlog);
					printf("%s", log_line);

					// send ACK
					nbytes = sendto_(sd, &tmpack, sizeof(ACK), 0, (struct sockaddr*)&cliAddr, cliLen);

					// s/r/rs seq [freeslot] LFRead LFRcvd LAF time
					strcpy(log_line, "Send\t");
					sprintf(tmpstr, "%d\t", tmpack.seq);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", free_slots);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFRead);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFRcvd);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LAF);
					strcat(log_line, tmpstr);
					time(&tmptime);
					strcat(log_line, ctime(&tmptime));
					//strcat(log_line, "\n");
					fwrite(log_line, sizeof(char), strlen(log_line), rcvlog);
					printf("%s", log_line);

					// write file
					fwrite((char*)&(tmppacket.data), sizeof(char), tmppacket.size, recvfile);
					// update LFRead
					LFRead = tmppacket.seq ; // equivalent to LFRread++;	

					// scan previous received out of order packets
					int k = LFRcvd;
					for(k = LFRcvd + 1; k < LFRcvd + 1 + MAXPCKTBUFSIZE; k++)
					{
						buf_index = k % MAXPCKTBUFSIZE;
						if (packet_buffer[buf_index].seq == LFRcvd + 1)
						{
							// update window
							LFRcvd++;
							seq++;
							upper_limit = LFRead +  RWS + 1;
							free_slots = upper_limit - LFRcvd;
							//if (window_decreasing_flag == 0)
							//{ RWS = free_slots;}
							// construct ACK
							tmpack.seq = LFRcvd;
							tmpack.freeSlots = free_slots;
							tmpack.rws = RWS;
							// send ACK
							nbytes = sendto_(sd, &tmpack, sizeof(ACK), 0, 
									(struct sockaddr*)&cliAddr, cliLen);

							// s/r/rs seq [freeslot] LFRead LFRcvd LAF time
							strcpy(log_line, "Send\t");
							sprintf(tmpstr, "%d\t", tmpack.seq);
							strcat(log_line, tmpstr);
							sprintf(tmpstr, "%d\t", free_slots);
							strcat(log_line, tmpstr);
							sprintf(tmpstr, "%d\t", LFRead);
							strcat(log_line, tmpstr);
							sprintf(tmpstr, "%d\t", LFRcvd);
							strcat(log_line, tmpstr);
							sprintf(tmpstr, "%d\t", LAF);
							strcat(log_line, tmpstr);
							time(&tmptime);
							strcat(log_line, ctime(&tmptime));
							// strcat(log_line, "\n");
							fwrite(log_line, sizeof(char), strlen(log_line), rcvlog);
							printf("%s", log_line);

							// write file
							fwrite((char*)&(packet_buffer[buf_index].data), sizeof(char), packet_buffer[buf_index].size, recvfile);
							// update LFRead
							LFRead = LFRcvd;
						}	
					}
				}
				if (tmppacket.seq > LFRcvd + 1)
				{// arrive out of order, cache packet, send duplicate ACK
				 // as we are sending a duplicate ACK, which is exactly the previous ACK sent
				 // just update ack.rws would be enough
				 	tmpack.rws = RWS;	
					nbytes = sendto_(sd, &tmpack, sizeof(ACK), 0, (struct sockaddr*)&cliAddr, cliLen);

					// receive log
					strcpy(log_line, "Receive\t");
					sprintf(tmpstr, "%d\t\t", tmppacket.seq);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFRead);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFRcvd);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LAF);
					strcat(log_line, tmpstr);
					time(&tmptime);
					strcat(log_line, ctime(&tmptime));
					// strcat(log_line, "\n");
					fwrite(log_line, sizeof(char), strlen(log_line), rcvlog);
					printf("%s", log_line);
					
					// send duplicate ACK log
					// s/r/rs seq [freeslot] LFRead LFRcvd LAF time
					strcpy(log_line, "Send\t");
					sprintf(tmpstr, "%d\t", tmpack.seq);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", free_slots);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFRead);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LFRcvd);
					strcat(log_line, tmpstr);
					sprintf(tmpstr, "%d\t", LAF);
					strcat(log_line, tmpstr);
					time(&tmptime);
					strcat(log_line, ctime(&tmptime));
					//strcat(log_line, "\n");
					fwrite(log_line, sizeof(char), strlen(log_line), rcvlog);
					printf("%s", log_line);

					// buffer out of order packet received
					buf_index = tmppacket.seq % MAXPCKTBUFSIZE;
					packet_buffer[buf_index].seq = tmppacket.seq;
					packet_buffer[buf_index].size = tmppacket.size;
					packet_buffer[buf_index].type = tmppacket.type;
					strcpy(packet_buffer[buf_index].data, tmppacket.data);
					
				}
				if (tmppacket.seq < LFRcvd + 1)
				{// packets alreadly received and buffered, discard
					;
				}	
			}
			// decrease rws
			// if (recv_cnt == 30) window_decreasing_flag = 1;
			// handle situation when RWS is 0
			if (RWS == 0) 
			{// RWS decreased to 0
				printf("RWS = 0!!!!!\n");
				strcpy(log_line, "RWS = 0!!!!!!!!!!\n");
				fwrite(log_line, sizeof(char), strlen(log_line), rcvlog);
				printf("window_decreasing_flag = %d\n", window_decreasing_flag);
				if (1)
				{// reset flag and sleep 10 ms	
					// window_decreasing_flag = 0;
					receiver_sleep();
					RWS = 6;
					// send ACK
					do
					{	
						tmpack.rws = RWS;
						nbytes = sendto_(sd, &tmpack, sizeof(ACK), 0, (struct sockaddr*)&cliAddr, cliLen);

						// s/r/rs seq [freeslot] LFRead LFRcvd LAF time
						strcpy(log_line, "Send\t");
						sprintf(tmpstr, "%d\t", seq);
						strcat(log_line, tmpstr);
						sprintf(tmpstr, "%d\t", free_slots);
						strcat(log_line, tmpstr);
						sprintf(tmpstr, "%d\t", LFRead);
						strcat(log_line, tmpstr);
						sprintf(tmpstr, "%d\t", LFRcvd);
						strcat(log_line, tmpstr);
						sprintf(tmpstr, "%d\t", LAF);
						strcat(log_line, tmpstr);
						time(&tmptime);
						strcat(log_line, ctime(&tmptime));
						//strcat(log_line, "\n");
						fwrite(log_line, sizeof(char), strlen(log_line), rcvlog);
						printf("%s", log_line);

						nbytes = timeout_recvfrom(sd, &tmppacket, sizeof(packet), (struct sockaddr*)&cliAddr);

					}while(!nbytes);
					window_decreasing_flag = 0;	
					skip_recv = 1;
				}
			}	
		}
	fclose(recvfile);	
	}
	else
	{
		printf("Failed open file %s, please retry. \n", fnamechar);
	}	

	// close log file
	fclose(rcvlog);
	// close socket
	close(sd);
}