int main(int argc, char *argv[]) { //check command line args. if(argc<6) { printf("usage : %s <server> <error rate> <random seed> <send_file> <send_log> \n", argv[0]); exit(1); } printf("error rate : %f\n",atof(argv[2])); /* 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])); /* get server IP address (input must be IP address, not DNS name) */ printf("%s: sending data to '%s' \n", argv[0], argv[1]); remoteServAddr.sin_family = AF_INET; remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT); inet_pton(AF_INET, argv[1], &remoteServAddr.sin_addr); cliAddr.sin_family = AF_INET; cliAddr.sin_addr.s_addr = htonl(INADDR_ANY); cliAddr.sin_port = htons(0); /* socket creation */ sd = socket(************************); if(sd<0) { printf("%s: cannot open socket \n",argv[0]); exit(1); } msg[] = "send this"; sendto_(sd,msg, strlen(msg),0, (struct sockaddr *) &remoteServAddr, sizeof(remoteServAddr)); }
int main( int argc, char *argv[] ) { // Variables char c; // Character to write to our program int sock; // Our Socket int index; // Index to get data from frame struct sockaddr_in servAddr; // Server Address struct sockaddr_in cliAddr; // Client Address unsigned int cliLen = sizeof( cliAddr ); // Length of Client struct int nbytes; // Number of bytes read char ack[2]; // Acknowledgment packet SwpState server; // Window state FILE *log, *out; // File pointers to log and output file // Initalize Variables server.hdr.SeqNum = 0; server.hdr.Flags = 0; server.LFRead = 0; server.LFRcvd = -1; server.LAF = RWS; server.NFE = 0; ack[SEQNUM] = -1; ack[FLAGS] = 0; // Check command line args. if( argc < 6 ) { printf( "Usage: %s <server_port> <error rate> <random seed> <output_file> <recieve_log> \n", argv[0] ); exit( EXIT_FAILURE ); } // 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] ) ); // Open log and output file out = fopen( argv[4], "w" ); ERROR( out == NULL ); log = fopen( argv[5], "w" ); ERROR( log == NULL ); // Socket creation sock = socket( AF_INET, SOCK_DGRAM, 0 ); ERROR( sock < 0 ); // Bind server port to "well-known" port whose value is known by the client 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 ERROR( bind( sock, (struct sockaddr *) &servAddr, sizeof( servAddr ) ) < 0 ); char buffer[PACKETSIZE]; bzero( &buffer, PACKETSIZE ); do { // Receive message from client nbytes = recvfrom( sock, &buffer, PACKETSIZE, 0, (struct sockaddr *) &cliAddr, &cliLen ); ERROR( nbytes < 0 ); // Make sure to cap string buffer[nbytes] = '\0'; server.hdr.SeqNum = buffer[SEQNUM]; // Check to see if packet is what we need if ( ( buffer[SEQNUM] >= server.LAF - RWS ) && ( buffer[SEQNUM] < server.LAF ) ) { // Set Last Frame Recieved to this buffer number server.LFRcvd = buffer[SEQNUM]; memcpy( server.recvQ[ server.LFRcvd % RWS ].msg, buffer, PACKETSIZE); // Update log logTime( log, "RECEIVE", &server ); } // Check to see if the one we recieved is the next frame if ( server.LFRcvd == server.NFE ) { // Copy and write recieved data index = 2; do { c = server.recvQ[server.NFE % RWS].msg[index]; if ( c == '\0' ) break; fputc( c, out ); index++; } while ( index < PACKETSIZE - 1 ); server.LFRead = server.NFE; // Set Ack Header Data ack[SEQNUM] = server.LFRcvd; ack[FLAGS] = 0; } // Respond using sendto_ in order to simulate dropped packets nbytes = sendto_( sock, ack, PACKETSIZE, 0, (struct sockaddr *) &cliAddr, sizeof( cliAddr ) ); ERROR( nbytes < 0 ); // Check to see if the one we recieved is the next frame if ( server.LFRcvd == server.NFE ) { // Update log logTime( log, "SEND", &server ); // Increment Next Frame Expected server.NFE++; // Increment Largest Acceptable Frame server.LAF++; } else { // Update log logTime( log, "RESEND", &server ); } } while ( buffer[FLAGS] != 1 ); // Close files fclose( log ); fclose( out ); return EXIT_SUCCESS; }
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); }
int main(int argc, char *argv[]) { typedef char * string; struct sockaddr_in cliAddr, remoteServAddr; //Socker addresses for the client and remote unsigned int remote_length = sizeof(remoteServAddr); //Length of remote address struct int sd; //The socket that we will use u_char receive_buffer[3]; //The buffer that receives acks. 512 bytes long struct timeval default_timeout; //The default timeout we are using for the select() default_timeout.tv_sec = 2; //2 secs default_timeout.tv_usec = 500000; //0.5 secs fd_set read_fds; // temp file descriptor list for select() //Initialize the state of the client SwpSeqno receivedAcks[500]; //(Non-optimal) implementation of the ACK list static SwpState state; initializeState(&state, receivedAcks); //Check command line args. if(argc<6) { printf("usage : %s <serve_ip_address> <error_rate> <random_seed> <send_file> <send_log> \n", argv[0]); exit(1); } //Print error rate printf("error rate : %f\n",atof(argv[2])); /* Note: you must initialize the network library first before calling sendto_(). The arguments are the <error_rate> and <random_seed> */ init_net_lib(atof(argv[2]), atoi(argv[3])); /* Test printing to the client Log */ /*int temp[] = {1,2,3,5}; int size_of_temp = 4; toLog(1, argv[5], "Send", state.hdr.SeqNum, temp, size_of_temp, &state);*/ /* get server IP address (input must be IP address, not DNS name) */ printf("%s: sending data to '%s' \n", argv[0], argv[1]); //Set up the address of the remote server. bzero(&remoteServAddr, sizeof(remoteServAddr)); //zero out the address remoteServAddr.sin_family = AF_INET; //address family remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT); //Use the port we set up //Convert the char string into an INET address structure int retVal; retVal = inet_pton(AF_INET, argv[1], &remoteServAddr.sin_addr); if(retVal == -1){ printf("Invalid address family for IP address\n"); } //Same deal with our client address cliAddr.sin_family = AF_INET; cliAddr.sin_addr.s_addr = htonl(INADDR_ANY); cliAddr.sin_port = htons(0); /* socket creation */ sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(sd<0) { printf("%s: cannot open socket \n",argv[0]); exit(1); } /* Open up our send file to get it ready to packet-ize and send */ FILE *fsend; fsend = fopen(argv[4],"r"); //Open the filename we entered if(fsend == NULL){ printf("Please use an existing file to send\n"); printf("usage : %s <serve_ip_address> <error_rate> <random_seed> <send_file> <send_log> \n", argv[0]); exit(1); } //Prep for the send loop FD_ZERO(&read_fds); //clear the select set FD_SET(sd, &read_fds); //add socket to the listening list int nbytes; char doneReadingFile = 0; //Flag to tell us if we are done reading the file SwpSeqno lastSeqNum = -1; //What is the last sequence number? Msg frame; char isSelectRunning = 0; struct timeval new_timeout; //The default timeout we are using for the select() new_timeout.tv_sec = 2; //2 secs new_timeout.tv_usec = 500000; //0.5 secs struct timeval void_timeout; void_timeout.tv_sec = 2147483647; void_timeout.tv_usec = 2147483647; struct recvQ_slot *rslot; struct timeval timeofday; /* Start the loop for sliding window. Stop conditions are that the whole file has been read and the LAR == LFS */ int count = 0; do{ //size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file); //printf("size of reading%ld\n",sizeof(Msg)-3*sizeof(char)); //Read a frame's worht of the file. if((nbytes = fread(&frame.m[3],sizeof(char),sizeof(frame.m)-3*sizeof(u_char), fsend))== -1){ printf("Error Reading File, Try again...\n"); // break; } //If the file is done being read else if (nbytes == 0){ doneReadingFile = 1; lastSeqNum = state.hdr.SeqNum; } //If there was something to read! else{ //printf("positions 4 5 6 %c %c %c\n",frame.m[3], frame.m[4],frame.m[5]); if(sendNewFrame(&state, &frame, isSelectRunning, sd,&read_fds, &default_timeout,&remoteServAddr,sizeof(remoteServAddr)) < 0){ printf("Error on packet send\n"); } // if(sendto_(sd, frame.m, sizeof(frame.m),0, (struct sockaddr *) &remoteServAddr, // sizeof(remoteServAddr)) < 0) // { // printf("EROROROEOs\n"); // } int num_least; if (FD_ISSET(sd, &read_fds)){ printf("received packet!\n"); if ((nbytes = recv(sd, &receive_buffer, sizeof(receive_buffer), 0)) <= 0) { // got error or connection closed by client if (nbytes == 0) { // connection closed printf("selectserver: socket %d hung up\n", sd); } else { perror("recv"); } } else {//Got an ACK! Update everyone's timeouts, get rid of the ACK sequence #'s timeout printf("got %d\n", receive_buffer[1]); SwpSeqno ack = receive_buffer[1]; if(ack == state.LAR +1){ state.sendQ[ack%SWS].timeout = void_timeout; struct timeval *least = &state.sendQ[0].timeout; struct timeval *temp; int i; if(gettimeofday(&timeofday,NULL)){ printf("Get timeofday error\n"); } for(i = 0;i < SWS;i++){ state.sendQ[i].timeout.tv_sec = timeofday.tv_sec - state.sendQ[i].timeout.tv_sec; state.sendQ[i].timeout.tv_usec = timeofday.tv_usec - state.sendQ[i].timeout.tv_usec; temp = &state.sendQ[i].timeout; if((least->tv_sec * 1000000 + least->tv_usec) > (temp->tv_sec * 1000000 + temp->tv_usec)){ least->tv_sec = temp->tv_sec; least->tv_usec = temp->tv_usec; num_least = i; } } printf("%d", num_least); FD_ZERO(&read_fds); //clear the select set FD_SET(sd, &read_fds); //add socket to the listening list if (select(sd+1, &read_fds, NULL, NULL, least) == -1) { perror("select"); exit(4); } //Move the ++state.newSend; ++state.LAR; ++state.LFS; state.sendQ[ack%RWS].acked = 0; while(state.sendQ[(state.LFS+1)%RWS].acked){ ++state.newSend; ++state.LAR; ++state.LFS; state.sendQ[ack%RWS].acked = 0; } } else if(ack > state.LFS && ack < state.LAR){ state.sendQ[ack%SWS].timeout = void_timeout; struct timeval *least = &state.sendQ[0].timeout; struct timeval *temp; int i; for(i = 0;i < SWS;i++){ temp = &state.sendQ[0].timeout; if((least->tv_sec * 1000000 + least->tv_usec) > (temp->tv_sec * 1000000 + temp->tv_usec)){ least->tv_sec = temp->tv_sec; least->tv_usec = temp->tv_usec; num_least = i; } } FD_ZERO(&read_fds); //clear the select set FD_SET(sd, &read_fds); //add socket to the listening list if (select(sd+1, &read_fds, NULL, NULL, least) == -1) { perror("select"); exit(4); } state.sendQ[ack%RWS].acked = 1; } } } else{ printf("Timed out. Resend\n"); SwpSeqno done; int i; struct timeval *temp; struct timeval *least = &state.sendQ[0].timeout; //Find which packet must be resent. for(i = 0;i < SWS;i++){ temp = &state.sendQ[0].timeout; if((temp->tv_sec * 1000000 + temp->tv_usec) >= 0) { done = state.sendQ[i].msg.m[0]; gettimeofday(&state.sendQ[i].timeout, NULL); //Ressend the frame; if(sendto_(sd, state.sendQ[i].msg.m, sizeof(state.sendQ[i].msg.m),0, (struct sockaddr *) &remoteServAddr, sizeof(remoteServAddr)) < 0){ printf("EROROROEOs\n"); } } } //Redo select for(i = 0;i < SWS;i++){ temp = &state.sendQ[0].timeout; if((least->tv_sec * 1000000 + least->tv_usec) > (temp->tv_sec * 1000000 + temp->tv_usec)){ least->tv_sec = temp->tv_sec; least->tv_usec = temp->tv_usec; num_least = i; } } FD_ZERO(&read_fds); //clear the select set FD_SET(sd, &read_fds); //add socket to the listening list new_timeout.tv_sec = least->tv_sec; //2 secs //printf("%d\n", least->tv_sec); new_timeout.tv_usec = least->tv_usec; if (select(sd+1, &read_fds, NULL, NULL, &new_timeout) == -1) { perror("select"); exit(4); } //sendto_(sd, msgs[iter], strlen(msg),0, (struct sockaddr *) &remoteServAddr, //sizeof(remoteServAddr)); } } count++; }while(!doneReadingFile && state.LAR != state.LFS); fclose(fsend); /* int sendto_(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, socklen_t tolen); */ /* FD_ZERO(&read_fds); FD_SET(sd, &read_fds); int nbytes; //sd; //Keep track of biggest file descriptor //for(;;){ char msg[] = "send this"; char msg2[] = "send that"; string msgs[4]; msgs[0] = "0send this"; msgs[1] = "1send that"; msgs[2] = "2cat in "; msgs[3] = "3hat"; int iter = 0; while(iter < 4){ sendto_(sd, msgs[iter], strlen(msg),0, (struct sockaddr *) &remoteServAddr, sizeof(remoteServAddr)); if (select(sd+1, &read_fds, NULL, NULL, &default_timeout) == -1) { perror("select"); exit(4); } if (FD_ISSET(sd, &read_fds)){ printf("received packet!\n"); if ((nbytes = recv(sd, receive_buffer, sizeof(receive_buffer), 0)) <= 0) { // got error or connection closed by client if (nbytes == 0) { // connection closed printf("selectserver: socket %d hung up\n", sd); } else { perror("recv"); } } else { printf("%s\n", receive_buffer); iter++; } } else{ printf("Timed out. Resend\n"); //sendto_(sd, msgs[iter], strlen(msg),0, (struct sockaddr *) &remoteServAddr, //sizeof(remoteServAddr)); } } */ //} return 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); }
int main(int argc, char *argv[]) { static int selret; unsigned int recLen; static char* p; static char filebuffer[FILESIZE]; static char directemp[BUFSIZE]; static char filename[BUFSIZE]; static struct timeval time; static fd_set readFDS; static frame frameArray[MAXSEQNUM]; static int LB = 0, RB = 0; // static static char ackBuffer[100]; static ack recvAck; static timeStruct timesArray[SWS]; int lastSeqNum = -1; double t, timeout; int lastFrameCount = 0; //check command line args. if(argc < 6) { printf("usage : %s <server> <error rate> <random seed> <send_file> <send_log> \n", argv[0]); exit(1); } printf("argv4: %s\n",argv[4]); if(strcmp(argv[4],"0")){ strcpy(directemp,argv[4]); p = strtok(directemp,DELM); while(p != NULL){ strcpy(filename,p); p= strtok(NULL,DELM); } printf("Filename: %s\n",filename); fp = fopen(argv[4],"r"); if(fp == NULL){ printf("Error opening file: %s\n",strerror(errno)); } //strcpy(msgbuffer,filebuffer); } printf("error rate : %f\n",atof(argv[2])); printf("%s: sending data to '%s' \n", argv[0], argv[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])); /* get server IP address (input must be IP address, not DNS name) */ //setup socket structs /***************************************************/ remoteServAddr.sin_family = AF_INET; remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT); inet_pton(AF_INET, argv[1], &remoteServAddr.sin_addr); cliAddr.sin_family = AF_INET; cliAddr.sin_addr.s_addr = htonl(INADDR_ANY); cliAddr.sin_port = htons(0); /*************************************************/ /* socket creation */ if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("Unable to connect socket!\n"); exit(1); } int lastFrameSent = 0; while(1){ bzero(&ackBuffer, sizeof(ackBuffer)); int moveCount = MoveForward(&LB, &RB, frameArray, MAXSEQNUM); if(lastFrameSent == 0){ lastFrameSent = SendNextFrames(moveCount, frameArray, MAXSEQNUM, LB, &fp, &sock,(struct sockaddr *) &remoteServAddr, timesArray, SWS); } /* if((sendto_(sock,sendFrame, strlen(sendFrame),0, (struct sockaddr *) &remoteServAddr, sizeof(remoteServAddr)))< 0 ){ printf("Error Sending\n"); perror("sendto()"); exit(1); }*/ gettimeofday(&time,NULL); t = (time.tv_sec + (time.tv_usec/1000000.0)); timeout = (currentDeadline(timesArray,SWS) + DELAY) - t; printf("Timeout: %f\n", timeout); if(timeout < 0){timeout = 0;} selret = ballinselect(sock,&readFDS,timeout,0); if ((selret != -1) && (selret != 0)){ if(recvfrom(sock, &ackBuffer, sizeof (ackBuffer), 0,(struct sockaddr *) &recAddr, (socklen_t*) &recLen) < 0){ perror("recvfrom()"); exit(1); } printf("Ack Buffer: %s\n",ackBuffer); makeackstruct(ackBuffer, &recvAck); if(lastSeqNum != recvAck.seqNum){ frameArray[recvAck.seqNum].ack = 1; lastSeqNum = recvAck.seqNum; printf("============================\n"); printf("Received Ack!\n"); printf("Ack SeqNum: %d\n", recvAck.seqNum); printf("============================\n\n\n"); removefromtimearray(recvAck.seqNum, timesArray,SWS); } } else if (selret == 0) { printf("timeout\n"); bzero(&filebuffer,sizeof(filebuffer)); int timeoutframe = FindTimeout(timesArray,SWS); if(frameArray[timeoutframe].lastFrame == 1){ if(frameArray[timeoutframe].ack == 1){return EXIT_SUCCESS;} if(lastFrameCount == 10){return EXIT_SUCCESS;} lastFrameCount ++; } MakePacket(filebuffer,frameArray[timeoutframe]); printf("\nSending Timed out Frame: \n\n"); printFrame(frameArray[timeoutframe]); if((sendto_(sock,filebuffer, strlen(filebuffer),0, (struct sockaddr *) &remoteServAddr, sizeof(remoteServAddr)))< 0 ){ printf("Error Sending\n"); perror("sendto()"); exit(1); } /*gettimeofday(&time,NULL); double t2= time.tv_sec + (time.tv_usec/1000000.0); printf("Time Out Time time: %f\n",t2);*/ } else if (selret < 0) {printf("select() failed\n");} } fclose(fp); return EXIT_SUCCESS; }