UDP file transfer

This is a discussion on UDP file transfer within the Networking/Device Communication forums, part of the General Programming Boards category; Hello everyone. I'm implementing a UDP file transfer. I was able to run this program yesterday, but after restarting my ...

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    9

    UDP file transfer

    Hello everyone.

    I'm implementing a UDP file transfer. I was able to run this program yesterday, but after restarting my machine, the client program seems to loop infinitely on a certain part, specifically at rcvfrom(). I've ran wireshark and it says that the port that I'm using is unreachable. I tried using another port but it still doesn't work. I was able to run it again when I accidentally overflowed something after running another program(command line has trash characters suddenly appearing). And today, it doesn't seem to receive data again.

    What can possibly cause this error?

    The source codes can be found here:
    sender(client): sender7.c - 4shared.com - online file sharing and storage - download

    receiver(server):
    rcv4.c - 4shared.com - online file sharing and storage - download

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You should post your code here. I don't think many people are going to sign up at 4shared just so they can download and debug something for you.

    Remember to use code tags, and if you cut and paste from an application that adds mark-up by default, change it to plain text first.

    http://cboard.cprogramming.com/netwo...ead-first.html

    I was able to run it again when I accidentally overflowed something after running another program(command line has trash characters suddenly appearing).
    That is probably coincidence.
    Last edited by MK27; 04-04-2012 at 05:32 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    9
    Oh, sorry about that. I didn't know about the Code thing. So here it is:

    by the way, for the client these are some of the flags that might be worth mentioning:
    -f <filename> is the file you want to send
    -c <chunksize> is the size of the file per datagram sent
    -r ipaddressort

    and for the server:
    -f <filename> is the name that you want to give to the received file

    Client:
    Code:
    /* code for CoE 151 MP2 by RhayneX
    THIS IS THE WORKING CODE~!!
    compile using:
    
    
    gcc sender7.c -o sender7 -lm -Wall -lpthread 
    
    
    run using:
    
    
    ./sender7 -f slowstart.png -c 2000 -i 100 -d 100 -t 100 -vv -r 192.168.1.102:15151
    
    
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <time.h>
    #include <sys/time.h>
    #include <signal.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <pthread.h>
    #include <math.h>
    #define MYPORT "15151"
    
    
    struct flist{                //linked list for file chunk
            char *chunk;            //file segment
            int chunksize;            //size of chunk of this node
            int isn;            //segment number of packet
            int res;
            int last;
            int acked;
            struct flist *next;        //pointer to the next node
        };
        typedef struct flist Flist;    
        Flist *fileparse = NULL;        //define pointer of struct flist
    
    
        char filename[32];
        int chunksize;
        int isn;
        int timeout;
        int delay;
        int v_flag = 0;
        int vv_flag = 0;
        char rcv_ipadd[17];        //ip address of receiver    
        int rcv_port;            //int value of receive port
        char rcv_port_str[6];        //port number used by the receiver in string format
        int cwindow = 1;
        int rcv_ack;
        int rcv_ack;
        int ack_max;
        int syn_ack_received = 0;
        int sent_last = 0;
    
    
        //declare sender variables
        int broadcast = 1;
        int sockfd;
        struct addrinfo hints, *servinfo;    //structs for getaddrinfo
        struct sockaddr_in their_addr;         // connector's address information
        struct hostent *he;
        int numbytes;
        int retval;
        int lost = 0;
        time_t now;
    
    
    
    
    void make_seqnum(int seqnum, char seqbuf[]);
    void make_packet(int flag, char seqbuf[], void *chunkbuf, char *packet, int chunksize);
    int parsechunk(char *buf, char *buf2,int datasent,int seq_val, char flag[]);
    void update_ackflag(int rcv_ack_local, Flist *sPtr, int lost);
    void listener(int lost);
    
    
    void inserttolist(Flist *sPtr, int chunksize, int isn, char *buffer, int last, int res, int modulo){
        while(sPtr->next != NULL){        
                sPtr = sPtr->next;                    //find end of list
                    
            }
            sPtr->next = (struct flist *)malloc(sizeof(struct flist));    //allocate memory for node
            sPtr->next-> res = res;
            sPtr->next->chunksize = chunksize;                //size of the chunk pointed by sptr->chunk
            sPtr->next->isn = isn;                        //segment number of this chunk
            sPtr->next->next = NULL;
            sPtr->next->acked = 0;
            if(last == 0){
                sPtr->next->last = 0;
                sPtr->next->chunk = (char *)malloc(sizeof(char)*chunksize);        //set sptr->chunk to point to the actual chunk        
                memcpy(sPtr->next->chunk,buffer,chunksize);
            }
            else{
                sPtr->next->last = 1;
                sPtr->next->chunk = (char *)malloc(sizeof(char)*modulo);        //set sptr->chunk to point to the actual chunk
                memcpy(sPtr->next->chunk,buffer,modulo);
            }
    }
    
    
    void parse_file(Flist* sPtr, int chunksize, int isn, char filename[]){                
        FILE *ptr;                //file pointer
        char *buffer1, *buffer2;                //pointer to memory holding each chunk
        int filesize;                //size of file to be sent
        int quotient;                //counter for f
        int modulo;
        size_t res;                //for fread
        int counter = 0;                //just a counter
        
        /*open file*/
        if ((ptr = fopen(filename, "r+b")) == NULL)            //if file cannot be opened..
        {
            printf("File open error\n");
            goto end;
        }
        else{
        /*obtain file size*/
        fseek (ptr , 0 , SEEK_END);
          filesize = ftell (ptr);
         rewind (ptr);
        }
        /*obtain number of chunks to be made*/
        if(filesize<chunksize){
            printf("File size is too small for chunk\n");
            quotient = 0;
            modulo = filesize;
            goto start;
        }
        quotient = filesize/chunksize;
        modulo = filesize%chunksize;
            printf("Modulo is %i\n",modulo);
        start:
        buffer1 = (char *)malloc(sizeof(char)*chunksize);        //allocate memory for chunk
        buffer2 = (char *)malloc(sizeof(char)*modulo);        //allocate memory for chunk
        /*start getting the chunks*/
        while(1){
            if(counter!=quotient){
                memset(buffer1,0,chunksize);
                if(buffer1 == NULL){
                    printf("Allocation failed\n");
                    goto end;
                }
                res = fread(buffer1,sizeof(char),chunksize,ptr);    //get the chunk from file pointer
                  if (res != chunksize){
                    goto end;
                }
                inserttolist(sPtr,res,isn,buffer1,0,res,modulo);
                counter++;                        //increment counter
                isn = isn + res;                            //increment segment number
                
            }
            else if((counter == quotient) && (modulo != 0)){
                memset(buffer2,0,modulo);
                if(buffer2 == NULL){
                    printf("Allocation failed\n");
                    goto end;
                }
                res = fread (buffer2,sizeof(char),modulo,ptr);    //get the chunk from file pointer
                inserttolist(sPtr,res,isn,buffer2,1, res,modulo);
                break;
            }
        }
        end:
        fclose(ptr);
            
    }
    
    
    void parse_cmdline(int argc, char *argv[]){
        int i = 1;                //counter for command line; counter for ip:port
        int y = 0;                 //counter for ip:port
        char c;
        char ip_portbuff[23];
        memset(ip_portbuff,0,23);
        if((argc == 1)||(argc == 2)){
                printf("Wrong parameter(s)\n");
           }
           while(argc>1){            //This loop gets the parameters needed in the program
                if(!strcmp(argv[i],"-f"))
                        strcpy(filename,argv[i+1]); 
                else if(!strcmp(argv[i],"-c"))
                        chunksize = atoi(argv[i+1]);
            else if(!strcmp(argv[i],"-i"))
                isn = atoi(argv[i+1]);
                else if(!strcmp(argv[i],"-t")){
                       timeout = atoi(argv[i+1]);
            }
                else if(!strcmp(argv[i],"-d")){
                        delay = atoi(argv[i+1]);
            }
            else if(!strcmp(argv[i],"-r"))
                        strcpy(ip_portbuff,argv[i+1]);
            else if(!strcmp(argv[i],"-v"))
                        v_flag = 1;
            else if(!strcmp(argv[i],"-vv"))
                        vv_flag = 1;
                    argc-=1;
                    i++;
            }
        int x = 0;
        c = ip_portbuff[x];                //get ip address
        while(c != ':'){
            rcv_ipadd[x] = c;        
            x++;
            c = ip_portbuff[x];
        }
        rcv_ipadd[x] = '\0';
        x++;
        c = ip_portbuff[x];
    
    
        while(c!='\0'){                    //get port
            rcv_port_str[y] = c;
            x++;
            y++;
            c = ip_portbuff[x];
        }
        rcv_port = atoi(rcv_port_str);
        //printf("Done getting program parameters.\n\n\n");
        //printf("filename is: %s\n chunksize is %i\n isn is %i\n timeout is %i\n delay is %i\n vflag is %i\n vvflag is %i\n ip_add is %s\n port is %i\n", filename, chunksize, isn, timeout, delay, v_flag, vv_flag, rcv_ipadd, rcv_port);
    }
    
    
    void send_syn(){
        
        char *buffer = NULL;
        char seqbuff[33];
        memset(seqbuff,0,33);
        buffer = (char *)malloc(sizeof(char)*chunksize);
        //sending syn
        
        while(syn_ack_received != 1){
            puts("Sending syn packet..");
            make_seqnum(isn,seqbuff);
            make_packet(1, seqbuff, buffer, buffer, chunksize);
            numbytes = sendto(sockfd, buffer, 32+35, 0, (struct sockaddr *)&their_addr, sizeof their_addr);    //send datagram
        //    printf("sent:%s\n",buffer);
            //    numbytes = sendto(sockfd, buffer, sPtr->chunksize, 0, (struct sockaddr *)&their_addr, sizeof their_addr);
            usleep(delay*1000);
            memset(seqbuff,0,33);
            memset(buffer,0,chunksize);
        }
        free(buffer);
    }
    
    
    void send_data(Flist *sPtr){
        
        int x = 0;
        int cwintemp = 0;
        char *buffer = NULL;
        char seqbuff[33];
        memset(seqbuff,0,33);
        buffer = (char *)malloc(sizeof(char)*chunksize);
    
    
        puts("Sending data packets..");
        //puts("wo");
        //start:
        while(sPtr->next != NULL){                        //find first node to send
            if(sPtr->acked == 1 || x == 0){            //node already acked, go to next node
            //    printf("acked isn:%i\n",sPtr->isn);
                sPtr = sPtr->next;
                x++;
            }
            else    {
            //    printf("not acked isn:%i\n",sPtr->isn);            //first unacked node found
                break;
            }
        }
    
    
        while(sPtr->last != 1){
            while(cwintemp != cwindow && lost != 1 && sPtr->last != 1) {            
                if(x != 0){
                    //sending first data packet
                    make_seqnum(sPtr->isn,seqbuff);
                    make_packet(2, seqbuff, sPtr->chunk, buffer, sPtr->chunksize);
                    if(vv_flag == 1){
                        time(&now);
                          printf("%s", ctime(&now));
                        printf("Data with seq num %i sent\n\n",sPtr->isn);
                    }
                    numbytes = sendto(sockfd, buffer, sPtr->chunksize+35, 0, (struct sockaddr *)&their_addr, sizeof their_addr);    //send datagram
                //    printf("sent:%s\n",buffer);
                    usleep((delay*1000)/cwindow);
                    memset(seqbuff,0,33);
                    memset(buffer,0,chunksize);
                    cwintemp++;
                //    printf("cwintemp is %i\ncwindow is %i\n", cwintemp, cwindow);
                }        
                sPtr = sPtr->next;
                x++;
                if(vv_flag == 1){
                //    printf("Cwin is %i temp is%i lost is%i\n",cwindow,cwintemp,lost);
                    printf("Congestion window is %i\n",cwindow);
                }    
            }
            break;
        }
        if(sPtr->last == 1 && cwintemp != cwindow && lost != 1){        
        //send last data packet
            puts("Sending last data packet and fin");
            make_seqnum(sPtr->isn,seqbuff);
            make_packet(3, seqbuff, sPtr->chunk, buffer, sPtr->chunksize);
            if(vv_flag == 1){
                time(&now);
                  printf("%s", ctime(&now));
                printf("Data with seq num %i sent\n\n",sPtr->isn);
            }
            numbytes = sendto(sockfd, buffer, sPtr->chunksize+35, 0, (struct sockaddr *)&their_addr, sizeof their_addr);    //send datagram
        //    printf("sent:%s\n",buffer);
            usleep(delay*1000);
            memset(seqbuff,0,33);
            memset(buffer,0,chunksize);
            goto end;
        }
        usleep(timeout*1000/cwindow);
    //    printf("a:%i",sPtr->isn);
        ack_max = sPtr->isn;
    //    printf("ack_max:%i, rcv_ack:%i",ack_max,rcv_ack);
        if(ack_max != rcv_ack){
            lost = 1;
        }
        if(lost == 1){
            cwindow = 1;    
            lost = 0;
        }
        else if(sPtr->last != 1){        //assume no loss..
            cwindow = cwindow*2;
        }
        end:
            puts(" ");
    }
    
    
    void make_seqnum(int seqnum, char seqbuf[]){
        int x,y;
        char temp_inv[32];
        memset(temp_inv,0,32);
        x = 0;
        while(seqnum>1){            //convert to binary, inverted
            if(seqnum%2 == 1){
                temp_inv[x] = '1';
            }
            else{
                temp_inv[x] = '0';
            }
            seqnum = seqnum/2;
            x++;
        }
        if(seqnum == 1){
            temp_inv[x] = '1';
        }
        else{
            temp_inv[x] = '0';
        }
        x++;
        while(x != 31){
            temp_inv[x] = '0';
            x++;
        }
        temp_inv[x] = '0';
        x = 31;
        y = 0;
        while(x != 0){
            seqbuf[y] = temp_inv[x];
            y++;
            x--;
        }
        seqbuf[y] = temp_inv[x];
        y++;
        seqbuf[y] = '\0';
    }
    
    
    void make_packet(int flag, char seqbuf[], void *chunkbuf, char *packet, int chunksize){
        int x, y;
        x = 0;
        y = 0;
        char chunksize_str[32];
        memset(chunksize_str,0,32);
        sprintf(chunksize_str,"%i",chunksize);
        if(flag == 1){            //make syn packet
            packet[0] = '1';
            packet[1] = '0';
            packet[2] = '0';
            y = 3;
            x = 0;
            while(x != 32){
                packet[y] = seqbuf[x];
                y++;
                x++;
            }
            memcpy(packet+35,chunksize_str,32);
        }
            if(flag == 2){            //make data packet
            packet[0] = '0';
            packet[1] = '0';
            packet[2] = '0';
            y = 3;
            x = 0;
            while(x != 32){
                packet[y] = seqbuf[x];
                y++;
                x++;
            }
            memcpy(packet+35,chunkbuf,chunksize);
        }
    
    
            if(flag == 3){            //make data packet
            packet[0] = '0';
            packet[1] = '0';
            packet[2] = '1';
            y = 3;
            x = 0;
            while(x != 32){
                packet[y] = seqbuf[x];
                y++;
                x++;
            }
            memcpy(packet+35,chunkbuf,chunksize);
        }
    }
    
    
    void listener(int lost){
    //VARIABLES:
        int sockfd;                //used for sockets
        struct addrinfo hints, *servinfo, *p;    //structs for getaddrinfo
        int retval;                //used for getaddrinfo    
        int datasent;                //return value of data sent
        struct sockaddr_storage addr;    
        socklen_t addr_len;            //for sockets    
        int yes = 1;                //for sockopt
        char flags[4];
    
    
    //set these values first
        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_flags = AI_PASSIVE; // use my IP
        retval = getaddrinfo(NULL, MYPORT, &hints, &servinfo);    //check if getaddr is successful
        for(p = servinfo; p != NULL; p = p->ai_next) {        // loop through all the results and bind to the first we can
            if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
    //            perror("listener: socket");
                continue;
            }
    
    
            if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {     //fix for address in use
    //            perror("setsockopt");
            }
    
    
            if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
                close(sockfd);
                continue;
            }
            break;
        }        //end for loop
        if (p == NULL) {                        //socket unable to bind
            printf("listener: failed to bind socket\n");
        }
        freeaddrinfo(servinfo);        //serveinfo already done; clean it                    
        addr_len = sizeof(addr);
    
    
    
    
                        //start listening to port
        char *buf, *buf2;            //max length of message buffer
        int fin = 0;
        char temp[32+35],temp2[32];
        memset(temp,0,32+35);
        memset(temp2,0,32);
        printf("syn_ack:%i\n",syn_ack_received);
        while(syn_ack_received != 1){        //wait for syn packet
            datasent = recvfrom(sockfd, temp, 32+35, 0, (struct sockaddr *)&addr, &addr_len);
            printf("%s\n",temp);
            rcv_ack = parsechunk(temp,temp2,datasent,rcv_ack,flags);
            if(!strcmp(flags,"110")){
                syn_ack_received = 1;
                puts("syn ack packet received");
            }
        }
        //wait for data
        flags[0] = '0';
        flags[1] = '0';
        flags[2] = '0';
        flags[3] = '\0';
        //printf("%s\n",flags);
        buf = (char *)malloc(sizeof(char)*chunksize+35);
        buf2 = (char *)malloc(sizeof(char)*chunksize);
        printf("Receiving data ack..\n");
        while (fin != 1){
            datasent = recvfrom(sockfd, buf, chunksize+35, 0, (struct sockaddr *)&addr, &addr_len);
        //    printf("%s\n",buf);
            rcv_ack = parsechunk(buf,buf2,datasent,rcv_ack, flags);
                if(!strcmp(flags,"010")){
                    if(vv_flag == 1){
                        printf("Ack for Seq: %i received\n", rcv_ack - chunksize);
                        
                    }
                    update_ackflag(rcv_ack-chunksize,fileparse,lost);
                    memset(buf,0,chunksize+35);
                    memset(buf2,0,chunksize);
                }
                else if(!strcmp(flags,"011")){
                    if(vv_flag == 1){
                        printf("Ack for Seq: %i received\n", rcv_ack - chunksize);
                        
                    }
                    update_ackflag(rcv_ack-chunksize,fileparse,lost);
                    memset(buf,0,chunksize+35);
                    memset(buf2,0,chunksize);
                    sent_last = 1;
                    fin = 1;
                }
                else if(!strcmp(flags,"110")){
                    memset(buf,0,chunksize+35);
                    memset(buf2,0,chunksize);
                    puts("duplicate syn received");
                }
        }
        puts("FIN ack received");
        close(sockfd);                //close the socket
    }
    
    
    int parsechunk(char *buf, char *buf2,int datasent,int seq_val, char flag[]){
        int x, y, seqnum_int;
        char seqnum[1];
        flag[0] = buf[0];
        flag[1] = buf[1];
        flag[2] = buf[2];
        flag[3] = '\0';
        
        x = 31;
        y = 3;
        seqnum_int = 0;
        while(x!=0){
            seqnum[0] = buf[y];
            if(seqnum[0] == '1'){
                seqnum_int = seqnum_int + pow(2,x);
            }
            x--;
            y++;
        }
        seqnum[0] = buf[y];
        if(seqnum[0] == '1'){
            seqnum_int = seqnum_int + pow(2,x);
        }
        seq_val = seqnum_int;
        memcpy(buf2,buf+35,datasent-35);
        return seq_val;
    }
    
    
    //FOR TEST
    void make_file(Flist *sPtr, char filename[]){                
        FILE *ptr;                //file pointer
        int filesize = 0;            //size of file received
        int x = 0;                //just a counter
        
        if ((ptr = fopen(filename, "w+b")) == NULL)            //if file cannot be opened..
        {
            printf("File not found\n");
            goto end;
        }
        else{    
            while(sPtr->next != NULL) {            //loop to write to list    until the 2nd to the last element
                if(x != 0){
                    fwrite(sPtr->chunk, sPtr->chunksize, sizeof(char),ptr);
                    filesize = filesize + sPtr->chunksize;
                }        
                sPtr = sPtr->next;
                x++;    
            }
        }    
        fwrite(sPtr->chunk, sPtr->chunksize, sizeof(char),ptr);
        filesize = filesize + sPtr->chunksize;
        printf("Filesize is: %i bytes\n", filesize);
        end:
        fclose(ptr);                        //close file pointer
    
    
        
    }
    //END OF FOR TEST
    void update_ackflag(int rcv_ack_local, Flist *sPtr, int lost){
        sPtr = sPtr->next;
        printf("rcv_ack:%i,sPtr->isn:%i\n",rcv_ack_local, sPtr->isn);
        while(sPtr->last != 1){
            if(sPtr->acked == 1){
                sPtr = sPtr->next;
            }
                
            else if(sPtr->acked == 0){
                break;
            }
        }
        //printf("UPDATEING ACK FLAG:rcv_ack:%i,sPtr->isn:%i\n",rcv_ack_local, sPtr->isn);
        if(sPtr->isn == rcv_ack_local && sPtr->last != 1){
            printf("isn:%i\n",sPtr->isn);
            sPtr->acked = 1;
            puts("Updated!");
        }
        else if(sPtr->isn == rcv_ack_local && sPtr->last == 1){
            printf("isn:%i\n",sPtr->isn);
            puts("Last packet Updated");
            sPtr->acked = 1;
        }
        else{
            if(vv_flag == 1){
                printf("Ack for Seq: %i lost\n", sPtr->isn);    
            }
            lost = 1;
        }    
    }
    
    
    
    
    int main(int argc, char *argv[]){
        pthread_t ackthread;    
        int ack_ret = 0;
        fileparse = (struct flist *)malloc(sizeof(struct flist));
        ack_ret = pthread_create(&ackthread, NULL, (void *)listener,(void *)lost);
        parse_cmdline(argc,argv);
    
    
        //set sender variables
            //set sender variables
        retval = getaddrinfo(NULL, rcv_ipadd, &hints, &servinfo);
        he=gethostbyname(rcv_ipadd);
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
        their_addr.sin_family = AF_INET;             // host byte order
        their_addr.sin_port = htons(rcv_port);             // short, network byte order
        their_addr.sin_addr = *((struct in_addr *)he->h_addr);
        memset(their_addr.sin_zero, '\0', sizeof(their_addr.sin_zero));
    
    
        parse_file(fileparse, chunksize, isn,filename);
        
        send_syn();
    
    
        while(sent_last != 1){
            send_data(fileparse);
        
        }
    
    
        printf("Done\n");
        pthread_kill(ackthread, ack_ret);
        close(sockfd);
        return 0;
    }
    and for the server(receiver):

    Code:
    /*MP02 for CoE 151 created by RhayneX 
    This will contain the networking codes and threading codes
    Compile using:
    
    
    gcc -lpthread -lm -Wall rcv4.c -o rcv
    
    
    run using:
    
    
    ./rcv -f hello.png -v -r 15151 -l 0
    
    
    */
    
    
    //declaration of libraries
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <pthread.h>
    #include <math.h>
    #define MYPORT "15151"
    
    
    struct flist{                //linked list for file chunk
        char *chunk;            //file segment
        int chunksize;            //size of chunk of this node
        int isn;            //segment number of packet
        struct flist *next;        //pointer to the next node
    };
    typedef struct flist Flist;    
    Flist *filechunks = NULL;    
    
    
        int listnotempty = 0;
        int isn_rcv;
        int modulo;
        int fin_rcv;
        int probability;
        int v;
        int vv;
        int port;
        char *myport;
        char filename[32];
        
        //Initialize network variables
        //For listener
        int sockfd;                //used for sockets
        struct addrinfo hints, *servinfo, *p;    //structs for getaddrinfo
        int retval;                //used for getaddrinfo    
        int datasent;                //return value of data sent
        struct sockaddr_storage addr;    
        socklen_t addr_len;            //for sockets    
        int yes = 1;                //for sockopt
        //For sender
        int broadcast = 1;
        struct addrinfo hints, *servinfo;    //structs for getaddrinfo
        struct sockaddr_in their_addr;         // connector's address information
        struct hostent *he;
        int numbytes;
        int retval2;
        int sockfd2;
        char s[INET6_ADDRSTRLEN];
        
    int parsechunk(char *buf, char *buf2, int datasent, int seq_val, char flag[]);
    int cointoss(int a);
    void set_send();
    void make_seqnum(int seqnum, char seqbuf[]);
    void make_packet(int flag, char seqbuf[], void *chunkbuf, char *packet, int chunksize);
    
    
    void inserttolist_rcv(Flist *sPtr, int chunksize, int isn, Flist *buffer){
                            
        while (sPtr->next != NULL) {
            sPtr = sPtr->next;    
        } 
        if(isn_rcv == buffer->isn && listnotempty == 0){
            puts("First node inserted");
            sPtr->next = buffer;
            listnotempty = 1;
        }
        else if(fin_rcv == 1 && listnotempty == 1){
            puts("last packet");
            sPtr->next = buffer;
            fin_rcv = 0;
        }
        else if(sPtr->isn + chunksize == buffer->isn && listnotempty == 1){
            sPtr->next = buffer;
        }
    }
    
    
    void make_file(Flist *sPtr, char filename[]){                
        FILE *ptr;                //file pointer
        int filesize = 0;            //size of file received
        int x = 0;                //just a counter
        
        if ((ptr = fopen(filename, "w+b")) == NULL)            //if file cannot be opened..
        {
            printf("File not found\n");
            goto end;
        }
        else{    
            while(sPtr->next != NULL) {            //loop to write to list    until the 2nd to the last element
                if(x != 0){
                    fwrite(sPtr->chunk, sPtr->chunksize, sizeof(char),ptr);
                    filesize = filesize + sPtr->chunksize;
                }        
                sPtr = sPtr->next;
                x++;    
            }
        }    
        fwrite(sPtr->chunk, sPtr->chunksize, sizeof(char),ptr);
        filesize = filesize + sPtr->chunksize;
        end:
        fclose(ptr);                        //close file pointer
    
    
        
    }
    
    
    void make_chunk(Flist *sPtr, int isn, int chunksize, char *buff_chunk){
        char *buffer;                //pointer to memory holding each chunk
        Flist *node;                //file checking
            node = (struct flist *)malloc(sizeof(struct flist));        //allocate memory for node
            if(node == NULL){
                printf("Allocation of node failed\n");
            }
            buffer = (char *)malloc(sizeof(char)*chunksize);        //allocate memory for chunk
            memcpy(buffer,buff_chunk,chunksize);                    //buff chunk is the buffer for file chunk
            if(buffer == NULL){
                printf("Allocation of buffer failed\n");
            }
            node->chunk = buffer;                        //assign values for node
            node->isn = isn;
            node->next = NULL;
            if(modulo == 0){
                inserttolist_rcv(sPtr, chunksize, node->isn, node);
                node->chunksize = chunksize;
                modulo = 0;
            }
            else{
                inserttolist_rcv(sPtr, modulo, node->isn, node);
                node->chunksize = modulo;
                modulo = 0;
            }
        
    }
    
    
    void listener(){
    //VARIABLES:
        
        int syn_received = 0;
        int chunksize;
        int isn;
        int prob;
        char flags[4];
    
    
    //set these values first
                        //start listening to port
        char *buf, *buf2;            //max length of message buffer
        int seq_val = 0;
        int fin = 0;
        char temp[32+35],temp2[32];
        char seq_num[33];
        memset(seq_num,0,33);
        memset(temp,0,32+35);
        memset(temp2,0,32);
        
        while(syn_received != 1){        //wait for syn packet
            datasent = recvfrom(sockfd, temp, 32+35, 0, (struct sockaddr *)&addr, &addr_len);
        //    printf("rcv:%s\n",temp);
            set_send();
            //JUST TEST
            isn = parsechunk(temp,temp2,datasent,isn,flags);
            chunksize = atoi(temp2);
            if(!strcmp(flags,"100")){
                syn_received = 1;
                isn_rcv = isn;
                puts("Syn packet received\n");
                memset(temp,0,32+35);
                make_seqnum(isn,seq_num);
                make_packet(1,seq_num,temp,temp,chunksize);
                numbytes = sendto(sockfd2, temp, 32+35, 0, (struct sockaddr *)&their_addr, sizeof their_addr);    //send syn ack
                printf("%s\n",temp);        
            }
        }
        //wait for data
        flags[0] = '0';
        flags[1] = '0';
        flags[2] = '0';
        flags[3] = '\0';
        //printf("%s\n",flags);
        buf = (char *)malloc(sizeof(char)*chunksize+35);
        buf2 = (char *)malloc(sizeof(char)*chunksize);
        printf("Receiving data..\n");
        while (fin != 1){
            datasent = recvfrom(sockfd, buf, chunksize+35, 0, (struct sockaddr *)&addr, &addr_len);
            //printf("rcv:%s\n",temp);
            seq_val = parsechunk(buf,buf2,datasent,seq_val, flags);
            prob=cointoss(probability);
            if (prob == 1){
                if(!strcmp(flags,"000")){
                    if(v == 1 || vv == 1){
                        printf("Data with Seq: %i received\n", seq_val);
                    }
                    make_chunk(filechunks, seq_val, datasent-35, buf2);
                    memset(buf,0,chunksize+35);
                    memset(temp,0,32+35);
                    memset(buf2,0,chunksize);
                    memset(seq_num,0,33);
                    make_seqnum(seq_val+datasent-35,seq_num);
                    make_packet(2,seq_num,temp,temp,chunksize);
                    numbytes = sendto(sockfd2, temp, 32+35, 0, (struct sockaddr *)&their_addr, sizeof their_addr);    //send data ack
                //    printf("sent:%s\n",temp);
                }    
                else if(!strcmp(flags,"001")){
                    if(v == 1 || vv == 1){
                        printf("Data with Seq: %i received\n", seq_val);
                    }
                    modulo = datasent - 35;
                    fin_rcv = 1;
                    make_chunk(filechunks, seq_val, datasent, buf2);
                    memset(buf,0,chunksize+35);
                    memset(temp,0,32+35);
                    memset(buf2,0,chunksize);
                    fin = 1;
                    memset(seq_num,0,33);
                    make_seqnum(seq_val+chunksize,seq_num);
                    make_packet(3,seq_num,temp,temp,chunksize);
                    numbytes = sendto(sockfd2, temp, 32+35, 0, (struct sockaddr *)&their_addr, sizeof their_addr);    //send fin ack
                //    printf("sent:%s\n",temp);
                }    
                else if(!strcmp(flags,"100")){
                    memset(buf,0,chunksize+35);
                    memset(buf2,0,chunksize);
                    memset(temp,0,32+35);
                    make_seqnum(isn,seq_num);
                    make_packet(1,seq_num,temp,temp,chunksize);
                    numbytes = sendto(sockfd2, temp, 32+35, 0, (struct sockaddr *)&their_addr, sizeof their_addr);
                //    printf("sent:%s\n",temp);                
                    puts("duplicate syn received");
                }
            }
            else{
                seq_val = parsechunk(buf,buf2,datasent,seq_val, flags);
                printf("Dropped packet with seq num %d\n",seq_val);
            }
        }
        puts("FIN received");
        close(sockfd);                //close the socket
        
    
    
    }
    
    
    void make_seqnum(int seqnum, char seqbuf[]){
        int x,y;
        char temp_inv[32];
        memset(temp_inv,0,32);
        x = 0;
        while(seqnum>1){            //convert to binary, inverted
            if(seqnum%2 == 1){
                temp_inv[x] = '1';
            }
            else{
                temp_inv[x] = '0';
            }
            seqnum = seqnum/2;
            x++;
        }
        if(seqnum == 1){
            temp_inv[x] = '1';
        }
        else{
            temp_inv[x] = '0';
        }
        x++;
        while(x != 31){
            temp_inv[x] = '0';
            x++;
        }
        temp_inv[x] = '0';
        x = 31;
        y = 0;
        while(x != 0){
            seqbuf[y] = temp_inv[x];
            y++;
            x--;
        }
        seqbuf[y] = temp_inv[x];
        y++;
        seqbuf[y] = '\0';
    }
    
    
    int parsechunk(char *buf, char *buf2,int datasent,int seq_val, char flag[]){
        int x, y, seqnum_int;
        char seqnum[1];
        flag[0] = buf[0];
        flag[1] = buf[1];
        flag[2] = buf[2];
        flag[3] = '\0';
        
        x = 31;
        y = 3;
        seqnum_int = 0;
        while(x!=0){
            seqnum[0] = buf[y];
            if(seqnum[0] == '1'){
                seqnum_int = seqnum_int + pow(2,x);
            }
            x--;
            y++;
        }
        seqnum[0] = buf[y];
        if(seqnum[0] == '1'){
            seqnum_int = seqnum_int + pow(2,x);
        }
        seq_val = seqnum_int;
        memcpy(buf2,buf+35,datasent-35);
        return seq_val;
    }
    
    
    int cointoss(int a)
    {
        int c;
        int d,e;
        if (a==0){
        c=1;
        }
        srand ( time(NULL) ); //generate random number
        d = rand();    
        e= d%100;         //modulo number to 100
    //    printf("%d\n", e);
        if (e>a){    //dont drop if greater than a which is the probability to drop
        c=1;
        }
        else{
        c=0;          //drop if lesser than a
        }     
        return c;
    }
    
    
    void parse_cmdline(int argc, char *argv[]){
        int i = 1;                //counter for command line; counter for ip:port
        
        if((argc == 1)||(argc == 2)){
                printf("Wrong parameter(s)\n");
                goto end;
           }
           while(argc>1){            //This loop gets the parameters needed in the program
                if(!strcmp(argv[i],"-f"))
                        strcpy(filename,argv[i+1]); 
                else if(!strcmp(argv[i],"-l"))
                        probability = atoi(argv[i+1]);
            else if(!strcmp(argv[i],"-p")){
                myport = argv[i+1];
                port = atoi(argv[i+1]);
                }
            else if(!strcmp(argv[i],"-v"))
                        v = 1;
            else if(!strcmp(argv[i],"-vv")){
                        v=1;
                vv=1;
            }
                argc-=1;
                    i++;
            }
        filename[strlen(filename)] = '\0';
        end:
    //    printf("fname:%s\n prob:%d\n myport:%s %d\n v:%d\n vv:%d\n",filename,probability,myport,port,v,vv);    
        puts(" ");
    }
    
    
    void *get_in_addr(struct sockaddr *sa)
    {
        if (sa->sa_family == AF_INET) {
            return &(((struct sockaddr_in*)sa)->sin_addr);
        }
    
    
        return &(((struct sockaddr_in6*)sa)->sin6_addr);
    }
    
    
    void set_send(){
        retval2 = getaddrinfo(NULL, myport, &hints, &servinfo);
        inet_ntop(addr.ss_family,get_in_addr((struct sockaddr *)&addr), s, sizeof(s));
        he=gethostbyname(s);
        sockfd2 = socket(AF_INET, SOCK_DGRAM, 0);
        setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
        their_addr.sin_family = AF_INET;             // host byte order
        their_addr.sin_port = htons(port);             // short, network byte order
        their_addr.sin_addr = *((struct in_addr *)he->h_addr);
        memset(their_addr.sin_zero, '\0', sizeof(their_addr.sin_zero));
    }
    
    
    void make_packet(int flag, char seqbuf[], void *chunkbuf, char *packet, int chunksize){
        int x, y;
        x = 0;
        y = 0;
        char chunksize_str[32];
        memset(chunksize_str,0,32);
        sprintf(chunksize_str,"%i",chunksize);
        if(flag == 1){            //make syn packet
            packet[0] = '1';
            packet[1] = '1';
            packet[2] = '0';
            y = 3;
            x = 0;
            while(x != 32){
                packet[y] = seqbuf[x];
                y++;
                x++;
            }
            memcpy(packet+35,chunksize_str,32);
        }
            if(flag == 2){            //make data packet
            packet[0] = '0';
            packet[1] = '1';
            packet[2] = '0';
            y = 3;
            x = 0;
            while(x != 32){
                packet[y] = seqbuf[x];
                y++;
                x++;
            }
            memcpy(packet+35,chunkbuf,0);
        }
    
    
            if(flag == 3){            //make data packet
            packet[0] = '0';
            packet[1] = '1';
            packet[2] = '1';
            y = 3;
            x = 0;
            while(x != 32){
                packet[y] = seqbuf[x];
                y++;
                x++;
            }
            memcpy(packet+35,chunkbuf,0);
        }
    }
    
    
    int main(int argc, char *argv[]){
        //SET network variables    
        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_flags = AI_PASSIVE; // use my IP
        retval = getaddrinfo(NULL, MYPORT, &hints, &servinfo);    //check if getaddr is successful
        for(p = servinfo; p != NULL; p = p->ai_next) {        // loop through all the results and bind to the first we can
            if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
    //            perror("listener: socket");
                continue;
            }
    
    
            if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {     //fix for address in use
    //            perror("setsockopt");
            }
    
    
            if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
                close(sockfd);
                continue;
            }
            break;
        }        //end for loop
        if (p == NULL) {                        //socket unable to bind
            printf("listener: failed to bind socket\n");
        }
        freeaddrinfo(servinfo);        //serveinfo already done; clean it                    
        addr_len = sizeof(addr);
        // for send
        
        
    
    
    
    
    
    
        filechunks = (struct flist *)malloc(sizeof(struct flist));
        parse_cmdline(argc,argv);
        listener();
        make_file(filechunks, filename);
        return 0;
    }
    Last edited by rhayne; 04-04-2012 at 10:20 AM.

  4. #4
    Registered User
    Join Date
    Apr 2012
    Posts
    9
    sorry for some if there are some commented printf in there, i use that to debug the thing somehow.

  5. #5
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,659
    Here's a list of things to do before trying to get people to read 1000+ lines of code.

    1. Indentation
    SourceForge.net: Indentation - cpwiki
    Unless it's perfect for this amount of code, nobody is going to give a damn

    2. magic numbers
    Replace all those 32 and 35 (and whatever) with meaningful constants like
    #define HEADER_LENGTH 35
    #define PACKET_LENGTH 32

    3. srand ( time(NULL) ); //generate random number
    Call this exactly ONCE at the start of main.
    In a loop, time() returns a constant, which means your next call(s) to rand() are going to return the SAME values as well.

    4. I'm guessing you're running this on linux, so the first thing to try is
    valgrind ./rcv -f hello.png -v -r 15151 -l 0
    and see how much it complains about out of bound memory accesses, and accesses to uninitialised variables.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  6. #6
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Quit with all the globals. Ideally, you shouldn't have any. But that huge list is terrible practice.

  7. #7
    Registered User
    Join Date
    Apr 2012
    Posts
    9
    Thanks for the replies. I've done the things you guys have said. Just a quick question though, Am I making doing this part of the code right? This is for the setup of the rcvfrom by the way.

    Code:
    void listener(int lost){//VARIABLES:
    	int sockfd;				
    	struct addrinfo hints, *servinfo, *p;	
    	int retval;				
    	int datasent;			
    	struct sockaddr_storage addr;	
    	socklen_t addr_len;				
    	int yes = 1;				
    	
    
    
    //set these values first
    	memset(&hints, 0, sizeof hints);
    	hints.ai_family = AF_UNSPEC; 
    	hints.ai_socktype = SOCK_DGRAM;
    	hints.ai_flags = AI_PASSIVE; 
    	retval = getaddrinfo(NULL, MYPORT, &hints, &servinfo);	
    	for(p = servinfo; p != NULL; p = p->ai_next) {		// loop through all the results and bind to the first we can
    		if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
    //			perror("listener: socket");
    			continue;
    		}
    
    
    		if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { 	//fix for address in use
    //			perror("setsockopt");
    		}
    
    
    		if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
    		//	close(sockfd);
    			continue;
    		}
    		break;
    	}		//end for loop
    	if (p == NULL) {						//socket unable to bind
    		printf("listener: failed to bind socket\n");
    	}
    	freeaddrinfo(servinfo);							
    	addr_len = sizeof(addr);	
    
    
    	char *buf, *buf2;			
    	int fin = 0;
    	char flags[FLAG_LEN];
    	char temp[HEADER_LEN+PAYLOAD_LEN],temp2[PAYLOAD_LEN];
    	memset(temp,0,HEADER_LEN+PAYLOAD_LEN);
    	memset(temp2,0,PAYLOAD_LEN);
    	printf("syn_ack:%i\n",syn_ack_received);
    	while(syn_ack_received != 1){	
    		datasent = recvfrom(sockfd, temp, HEADER_LEN+PAYLOAD_LEN, 0, (struct sockaddr *)&addr, &addr_len);
    		rcv_ack = parsechunk(temp,temp2,datasent,rcv_ack,flags);
    		if(!strcmp(flags,"110")){
    			syn_ack_received = 1;
    			puts("syn ack packet received");
    		}
    	}
    	flags[0] = '0';
    	flags[1] = '0';
    	flags[2] = '0';
    	flags[3] = '\0';
    	buf = (char *)malloc(sizeof(char)*chunksize+HEADER_LEN);
    	buf2 = (char *)malloc(sizeof(char)*chunksize);
    	printf("Receiving data ack..\n");
    	while (fin != 1){
    		datasent = recvfrom(sockfd, buf, chunksize+HEADER_LEN, 0, (struct sockaddr *)&addr, &addr_len);
    		rcv_ack = parsechunk(buf,buf2,datasent,rcv_ack, flags);		
    			if(!strcmp(flags,"010")){
    				if(vv_flag == 1){
    					printf("Ack for Seq: %i received\n", rcv_ack - chunksize);
    					
    				}
    				update_ackflag(rcv_ack-chunksize,fileparse,lost);
    				memset(buf,0,chunksize+HEADER_LEN);
    				memset(buf2,0,chunksize);
    			}
    			else if(!strcmp(flags,"011")){
    				if(vv_flag == 1){
    					printf("Ack for Seq: %i received\n", rcv_ack - chunksize);
    					
    				}
    				update_ackflag(rcv_ack-chunksize,fileparse,lost);	
    				memset(buf,0,chunksize+35);
    				memset(buf2,0,chunksize);
    				sent_last = 1;
    				fin = 1;
    			}
    			else if(!strcmp(flags,"110")){
    				memset(buf,0,chunksize+35);
    				memset(buf2,0,chunksize);
    				puts("duplicate syn received");
    			}
    	}
    	puts("FIN ack received");
    	close(sockfd);		
    }

  8. #8
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    265
    Did you ever get this resolved? Seems to be looping in send_syn() for me where syn_ack_received gets tested. I only see one place in your code where this value changes. I agree with memcpy about the globals though. It's really late, maybe I can try and look further tomorrow.

    EDIT: You made your post just as I posted :P

  9. #9
    Registered User
    Join Date
    Apr 2012
    Posts
    9
    Quote Originally Posted by Syscal View Post
    Did you ever get this resolved? Seems to be looping in send_syn() for me where syn_ack_received gets tested. I only see one place in your code where this value changes. I agree with memcpy about the globals though. It's really late, maybe I can try and look further tomorrow.

    EDIT: You made your post just as I posted :P
    Yup, that's my big problem as of the moment. I traced it until the first rcvfrom(first call of rcvfrom from the listener function). It seems to me that the acknowledgement coming from the server is not getting received. According to Wireshark, the port is unreachable. I tried using a different port but still the same error is encountered.

    Code:
    while(syn_ack_received != 1){ datasent = recvfrom(sockfd, temp, HEADER_LEN+PAYLOAD_LEN, 0, (struct sockaddr *)&addr, &addr_len); rcv_ack = parsechunk(temp,temp2,datasent,rcv_ack,flags); if(!strcmp(flags,"110")){ syn_ack_received = 1; puts("syn ack packet received"); } }

  10. #10
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Another thing you *could* do is use a better system for flags.

    Start by #defining the ones you use:
    Code:
    #define SYN_SENT        0x001
    #define SYN_ACK_RECV 0x002
    #define SYN_ACK_SENT 0x004
    
    /* et cetera, remember to use powers of 2 for the constants */
    And then pick a sufficiently large data type to use, a 4-byte int usually works.

    How to use the flags:
    Code:
    int flags = 0;
    
    flags |= SYN_SENT; /* turn "on" SYN_SENT */
    flags &= ~SYN_SENT; /* turn "off" SYN_SENT */
    
    if (flags & SYN_SENT) /* check if SYN_SENT is "on" */
    if (!(flags & SYN_SENT)) /* check if SYN_SENT is "off" */
    You can set as many flags as you like, and then simply pass around the integer value to check the flag value.

  11. #11
    Registered User
    Join Date
    Apr 2012
    Posts
    9
    Quote Originally Posted by memcpy View Post
    Another thing you *could* do is use a better system for flags.

    Start by #defining the ones you use:
    Code:
    #define SYN_SENT        0x001
    #define SYN_ACK_RECV 0x002
    #define SYN_ACK_SENT 0x004
    
    /* et cetera, remember to use powers of 2 for the constants */
    And then pick a sufficiently large data type to use, a 4-byte int usually works.

    How to use the flags:
    Code:
    int flags = 0;
    
    flags |= SYN_SENT; /* turn "on" SYN_SENT */
    flags &= ~SYN_SENT; /* turn "off" SYN_SENT */
    
    if (flags & SYN_SENT) /* check if SYN_SENT is "on" */
    if (!(flags & SYN_SENT)) /* check if SYN_SENT is "off" */
    You can set as many flags as you like, and then simply pass around the integer value to check the flag value.
    Oh, thanks for that advice. I might probably do that. On other news, I tried using my listener function in a simple "receiver-only" program and it works fine. What could probably cause the problem?

  12. #12
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    265
    With all of the control stuff in your code, why don't you just use a SOCK_STREAM instead? I wrote a very similar application that accomplishes the same end goal of sending a file from host a to host b and it works fine with a lot less code.
    Last edited by Syscal; 04-05-2012 at 12:03 PM.

  13. #13
    Registered User
    Join Date
    Apr 2012
    Posts
    9
    Quote Originally Posted by Syscal View Post
    With all of the control stuff in your code, why don't you just use a SOCK_STREAM instead? I wrote a very similar application that accomplishes the same end goal of sending a file from host a to host b and it works fine with a lot less code. I'm not a godly programmer so I'm sure there's stuff wrong with my code too. But just as a suggestion, here is my client code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    
    #define SEND_BUFFER 1024
     
    struct socket_args{
      int socket_fd;
      struct sockaddr_in server;
    };
    
    
    int prepare_file(FILE ** file_ptr, char * file_name){
    
      int file_size = 0;
    
      if(!(*file_ptr = fopen(file_name, "r+"))){
        perror("fopen()");
        exit(-1);
      }
    
      fseek(*file_ptr, 0, SEEK_END);
      file_size = ftell(*file_ptr);
      fseek(*file_ptr, 0, SEEK_SET);
    
      return file_size;
    
    }
    
    void prepare_socket(struct socket_args * sock_args){
    
      unsigned port;
      char ipv4[INET_ADDRSTRLEN];
    
      if((sock_args->socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        perror("socket()");
        exit(-1);
      }
    
      fputs("Enter a port and IP Address: ", stdout);
      scanf("%s %u", ipv4, &port);
    
      sock_args->server.sin_family = AF_INET;
      sock_args->server.sin_port = htons(port);
    
      inet_pton(AF_INET, ipv4, &sock_args->server.sin_addr);
    
    }
    
    void send_file(struct socket_args * sock_args , FILE * file_ptr){
    
      int rBytes, wBytes, allBytes;
      char file_buffer[SEND_BUFFER];
    
      if(connect(sock_args->socket_fd, (struct sockaddr*)&sock_args->server,
             sizeof(sock_args->server)) < 0){
        perror("connect()");
        exit(-1);
      }
      
      while(rBytes = fread(file_buffer, 1, SEND_BUFFER, file_ptr))
       wBytes += write(sock_args->socket_fd, file_buffer, rBytes);
      
      printf("%d bytes written to the socket...\n", wBytes);
    
    }
    
    int main(int argc, char **argv){
    
      if( argc == 2){
    
        FILE * file_ptr;
        struct socket_args sock_args;
    
        prepare_file(&file_ptr, argv[1]);
    
        prepare_socket(&sock_args);
      
        send_file(&sock_args, file_ptr);
    
        fclose(file_ptr);
        close(sock_args.socket_fd);
      }
    
    
      return 0;
    }
    is that for TCP? well, I need to implement it in UDP so i use SOCK_DGRAM >.<

  14. #14
    Registered User
    Join Date
    Apr 2012
    Posts
    9
    confirmed! The problem is really in the listener thread.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File Transfer Using UDP/IP
    By AdamOhio76 in forum Networking/Device Communication
    Replies: 6
    Last Post: 03-19-2011, 02:37 PM
  2. Replies: 1
    Last Post: 11-08-2010, 01:03 PM
  3. File Transfer?
    By illiterate in forum C++ Programming
    Replies: 3
    Last Post: 07-23-2010, 04:35 AM
  4. big file transfer
    By Pyroteh in forum Tech Board
    Replies: 2
    Last Post: 05-26-2005, 10:35 AM
  5. File transfer
    By scrapedbr in forum C Programming
    Replies: 1
    Last Post: 05-27-2004, 12:46 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21