Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*turboclient.c*/
- //gcc turboclient.c -o utc && utc 128.10.104.134 23456 abcdeabcdeab kl.au configfile.dat
- //utc 128.10.104.134 23456 abcdeabcdeab kl.au configfile.dat
- #include <signal.h>
- #include <sys/wait.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <netdb.h>
- #include <errno.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <sys/time.h>
- #include "dropsendto.h"
- #include "p_params.h"
- #define MAX_BUF 1600
- #define MAX_LOAD 1600
- #ifndef max
- #define max(a,b) ((a) > (b) ? (a) : (b))
- #endif
- void signal_sigio_hndlr(int sig);
- int work_to_do = 0;
- void signal_sigio_hndlr(int sig){
- work_to_do = 1;
- //printf("HHHHHHHHHHHHHHHHHHHHHHHHHHHHAAAAAAAAAAAAAAAAANNNNNNNNNNNNNDDDDDDDDDDDLLLLLLLLLLLLEEEEEEEEEERRRRRRRRRRRR\n");
- }
- typedef struct
- {
- int *seq_id;
- int *paylen;
- int *h_exist;
- char *payload;
- }PKINFO;
- PKINFO *pckt_book = NULL;
- int check_fname(char *s);
- int check_fname(char *s){
- //0 means good file name
- //1 means bad file name
- char *c = s;
- int len = strlen(s);
- const char *invalid_chars = " /";
- if(len>16)
- return 1;
- while(*c){
- if(strchr(invalid_chars, *c))
- return 1;
- c++;
- }
- return 0;
- }
- int main(int argc, char * argv[]) {
- char *srv_name, *srv_port, *secretkey, *filename, *config_file;
- struct sockaddr_in srv_addr, udp_cl;
- struct sockaddr_storage from_addr;
- socklen_t from_addr_len = sizeof(from_addr);
- struct hostent *hp;
- int len, block_size, val, fd, send_sock, sock_ack, j;
- FILE *fp;
- char request[MAX_BUF], f_name[MAX_BUF], r_filename[MAX_BUF], nack[25], p_ack[5] = "$P$", all_ack[5] = "$A$";
- struct timeval tv1, tv2;
- long time_elapsed = 0, bytes_read = 0;
- if (argc == 6) {
- srv_name= argv[1];
- srv_port = argv[2];
- secretkey = argv[3];
- filename = argv[4];
- config_file = argv[5];
- } else {
- printf(
- "usage: $turboclient hostname portnumber secretkey filename configfile.dat\n");
- exit(1);
- }
- if(check_fname(filename) == 1){
- printf("Bad filename, cannot contain spaces, slashes or exceed a length of 16 ascii characters\n");
- exit(1);
- }
- pckt_book = (PKINFO*)malloc(CACHE_SZ * sizeof(PKINFO));
- for(j = 0; j< CACHE_SZ; j++) {
- PKINFO tmp;
- tmp.seq_id = (int *)malloc(sizeof(int));
- tmp.paylen = (int *)malloc(sizeof(int));
- tmp.h_exist = (int *)malloc(sizeof(int));
- tmp.payload = (char *)malloc(MAX_LOAD);
- memcpy((pckt_book + j), &tmp, sizeof(PKINFO));
- }
- for(j = 0; j< CACHE_SZ; j++) {
- memset(pckt_book[j].seq_id, 0, sizeof(int));
- memset(pckt_book[j].h_exist, 1, sizeof(int));
- memset(pckt_book[j].paylen, 0, sizeof(int));
- memset(pckt_book[j].payload, 0, MAX_LOAD);
- }
- //reading blocksize
- fp = fopen(config_file, "r");
- //fscanf stops scanning at whitespace
- fscanf(fp, "%d", &block_size);
- fclose(fp);
- //Setting up io signal
- struct sigaction sgio;
- sgio.sa_handler = signal_sigio_hndlr;
- sgio.sa_flags = 0;
- //sgio.sa_flags = SA_RESTART;
- sigemptyset(&sgio.sa_mask);
- if (sigaction(SIGPOLL, &sgio, NULL) == -1) {
- perror("sigaction sigio");
- exit(1);
- }
- //char recvbuf[block_size];
- char recvbuf[MAX_BUF];
- hp = gethostbyname(srv_name);
- if (!hp) {
- printf("Error: unknown host: %s\n", srv_name);
- exit(1);
- }
- memset((char *) &srv_addr, 0, sizeof(srv_addr));
- srv_addr.sin_family = AF_INET;
- bcopy(hp->h_addr_list[0], (char *) &srv_addr.sin_addr, hp->h_length);
- srv_addr.sin_port = htons(atoi(srv_port));
- send_sock = socket(AF_INET, SOCK_DGRAM, 0);
- sprintf(request, "$%s$%s", secretkey, filename);
- if ((val = sendto(send_sock, request, strlen(request), 0, (struct sockaddr *)&srv_addr, sizeof(srv_addr))) == -1) {
- perror("Send to error: forwarding");
- exit(1);
- }
- strcpy(f_name, "/tmp/");
- strcpy(r_filename, "/tmp/");
- strcat(r_filename, filename);
- srand(time(NULL));
- int f_ind = rand();
- char r_append[MAX_BUF];
- sprintf(r_append, "_w%d", f_ind);
- strcat(strcat(f_name, filename), r_append);
- //printf("f_name is %s\n", f_name);
- //Read response and save it in ./filename
- if (access(f_name, F_OK) != -1) {
- // file exists
- printf("Error: File already exists\n");
- exit(1);
- } else {
- // file doesn't exist, hence create it
- fd = open(f_name, O_RDWR| O_APPEND | O_CREAT, S_IRUSR | S_IWUSR |S_IXUSR);
- //noting starting time
- if (gettimeofday(&tv1, NULL) == -1) {
- exit(1);
- }
- memset(recvbuf, 0, MAX_BUF);
- int n_excpt = 0, seq_no = -1, p_len, buf_ind, eot_flag = 0, holes = CACHE_SZ, f_in, true_h = 0, c_rcv = 0;
- memset((char *) &udp_cl, 0, sizeof(udp_cl));
- udp_cl.sin_family = AF_INET;
- bcopy(hp->h_addr_list[0], (char *) &udp_cl.sin_addr, hp->h_length);
- udp_cl.sin_port = htons(0);
- sock_ack = socket(AF_INET, SOCK_DGRAM, 0);
- bind(sock_ack, (struct sockaddr *) &udp_cl, sizeof(udp_cl));
- fcntl(send_sock, F_SETFL, O_NONBLOCK|O_ASYNC);
- fcntl(send_sock, F_SETOWN, getpid());
- int dum = 0, retran;
- while (1) {
- memset(recvbuf, 0, MAX_BUF);
- if(work_to_do == 1){
- if ((val = recvfrom(send_sock, recvbuf, MAX_BUF, 0, (struct sockaddr *) &from_addr, &from_addr_len)) > 0) {
- work_to_do = 0;
- //printf("Here000\n");
- if (val == 1) {
- eot_flag = 1;
- break;
- }
- //Update holes upon any packet reception (except EOT)
- c_rcv++;
- printf("cum recv %d\t", c_rcv);
- holes--;
- char *temp_unravel;
- char *s_et = strtok_r(recvbuf, "$", &temp_unravel);
- seq_no = atoi(s_et);
- printf("(n, s) (%d, %d)\n", n_excpt, seq_no);
- if (n_excpt < seq_no) {
- //It's a hole, retransmission requests to be sent from n_excpt to & including seq_no
- retran = n_excpt;
- true_h += (seq_no - n_excpt);
- printf("Holes detected %d ##########\n", seq_no - retran);
- n_excpt = seq_no + 1;
- //fork child to retransmit -ve acks so that you may not lose packets being sent in that time
- if(!fork()){
- while (seq_no > retran) {
- memset(nack, 0, 25);
- printf("Sendin nack %d\n", retran);
- sprintf(nack, "$N$%d$", retran++);
- //send from different socket
- if ((val = sendto(sock_ack, nack, strlen(nack), 0, (struct sockaddr *) &from_addr, from_addr_len))== -1) {
- perror("Send to nack: forwarding");
- exit(1);
- }
- }
- printf("Exiting child ######\n");
- exit(0);
- }
- }
- else if (n_excpt > seq_no) {
- //hole being filled
- memset(pckt_book[(seq_no%CACHE_SZ)].h_exist, 0, sizeof(int));
- true_h--;
- }
- else {
- n_excpt++;
- }
- // printf("Here111\n");
- buf_ind = seq_no % CACHE_SZ;
- p_len = val - (strlen(s_et) + 2);
- memcpy(pckt_book[buf_ind].seq_id, &(seq_no), sizeof(seq_no));
- memcpy(pckt_book[buf_ind].paylen, &(p_len), sizeof(p_len));
- memcpy(pckt_book[buf_ind].payload, temp_unravel, p_len);
- memset(pckt_book[buf_ind].h_exist, 0, sizeof(int));
- bytes_read += val;
- if (holes == 0) {
- printf("true_h must 0, is %d\t \n", true_h);
- int v_wrt = 0;
- for (f_in = 0; f_in < CACHE_SZ; f_in++) {
- if ((val = write(fd, pckt_book[f_in].payload, *(pckt_book[f_in].paylen))) < 0) {
- perror("write error\n");
- exit(1);
- }
- v_wrt += val;
- }
- printf("$$$$$$$$$$$$$written all %d$$$$$$$$$$$$$$$$\n", v_wrt);
- if (eot_flag == 1) {
- //All work done
- break;
- }
- else {
- //reset buffer
- for(j = 0; j< CACHE_SZ; j++) {
- memset(pckt_book[j].seq_id, 0, sizeof(int));
- memset(pckt_book[j].paylen, 0, sizeof(int));
- memset(pckt_book[j].h_exist, 1, sizeof(int));
- memset(pckt_book[j].payload, 0, MAX_LOAD);
- }
- holes = CACHE_SZ;
- if ((val = sendto(send_sock, p_ack, strlen(p_ack), 0, (struct sockaddr *) &from_addr, from_addr_len)) == -1) {
- perror("Send to nack: forwarding");
- exit(1);
- }
- printf("sent p_ack %s\n", p_ack);
- }
- }
- else if (eot_flag == 1 && (true_h == 0)) {
- for (f_in = 0; f_in < (n_excpt%CACHE_SZ); f_in++) {
- write(fd, pckt_book[f_in].payload, *(pckt_book[f_in].paylen));
- }
- }
- //printf("in3\n");
- //printf("Wfn %d; holes %d true_h %d \n", n_excpt, holes, true_h);
- memset(recvbuf, 0, MAX_BUF);
- // printf("Her3333\n");
- }
- }
- if(true_h > 0){
- //Send negative acks again for the first hole
- if(!fork()){
- for(j = 0; j< CACHE_SZ; j++) {
- if(*(pckt_book[j].h_exist) == 1){
- int quo = (int)n_excpt/CACHE_SZ;
- memset(nack, 0, 25);
- printf("Extra nack %d\n", quo + j);
- sprintf(nack, "$N$%d$", (quo + j));
- //send from different socket
- if ((val = sendto(sock_ack, nack, strlen(nack), 0, (struct sockaddr *) &from_addr, from_addr_len))== -1) {
- perror("Send to nack: forwarding");
- exit(1);
- }
- break;
- }
- }
- exit(0);
- }
- }
- // if(eot_flag && !holes){
- // for (f_in = 0; f_in < CACHE_SZ; f_in++) {
- // if ((val = write(fd, pckt_book[f_in].payload, *(pckt_book[f_in].paylen))) < 0) {
- // perror("write error\n");
- // exit(1);
- // }
- // }
- // break;
- // }
- if(eot_flag && (true_h == 0)){
- for (f_in = 0; f_in < (n_excpt%CACHE_SZ); f_in++) {
- write(fd, pckt_book[f_in].payload, *(pckt_book[f_in].paylen));
- }
- break;
- }
- }
- close(fd);
- if ((val = sendto(send_sock, all_ack, strlen(all_ack), 0, (struct sockaddr *) &from_addr, from_addr_len)) == -1) {
- perror("Send to all_ack: forwarding");
- exit(1);
- }
- //noting ending time
- if (gettimeofday(&tv2, NULL) == -1) {
- exit(1);
- }
- char cmd_to_exec[MAX_BUF];
- //Checking content of files
- sprintf(cmd_to_exec, "cmp %s %s && echo 'SUCCESS, FILES MATCH' || echo 'FILES DO NOT MATCH'", r_filename, f_name);
- system(cmd_to_exec);
- //seconds to milliseconds
- time_elapsed = (tv2.tv_sec - tv1.tv_sec) * 1000.0;
- //micro to milliseconds
- time_elapsed += (tv2.tv_usec - tv1.tv_usec) / 1000.0;
- printf("Last seq: %d\n", seq_no);
- printf("Completion time: %ld msec\n", time_elapsed);
- printf("Bytes downloaded: %ld\n", bytes_read);
- printf("Throughput: %f KBps\n", (float)bytes_read/time_elapsed);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement