Thread: Server/Client Go-Back-N

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    4

    Server/Client Go-Back-N

    Hi, I have a little side project I have to do, but for the life of me I cant figure out the information.

    Ive got the following two source codes

    Server1.c
    Code:
    #include <stdio.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 <time.h>
    
    
    #define MYPORT "4951"    
    
    // This is the size of our receiving buffer
    #define MAXBUFLEN 100
    
    
    int main(void)
    {
        int       sockfd;
        struct addrinfo hints, *servinfo, *p;
        int       rv;
        int       numbytes;
        struct    sockaddr_storage their_addr;
        char      buf[MAXBUFLEN];
        socklen_t addr_len;
    
            
        memset(&hints, 0, sizeof hints);
        hints.ai_family   = AF_UNSPEC;  
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_flags    = AI_PASSIVE; 
    
            // COMMENT -- What does the following function do?
            // COMMENT -- Why is the first parameter to getaddrinfo NULL?
        if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            return 1;
        }
    
        
        for(p = servinfo; p != NULL; p = p->ai_next) 
            {
            if ((sockfd = socket(p->ai_family, p->ai_socktype,
                    p->ai_protocol)) == -1) {
                perror("listener: socket");
                continue;
            }
    
            if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
                close(sockfd);
                perror("listener: bind");
                continue;
            }
    
            break;
        } // END FOR
    
        if (p == NULL) {
            fprintf(stderr, "listener: failed to bind socket\n");
            return 2;
        }
    
        freeaddrinfo(servinfo);
    
        printf("server: waiting to recvfrom...\n");
    
     
        
          while(1) 
          {
        
        addr_len = sizeof their_addr;
        if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
            (struct sockaddr *)&their_addr, &addr_len)) == -1) 
            {
            perror("recvfrom");
            exit(1);
        }
    
            
        buf[numbytes] = '\0';
        printf("server: received... \"%s\"\n", buf);
    
           
       
    
           } // END WHILE -- the main loop
    
          //  -----------------------------------------------------------------------
          // Close the socket to the channel.
          close(sockfd);
    
          return 0;
    }
    and client1.c
    Code:
    #include <stdio.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 <time.h>
    
    // The channel's port
    #define CHANNELPORT "4950"
    // Our receiving buffer length
    #define MAXBUFLEN   100
    // Size of our frame
    #define MAXMESGLEN  1
    
    int main(int argc, char *argv[])
    {
        int sockfd;                          
        struct addrinfo hints, *servinfo, *p; 
        int rv;                               
        int numbytes;                         
            socklen_t addr_len;                   
            struct sockaddr_storage their_addr;   
    
            char buf[MAXBUFLEN];                  
            char myframe[MAXMESGLEN];             
    
            char *mesg = "A";                     // Message to be sent
    
            
            fd_set fds;
            int rc;
            struct timeval timeout;
    
    
         
        memset(&hints, 0, sizeof hints);
        hints.ai_family   = AF_UNSPEC;        
        hints.ai_socktype = SOCK_DGRAM;      
    
            
        if ((rv = getaddrinfo("127.0.0.1", CHANNELPORT, &hints, &servinfo)) != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            return 1;
        }
    
        
        for(p = servinfo; p != NULL; p = p->ai_next) 
            {
            if ((sockfd = socket(p->ai_family, p->ai_socktype,
                    p->ai_protocol)) == -1) {
                perror("client: socket");
                continue;
            }
    
            break;
        }
    
           
        if (p == NULL) {
            fprintf(stderr, "client: failed to bind socket\n");
            return 2;
        }
    
            myframe[0] = mesg[0];
    
          
        if ((numbytes = sendto(sockfd, myframe, MAXMESGLEN, 0,
                           p->ai_addr, p->ai_addrlen)) == -1) 
            {
            perror("talker: sendto");
            exit(1);
        }
    
            printf("Done Sending: %d\n", numbytes);
    
         
        freeaddrinfo(servinfo);
        close(sockfd);
        return 0;
    }
    Basically I have this code compiled, all works, Im using IdealChannel and EvilChannel, which are two channels im meant to test things on.


    In My first step which im stuck on, is I need to modify the above codes to include Go-Back-N. I have to transfer the letters in the char *mesg = "A", and I also have to edit char* mesg so it send a string of ABCD, but sending one letter at a time, and transfer the letters using go-back-n as well.

    I was wondering how exactly am I supposed to do that, and how do I then calculate the average round Trip Time of the channel.

    I really want to understand this, as then it will help me in the future with my actaul assignments as i know similar things will be coming up soon.

    Regards

  2. #2
    Registered User
    Join Date
    Oct 2012
    Posts
    4
    I have modified client.c to send a large string, but the rest so far i have problems with

    Code:
    #include <stdio.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 <time.h>
    
    // The channel's port -- do not change
    #define CHANNELPORT "4950"
    // Our receiving buffer length
    #define MAXBUFLEN   100
    // Size of our frame
    #define MAXMESGLEN  1
    
    int main(int argc, char *argv[])
    {
        int sockfd;                           
        struct addrinfo hints, *servinfo, *p; 
        int rv;                               
        int numbytes;                         
            socklen_t addr_len;                   
            struct sockaddr_storage their_addr;   
    
            char buf[MAXBUFLEN];                  
            char myframe[MAXMESGLEN];             
    
            char *mesg = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123";                     
        int i;
    
            // used for select
            fd_set fds;
            int rc;
            struct timeval timeout;
    
    
        memset(&hints, 0, sizeof hints);
        hints.ai_family   = AF_UNSPEC;        // COMMENT
        hints.ai_socktype = SOCK_DGRAM;       // COMMENT
    
        if ((rv = getaddrinfo("127.0.0.1", CHANNELPORT, &hints, &servinfo)) != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            return 1;
        }
    
        // COMMENT
        for(p = servinfo; p != NULL; p = p->ai_next) 
            {
            if ((sockfd = socket(p->ai_family, p->ai_socktype,
                    p->ai_protocol)) == -1) {
                perror("client: socket");
                continue;
            }
    
            break;
        }
    
            // If we can't get a socket ...
        if (p == NULL) {
            fprintf(stderr, "client: failed to bind socket\n");
            return 2;
        }
    
         
        for(i=0;i<30;i++)        
        {
            myframe[0] = mesg[i];
    
                   // COMMENT
            if ((numbytes = sendto(sockfd, myframe, MAXMESGLEN, 0,
                           p->ai_addr, p->ai_addrlen)) == -1) 
                {
                perror("talker: sendto");
                exit(1);
            }    
    
                printf("Done Sending: %d\n", numbytes);
        }
            
          
        freeaddrinfo(servinfo);
        close(sockfd);
        return 0;
    }

  3. #3
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by crazystudentc View Post
    Code:
        memset(&hints, 0, sizeof hints);
        hints.ai_family   = AF_UNSPEC;  
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_flags    = AI_PASSIVE; 
    
        if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            return 1;
        }
    The getaddrinfo() function creates a singly-linked list of socket definitions that match the parameters. The pointer to the first item in that list is saved to servinfo, if the function returns success/zero.

    The first parameter to the function is node, the second parameter service. Here is what the above-linked man page says about this:
    Quote Originally Posted by man 3 getaddrinfo
    If the AI_PASSIVE flag is specified in hints.ai_flags, and node is NULL, then the returned socket addresses will be suitable for bind()ing a socket that will accept() connections. The returned socket address will contain the "wildcard address" (INADDR_ANY for IPv4 addresses, IN6ADDR_ANY_INIT for IPv6 address). The wildcard address is used by applications (typically servers) that intend to accept connections on any of the hosts's network addresses. If node is not NULL, then the AI_PASSIVE flag is ignored.
    In other words, your function call asks for sockets that will accept incoming connections to the specified port (string MYPORT) on all network interfaces.

    Quote Originally Posted by crazystudentc View Post
    In My first step which im stuck on, is I need to modify the above codes to include Go-Back-N.
    What do you mean, exactly, by Go-Back-N?

    The current programs don't seem to use any kind of datagram acknowledgment. Perhaps you are supposed to implement the Go-Back-N ARQ protocol between the server and the client?

    Quote Originally Posted by crazystudentc View Post
    how do I then calculate the average round Trip Time of the channel
    Right after your sendto() and recvfrom() functions complete, use clock_gettime(CLOCK_REALTIME, &timespec) to get the wall clock. The difference in the timespecs is the round-trip time for that message; in seconds,
    Code:
    double seconds = (double)(after.tv_sec - before.tv_sec)
                   + (double)(after.tv_nsec - before.tv_nsec) / 1000000000.0;
    If you don't want to or cannot link against the rt library (-lrt when compiling/linking), then you can use the less precise gettimeofday(&timeval, NULL) call in exactly the same way. Then, the difference in seconds is
    Code:
    double seconds = (double)(after.tv_sec - before.tv_sec)
                   + (double)(after.tv_usec - before.tv_usec) / 1000000.0;
    Because round-trip time is real world time (wall clock time), you need to use the wall clock and not say CPU clock (or CPU cycle counters).

  4. #4
    Registered User
    Join Date
    Oct 2012
    Posts
    4
    Thank you for your prompt reply, can you please explain in more detail the rest of the code that has //comment on it, as they r vital for me to understand

    Code:
    #include <stdio.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 <time.h>
    
    // The channel's port -- do not change
    #define CHANNELPORT "4950"
    // Our receiving buffer length
    #define MAXBUFLEN   100
    // Size of our frame
    #define MAXMESGLEN  1
    
    int main(int argc, char *argv[])
    {
        int sockfd;                           // COMMENT
        struct addrinfo hints, *servinfo, *p; // COMMENT
        int rv;                               // COMMENT
        int numbytes;                         // COMMENT
            socklen_t addr_len;                   // COMMENT
            struct sockaddr_storage their_addr;   // COMMENT
    
            char buf[MAXBUFLEN];                  // COMMENT
            char myframe[MAXMESGLEN];             // Do not change.  Size of frame to channel
    
            char *mesg = "A";                     // Message to be sent
    
            // used for select
            fd_set fds;
            int rc;
            struct timeval timeout;
    
    
            // COMMENT
        memset(&hints, 0, sizeof hints);
        hints.ai_family   = AF_UNSPEC;        // COMMENT
        hints.ai_socktype = SOCK_DGRAM;       // COMMENT
    
            // COMMENT
        if ((rv = getaddrinfo("127.0.0.1", CHANNELPORT, &hints, &servinfo)) != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            return 1;
        }
    
        // COMMENT
        for(p = servinfo; p != NULL; p = p->ai_next) 
            {
            if ((sockfd = socket(p->ai_family, p->ai_socktype,
                    p->ai_protocol)) == -1) {
                perror("client: socket");
                continue;
            }
    
            break;
        }
    
            // If we can't get a socket ...
        if (p == NULL) {
            fprintf(stderr, "client: failed to bind socket\n");
            return 2;
        }
    
           // In this assignment, we only send 1 byte at a time.
            // Let's copy a byte into our frame
            myframe[0] = mesg[0];
    
            // COMMENT
        if ((numbytes = sendto(sockfd, myframe, MAXMESGLEN, 0,
                           p->ai_addr, p->ai_addrlen)) == -1) 
            {
            perror("talker: sendto");
            exit(1);
        }
    
            printf("Done Sending: %d\n", numbytes);
    
            
            // ---------------------------------------------------------------------------
            // Free everything and call it a day ...
        freeaddrinfo(servinfo);
        close(sockfd);
        return 0;
    }


    and server1.c

    Code:
    int main(void)
    {
        int       sockfd;
        struct addrinfo hints, *servinfo, *p;
        int       rv;
        int       numbytes;
        struct    sockaddr_storage their_addr;
        char      buf[MAXBUFLEN];
        socklen_t addr_len;
    
            /*
             * COMMENT
             */
        memset(&hints, 0, sizeof hints);
        hints.ai_family   = AF_UNSPEC;  
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_flags    = AI_PASSIVE; 
    
            // COMMENT -- What does the following function do?
            // COMMENT -- Why is the first parameter to getaddrinfo NULL?
        if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
            fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
            return 1;
        }
    
        /*
             *  COMMENT -- what does the following code do?
             */
        for(p = servinfo; p != NULL; p = p->ai_next) 
            {
            if ((sockfd = socket(p->ai_family, p->ai_socktype,
                    p->ai_protocol)) == -1) {
                perror("listener: socket");
                continue;
            }
    
            if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
                close(sockfd);
                perror("listener: bind");
                continue;
            }
    
            break;
        } // END FOR
    
        if (p == NULL) {
            fprintf(stderr, "listener: failed to bind socket\n");
            return 2;
        }
    
        freeaddrinfo(servinfo);
    
        printf("server: waiting to recvfrom...\n");
    
     
          /* -----------------------------------------------------------------------
           *  MAIN LOOP
           *  Hint: hit ctrl-c to kill the server
           * -----------------------------------------------------------------------
           */
          while(1) 
          {
        /*
             *  COMMENT
             */
        addr_len = sizeof their_addr;
        if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
            (struct sockaddr *)&their_addr, &addr_len)) == -1) 
            {
            perror("recvfrom");
            exit(1);
        }
    
            // Let's print our received data.
        buf[numbytes] = '\0';
        printf("server: received... \"%s\"\n", buf);
    
            /*
             * Now that we've received a character (1-byte), do something ...
             * Hint:  checkout sendto
             */
       
    
           } // END WHILE -- the main loop
    
          //  -----------------------------------------------------------------------
          // Close the socket to the channel.
          close(sockfd);
    
          return 0;
    }

    I know im supposed to use packet acknowledgements, so Im not sure if im supposed to use go-back-n arq or simply modify code to acknowledge, and use go-back-n differently.

    Could you please provide me an example of what you would change in the codes to make use of go-back-n,
    and also how could it then be used to help the client recover from packet loss, which must include a senders and recievers window, the timeout, I will have to work out by myself using the avergae RTT as a starting point, which fits in with my channels im using

  5. #5
    Registered User
    Join Date
    Oct 2012
    Posts
    4
    also quick question, how do you modify server1.c so that it prints out the throughput in bytes/s after receiving five frames.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. client server
    By kapil1089thekin in forum C Programming
    Replies: 1
    Last Post: 01-18-2011, 02:43 PM
  2. Client/server problem; server either stops receiving data or client stops sending
    By robot-ic in forum Networking/Device Communication
    Replies: 10
    Last Post: 02-16-2009, 11:45 AM
  3. Client - Server
    By sCandal2 in forum Windows Programming
    Replies: 5
    Last Post: 11-16-2004, 06:24 AM
  4. Ftp Client Server
    By Bharat_kumarr in forum C++ Programming
    Replies: 1
    Last Post: 10-19-2004, 06:58 AM
  5. client/server
    By Sabrina in forum C Programming
    Replies: 2
    Last Post: 10-13-2001, 12:53 AM