/************************************************************************ /* * UCSD CSE123a * (from Byer's BU CS555 assignment) * Winter 2005 * * The interfaces for the SRMP sender (you get to implement them), and a * simple application-level routine to drive the sender. * * This routine reads the data to be transferred over the connection * from a file specified and invokes the SRMP send functionality to * deliver the packets as an ordered sequence of datagrams. * * Version 2.0 * * *************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "srmp.h" #define SRMP_ERROR -1 #define SRMP_PASS 1 #define MAX_SEQ 65535 #define TIME_OUT 2000 // Receiver timeout in ms int send_syn_attempts(srmp_send_ctrl_blk *); int send_data_attempts(srmp_send_ctrl_blk *); unsigned short int random_number(void); int srmp_sender_state_transition_machine(srmp_send_ctrl_blk *); int can_send_data(srmp_send_ctrl_blk *,int); /* * Send a message using SRMP. * The main entry point to the (not yet implemented) sender-side of the protocol. */ int srmp_send (srmp_send_ctrl_blk *srmp_CB, char* data, int len) { int result; srmp_CB->state = SRMP_ESTABLISHED; srmp_CB->data = data; srmp_CB->length = len; result = srmp_sender_state_transition_machine(srmp_CB); return result; } /* * Open the sender side of the SRMP connection. * */ int srmp_open(srmp_send_ctrl_blk * srmp_CB, char *dst, int sport, int rport) { /********************YOUR CODE HERE**********************************/ // open the udp connection and start the statemachine } int srmp_sender_state_transition_machine(srmp_send_ctrl_blk *srmp_CB) { /********************YOUR CODE HERE**********************************/ } // end srmp_sender_state_transition_machine /* * Close the sender side of the SRMP connection after all data transmitted. * */ int srmp_close(srmp_send_ctrl_blk *srmp_CB) { int result; srmp_CB->state = SRMP_CLOSING; result = srmp_sender_state_transition_machine(srmp_CB); if (result == SRMP_ERROR) return result; srmp_CB->state = SRMP_FIN_WAIT; result = srmp_sender_state_transition_machine(srmp_CB); return result; } unsigned short int random_number(void) { // Not a perfect RNG, but will do the job srand(time(0)); return (rand() % MAX_SEQ); } /***************************************************************/ /* This application is to invoke the send-side functionality. */ /* Feel free to rewrite or write your own application to */ /* test your code. */ /* */ /***************************************************************/ int main(int argc, char **argv) { srmp_send_ctrl_blk *srmp_CB; char *dst; int recv_port, send_port; int file; int ret_val; /* Verify that the arguments are right*/ if (argc != 5) { fprintf(stderr, "usage: SendApp receiver-IP-address recv-port send-port filename \n"); exit(1); } /************************************************************/ /* */ /* Open connection to destination. If srmp_open succeeds */ /* the srmp_CB should be correctly initialized */ /* */ /************************************************************/ srmp_CB = (srmp_send_ctrl_blk *) malloc (sizeof( *srmp_CB)); dst = argv[1]; recv_port = atoi(argv[2]); send_port = atoi(argv[3]); ret_val = srmp_open(srmp_CB, dst, send_port, recv_port); if( ret_val == SRMP_ERROR ) reset(srmp_CB->fd); /************************************************************/ /* */ /* Open file for transfer */ /* */ /************************************************************/ file = open(argv[4], O_RDONLY); if (file < 0) { perror(argv[4]); exit(1); } /************************************************************/ /* */ /* Start to send data in file via SRMP to remote receiver */ /* */ /************************************************************/ /************************************************************/ /* */ /* Chop up the file into pieces half as large as max */ /* packet size ... and transmit those pieces. */ /* */ /************************************************************/ while(1) { char wrk[SRMP_MAXPKT/2]; int cc = read(file, wrk, SRMP_MAXPKT/2); /* Break when EOF is reached */ if(cc <= 0) break; if(srmp_send(srmp_CB, wrk, cc) == SRMP_ERROR) reset(srmp_CB->fd); } /************************************************************/ /* */ /* Close the connection to remote receiver */ /* */ /************************************************************/ if (srmp_close(srmp_CB) == SRMP_ERROR) reset(srmp_CB->fd); free(srmp_CB); return 0; } int send_syn_attempts(srmp_send_ctrl_blk *srmp_CB) { int attempts = 0; char *packet = (char *)malloc(SRMP_MAXPKT); int result; int isn; srmphdr *srh; while (attempts++ < 3) { sendpkt(srmp_CB->fd, SRMP_SYN, 0, srmp_CB->seqno, 0, 0); result = readWithTimer(srmp_CB->fd,packet, TIME_OUT); if (result != SRMP_TIMED_OUT) { srh = (srmphdr *)packet; isn = ntohs(srh->seqno); srmp_CB->AdvWin = ntohs(srh->window); srmp_CB->LAR = isn; srmp_CB->LFS = srmp_CB->seqno; //srmp_CB->LAR; srmp_CB->MaxAdvWin = srmp_CB->AdvWin; srmp_CB->ESWS = srmp_CB->AdvWin; srmp_CB->first_data_sent = 1; srmp_CB->cansend = 1; if (isn != plus(srmp_CB->seqno,1)) return SRMP_ERROR; else { srmp_CB->NBE = isn; return SRMP_PASS; } } } return SRMP_ERROR; } void send_store_data(srmp_send_ctrl_blk *srmp_CB, unsigned short seqno, char *data, int len) { int diff; sender_add_packet(srmp_CB, seqno, time(NULL),data, len); sendpkt(srmp_CB->fd,SRMP_DATA,0,seqno,data,len); diff = minus(srmp_CB->LFS,srmp_CB->LAR); srmp_CB->ESWS = srmp_CB->AdvWin - diff; if (srmp_CB->ESWS < 0) srmp_CB->ESWS = 0; //printf("ESWS :%d\n",srmp_CB->ESWS); } int can_send_data(srmp_send_ctrl_blk *srmp_CB,int len) { int diff = minus(srmp_CB->LFS,srmp_CB->LAR); int esws = srmp_CB->AdvWin - diff; if (esws < 0) { return 0; } return 1; }