Thread: UDP Message Passing

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    10

    UDP Message Passing

    So, as always, I'll preface this email by saying this is for a class assignment. I'm looking for debugging assistance.

    I have two files running on two machines. The sending program is taking 100 byte chunks of a file, adding a header file, adding a crc-16 tail and sending the message to the remote server. The remote server is validating the code, ensuring it's not duplicated and sending an ack back to the local machine.

    My problem is this...I'm not seeing the output I'd expect when the file is longer than 1 frame. (>100 bytes). The program works perfectly when the file is only 1 frame long.

    File: send.c
    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define BUFMAX 128
    
    //Command Arguments:
    // [0] - sendf
    // [1] - destination machine
    // [2] - destination port number
    // [3] - file to be sent
    
    int main(int argc, char* argv[]){
      int sk;                       // Socket
      int n;                        // # of char read to buffer
      int i;                        // Looping Index
      int fin;                      // Final Frame 1=true 0=false
      int seq;                      // Frame Seq No
      int ack;                      // Frame Ack
      unsigned char buf[BUFMAX];    // Send Buffer
      unsigned char res[BUFMAX];    // Response Buffer
      unsigned short reply;         // CRC Reply
    
      struct sockaddr_in remote;
      struct hostent *hp;
    
      // Define and open the input file for transfer
      FILE *fp;
      fp = fopen(argv[3],"r");
    
      // Create the socket
      sk = socket(AF_INET, SOCK_DGRAM, 0);
      remote.sin_family = AF_INET;
      hp = gethostbyname(argv[1]);
    
      // If the host cannot be found terminate program
      if(hp==NULL){
        printf("Can't find hostname. %s\n", argv[1]);
        exit(1);
      }
    
      bcopy(hp->h_addr, &remote.sin_addr.s_addr, hp->h_length);
      remote.sin_port = ntohs(atoi(argv[2]));
    
      seq = 1; // set the initial seq
    
      fd_set rfds;
      struct timeval tv;
      int retval;
    
      FD_ZERO(&rfds);
      FD_SET(sk, &rfds);
    
      // Read 100 bytes at a time from the file to the buffer
      while((n=fread(&buf[1], 1, 100, fp)>0)){
        printf("Preparing to send a new frame!\n");
        printf("%d bytes read to buffer.\n", strlen(buf));
        for(i=1; i<strlen(buf); i++){ printf("%c", buf[i]); }
        printf("\n");
    
        // Prepare header byte
        // fin = 1 << 5;
        // seq = 1 << 2;
        // ack = 1;
    
        if(strlen(buf)<100){                // Is this the final frame?
          printf("Found the final frame! %d\n", strlen(buf));
          fin = 1 << 5;     // Set the 6th bit to 1
        } else {
          fin = 0;
        }
    
        seq = (seq == 0) ? 1 : 0;           // Need to alternate seq no
        seq = seq << 2;
    
        ack = 0;                    // Not needed for the sendf function
        buf[0] = fin | seq | ack;   // Bitwise or to set the header
        printf("Preparing Header: %x\n", buf[0]);
    
        // Generate CRC Code //
        reply = crc(&buf, strlen(buf));
        buf[strlen(buf)] = reply >> 8 & 0xff;
        buf[strlen(buf)] = reply & 0xff;
        printf("Did I get here?\n");
        for(i=0; i<strlen(buf); i++){ printf("buf[%i] = %02x\n", i, buf[i]); }
    
        // Send to the remote machine //
        while(1){
          dlsendto(sk, buf, strlen(buf)+1, 0, &remote,sizeof(remote),0);
    
          // Stop and Wait for a response from the remote machine //
          tv.tv_sec = 10;
          tv.tv_usec = 0;
          if(select(32, &rfds, NULL, NULL, &tv)==0){
            printf("Timeout - resending the frame!!\n");
          }
          else {
            read(sk,res,BUFMAX);
            reply = crc(res, strlen(res));
    
            if(crc(res, strlen(res))==0){           // Is CRC Correct?
              if(((res[0] << 5) & 0x80) == seq){    // Is Seq Correct?
                if(((res[0] << 7) & 0x80)){ // Is Ack?
                    printf("Ack Received\n");
                    //buf[1] = '\0';
                    break;
                }
                else{
                    printf("Not an Ack! Resend Frame!\n");
                }
              }
              else {
                printf("Duplicate Ack Received! Resend Frame!\n");
              }
            }
            else {
              printf("Ack Frame Damaged! Resend Frame!\n");
            }
          }
        } //printf("Exited to here\n");
      }
      close(sk);
    }
    The output I'm getting looks like this....
    Code:
    Preparing to send a new frame!
    101 bytes read to buffer.
    total 4945
    -rwxr-xr-x 1 root root  57548 2005-01-29 12:20 afio
    -rwxr-xr-x 1 root root   3200 2006-05Preparing Header: 0
    Did I get here?
    Ack Received
    Preparing to send a new frame!
    0 bytes read to buffer.
    Found the final frame! 0
    Preparing Header: 24
    Did I get here?
    buf[0] = 24
    ... <intentionally removed for space>
    buf[102] = c1
    Duplicate Ack Received! Resend Frame!
    Timeout - resending the frame!!
    Timeout - resending the frame!!
    Notice that the first read appears to work fine. One the second read, it thinks I'm not reading anything into the buffer so it turns the final frame bit on.

    For reference, my header should be:
    8 - 0
    7 - 0
    6 - final frame? 1 = yes; 0 = no;
    5 - 0
    4 - 0
    3 - sequence - alternates between 1 and 0
    2 - 0
    1 - ack? 1 = yes; 0 = no;

    Hoping some fresh eyes might see what I'm doing wrong. If you need it, I can also post the receive program.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Because you are getting "Timeout -- Resending the frame", it would seem your sender is working more or less as it should...

    I'm betting the problem is on the receiving end...

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    10
    Quote Originally Posted by CommonTater View Post
    Because you are getting "Timeout -- Resending the frame", it would seem your sender is working more or less as it should...

    I'm betting the problem is on the receiving end...
    That was my original thought and I haven't ruled out a problem on the ack side.

    That being said, I did find that my strlen(buf) was causing one problem. When the header was 00000000 it was reading as the end-of-string. I've fixed that so now I can read what's in the buffer.

    My problem is actually somewhere in the Ack process on the sender side. It is hanging up on the ack because it thinks it's a duplicate frame.

    I added more code to validate what comes across back from the receiver. My if statements are generating false negatives.

    Code:
    if(((res[0] << 5) & 0x80) == seq){    // Is Seq Correct?
    I thought this would generate a 1 or 0. It's generating 128 or 0.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. UDP Broadcast Client and Server
    By lamoseley in forum C Programming
    Replies: 1
    Last Post: 10-23-2010, 10:28 PM
  2. passing stuff into dialog boxes
    By Quantumcat in forum Windows Programming
    Replies: 1
    Last Post: 10-04-2010, 12:39 AM
  3. Message printing problem
    By robert_sun in forum C Programming
    Replies: 1
    Last Post: 05-18-2004, 05:05 AM
  4. Traceroute using UDP and ICMP
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 08-09-2002, 07:09 PM
  5. Traceroute using UDP + ICMP
    By Unregistered in forum Windows Programming
    Replies: 0
    Last Post: 08-05-2002, 10:50 AM