C TCP/IP Reliable Transmission project not reliable


 
Thread Tools Search this Thread
Homework and Emergencies Homework & Coursework Questions C TCP/IP Reliable Transmission project not reliable
# 1  
Old 07-12-2013
Network [SOLVED] C TCP/IP Reliable Transmission project not reliable

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted!

1. The problem statement, all variables and given/known data:

We must do the following for a massive coding project that is due at 12:20PM on Monday, July 22, 2013. We are to do the following (from the project writeup):

You are required to implement a socket based file
transmission program that runs on top of TCP/IP.
This can be divided into two phases:
1. Secure communication between two processes, e.g., A and B, with
error-handling using the Internet checksum algorithm for error detection.
2. The Stop-and-Wait (SW) protocol discussed in class.


The following, at a minimum, must be
prompted for:
[for the user to enter in]
(a) Size of packet
(b) Timeout interval (user-specified or ping-calculated)
(c) Size of sliding window
(d) Range of sequence numbers
(e) Situational Errors (none, randomly generated, or user-specified, i.e., drop
packets 2, 4, 5, lose acks 11, etc.)


File formats that must transfer over can be of any type,
e.g., .txt, .doc, .mov, .jpg, .exe, etc.

The information provided in the client (sender) window should include, but not
limited to:
Packet sequence number of packet sent.
Packet (sequence number) that timed out
Packet that was re-transmitted.
All packets in the current window.
Acks received.
Which packets are damaged, .i.e., deliberately trigger a
checksum error on the receiver side.
Information to be provided by the receiver:
◦ Packets (sequence number) received.
◦ Damaged packet(s) (checksum error should match
corresponding damaged packet from sender window).
◦ Packets in the current receiver window.
◦ Packets (duplicated) that are discarded.
◦ Ack packets that are sent.
• Frames arriving out of order should be re-sequenced before assembly.

We are also required to ensure the md5 sums match for both the source and destination files and test our code with a 1GB file (to stress test it, the professor has said "I will try to break your code").


2. Relevant commands, code, scripts, algorithms:

"assignment1.c"

Code:
#include <pthread.h> 
#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 <netdb.h> 
#include <arpa/inet.h> 
#include <sys/wait.h> 
#include <signal.h> 
#include <time.h> 
#include <semaphore.h> 
#include <fcntl.h> 
 
#define PORT 6789  // the port users will be connecting to 
#define BACKLOG 10   // how many pending connections queue will hold 
#define BUFFER_SIZE 1024 
 
int user, permPacketSize, timeoutType, timeoutInterval, sitErr; 
sem_t sem_transfer; 
 
/***********************************************************************************/ 
/***************************                          ******************************/ 
/***************************         SERVER           ******************************/ 
/***************************                          ******************************/ 
/***********************************************************************************/ 
int runServer() 
{ 
    int sock, msgsock, sin_size; // listen on sock, new connection on msgsock 
    struct sockaddr_in server;   // socket struct for server connection 
    struct sockaddr_in client;   // socket struct for client connection 
    char fromClient[BUFFER_SIZE];  // String from client 
    char toClient[BUFFER_SIZE];  // String sent to client 
    int temp;                     // temp int for calculations 
    int packetSize; 
    unsigned int seqNum = 0; 
    sem_init(&sem_transfer, 0, 1);   // initialize semaphore to 1 
    int fdServer; 
    int bytes_read, bytes_written; 
 
    /* Open a socket */ 
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
        perror("socket"); 
        exit(1); 
    } 
 
    /* Fill out server sockaddr_in struct */ 
    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(PORT); 
           
    /* Bind */ 
    if (bind(sock, (struct sockaddr *) &server, sizeof(server)) == -1) { 
        perror("bind"); 
        exit(2); 
    } 
 
    /* Listen w/ max queue of defined BACKLOG value */ 
    if (listen(sock, BACKLOG) == -1) { 
        perror("listen"); 
        exit(3); 
    } 
 
    sin_size = sizeof(struct sockaddr_in); 
 
    if ((msgsock = accept(sock, (struct sockaddr *)&client, &sin_size)) == -1) { 
        perror("accept"); 
    } 
 
    // get file to copy 
    char filename_received[BUFFER_SIZE]; 
     
    if (recv(msgsock, filename_received, BUFFER_SIZE,0) < 0){ 
        perror("Aborting"); 
        close(msgsock); 
        exit(4); 
    } 
    fprintf(stderr, "file to be copied: %s\n",filename_received); 
    char *copy; 
    copy = (char*) malloc (sizeof(char)*1024); 
    strcpy(copy, filename_received); 
        if  ( (fdServer = open (copy,  O_RDONLY))  == -1) { 
            perror ( "Error in opening the input file:"); 
            exit (1); 
        } 
    free(copy); 
     
    // Determine lowest packet size between client and server 
    sprintf(toClient, "%d", permPacketSize); 
    send(msgsock, toClient, sizeof(toClient),0); 
 
    if (recv(msgsock, fromClient, BUFFER_SIZE,0) < 0){ 
        perror("Aborting"); 
        close(msgsock); 
        exit(4); 
    } 
     
    temp = atoi(fromClient); 
 
    if (temp < permPacketSize){ 
        packetSize = temp; 
    } 
    else { 
        packetSize = permPacketSize; 
    } 
 
    fprintf(stderr, "The agreed upon packet size is %d\n", packetSize); 
    while (1) 
    { 
        void* buffer = (void*) malloc (packetSize); 
 
        bytes_read = read(fdServer, buffer, packetSize); 
        if (bytes_read == 0){ 
            break; 
        } 
         
        void *p = buffer; 
        while (bytes_read > 0){ 
            bytes_written = write(msgsock, p, bytes_read); 
            bytes_read -= bytes_written; 
            p += bytes_written; 
        } 
 
        free(buffer); 
 
        fprintf(stderr, "sending %d\n", seqNum); 
        seqNum++; 
    } 
    sprintf(toClient, "FINISHED\n"); 
    send(msgsock, toClient, sizeof(toClient),0); 
    // close all open fd's and sockets 
    close(msgsock); 
    close(sock); 
    close(fdServer); 
}   
 
/***********************************************************************************/ 
/***************************                          ******************************/ 
/***************************         CLIENT           ******************************/ 
/***************************                          ******************************/ 
/***********************************************************************************/ 
 
int runClient() 
{ 
    int sock;                    // fd for socket connection 
    struct sockaddr_in server;   // Socket info. for server 
    struct hostent *host;        // Server info   
    char selection[BUFFER_SIZE]; // User's input 
    char toServer[BUFFER_SIZE];   // String sent to server 
    char fromServer[BUFFER_SIZE];  // String rec'd from server 
    int temp;                     // temp int for calculations 
    int packetSize; 
    unsigned int ackNum = 0; 
    char* userInput; 
    userInput = (char*) malloc (sizeof(toServer)); 
    int fdClient; 
    int bytes_read, bytes_written; 
 
    // get server address 
    fprintf(stderr, "Enter the address of the server.\n"); 
    scanf("%s", userInput); 
 
    // Fill out sockaddr struct 
    server.sin_family = AF_INET; 
    if ((host = gethostbyname(userInput)) == NULL){ 
        printf("Unknown host.\n"); 
        exit(1); 
    } 
    server.sin_family = host->h_addrtype; 
    memcpy((char *) &server.sin_addr.s_addr, host->h_addr_list[0], host->h_length); 
    server.sin_port = htons((u_short) PORT); 
 
  // Create socket 
      if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){ 
        printf("Unable to open socket\n"); 
        perror("Aborting"); 
        exit(1); 
      } 
 
      // Try to connect 
      if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0){ 
        printf("Unable to connect to %s\n", userInput); 
        perror("Aborting"); 
        exit(1); 
      } 
 
    // request file to copy 
    printf("Enter a file name:\n"); 
    scanf("%s",userInput); 
    fprintf(stderr, "You entered: %s\n",userInput); 
    char filename_buf[BUFFER_SIZE]; 
    strcpy(filename_buf, userInput); 
 
    if (send(sock, filename_buf, sizeof(filename_buf),0) <0) 
    { 
        perror("Aborting"); 
        close(sock); 
        exit(42);         
    } 
 
    if  ( (fdClient = open (userInput, (O_WRONLY | O_CREAT),  0740)) == -1 ) 
    {  
            perror ( "Error in creating the output file:"); 
            exit (11); 
    } 
 
    free(userInput); 
 
    // Determine lowest packet size between client and server 
    sprintf(toServer, "%d", permPacketSize); 
    send(sock, toServer, sizeof(toServer),0); 
 
    if (recv(sock, fromServer, BUFFER_SIZE,0) < 0) 
    { 
        perror("Aborting"); 
        close(sock); 
        exit(4); 
    } 
 
    temp = atoi(fromServer); 
 
    if (temp < permPacketSize){ 
        packetSize = temp; 
    } 
    else { 
        packetSize = permPacketSize; 
    } 
    fprintf(stderr, "The agreed upon packet size is %d\n", packetSize); 
 
    while(1) 
    { 
        void* buffer = (void*) malloc (packetSize); 
 
        bytes_read = read(sock, buffer, packetSize); 
        if (bytes_read == 0){ 
            break; 
        } 
     
        void *p = buffer; 
        while (bytes_read > 0){ 
            bytes_written = write(fdClient, p, bytes_read); 
            bytes_read -= bytes_written; 
            p += bytes_written; 
        } 
 
        free(buffer); 
         
        fprintf(stderr, "receiving %d\n", ackNum); 
        ackNum++; 
    } 
    close(sock); 
    printf("All done. Connection to server terminated. Exiting...\n"); 
} 
 
 
/***********************************************************************************/ 
/***************************                          ******************************/ 
/***************************          MAIN            ******************************/ 
/***************************                          ******************************/ 
/***********************************************************************************/ 
 
int main(int argc, char *argv[]) 
{     
 
    // determine client or server 
    fprintf(stderr, "\nWelcome to the Reliable Transmission Project.\n"); 
    fprintf(stderr, "Please make the following numerical selections.\n\n"); 
    fprintf(stderr, "0) Server\n"); 
    fprintf(stderr, "1) Client\n"); 
     
    scanf("%d", &user); 
 
    if (user == 0){ 
        fprintf(stderr, "You have chosen to be the server.\n"); 
    } 
    else{ 
        fprintf(stderr, "You have chosen to be the client.\n"); 
    } 
 
    // determine packet size 
    fprintf(stderr, "\nPlease enter the packet size you would like to use (in bytes).\n"); 
    scanf("%d", &permPacketSize); 
    fprintf(stderr, "You have chosen a packet size of %d bytes.\n", permPacketSize); 
 
    // determine how to calculate timeout interval 
    fprintf(stderr, "\nWould you like the timeout interval to be determined manually or dynamically?\n\n"); 
    fprintf(stderr, "0) Set timeout interval manually\n"); 
    fprintf(stderr, "1) Automatic time interval\n"); 
 
    scanf("%d", &timeoutType); 
 
    if (timeoutType == 0){ 
        fprintf(stderr, "What would you like the timeout interval to be (in milliseconds)?\n"); 
        scanf("%d", &timeoutInterval); 
        fprintf(stderr, "You have chosen a timeout interval of %d milliseconds.\n", timeoutInterval); 
    } 
    else{ 
        fprintf(stderr, "The timeout interval will be automatically ping-calculated.\n"); 
        timeoutInterval = 4213; 
    } 
 
/***************************************************************** 
****************************************************************** 
 
    // determine situational errors 
    fprintf(stderr, "\nDo you want to introduce situational errors?\n\n"); 
    fprintf(stderr, "0) No\n"); 
    fprintf(stderr, "1) Yes\n"); 
 
    scanf("%d", &sitErr); 
 
    if (sitErr == 0){ 
        fprintf(stderr, "No situational errors will be used.\n"); 
    } 
    else{ 
        fprintf(stderr, "Which situational error would you like to introduce?\n"); 
        fprintf(stderr, "1) Drop packets\n"); 
        fprintf(stderr, "2) Lose ACKs\n"); 
        fprintf(stderr, "3) Send damaged packets\n"); 
        fprintf(stderr, "4) Random\n"); 
        scanf("%d", &sitErr); 
 
        if(sitErr == 1){ 
            fprintf(stderr, "You have chosen to have some packets get dropped.\n");         
        } 
        else if(sitErr == 2){ 
            fprintf(stderr, "You have chosen to lose some ACK commands.\n"); 
        } 
        else if(sitErr == 3){ 
            fprintf(stderr, "You have chosen to send some damaged packets.\n"); 
        } 
        else{ 
            fprintf(stderr, "You have chosen to have a random error selected.\n"); 
            srand((unsigned)time(NULL)); 
            sitErr = (rand() % 3 + 1); 
            if(sitErr==1) 
                fprintf(stderr, "You will have some packets get dropped.\n"); 
            else if(sitErr==2) 
                fprintf(stderr, "You will lose some ACK commands.\n"); 
            else 
                fprintf(stderr, "You will send some damaged packets.\n"); 
        } 
    } 
 
********************************************** 
********************************************/ 
 
    // all settings are entered, run client/server 
    if(user){ 
        runClient(); 
    } 
    else{ 
        runServer(); 
    } 
 
    return 0; 
}

"send.txt"
Code:
SEND ME...

3. The attempts at a solution (include all code and scripts):

When I ran this, I got the following printouts (these are abbreviated to not take up ten miles of screen space):

(server side)

Code:
Welcome to the Reliable Transmission Project. 
Please make the following numerical selections. 
 
0) Server 
1) Client 
0 
You have chosen to be the server. 
 
Please enter the packet size you would like to use (in bytes). 
50 
You have chosen a packet size of 50 bytes. 
 
Would you like the timeout interval to be determined manually or dynamically? 
 
0) Set timeout interval manually 
1) Automatic time interval 
1 
The timeout interval will be automatically ping-calculated. 
file to be copied: project.pdf 
The agreed upon packet size is 50 
sending 0 
sending 1 
sending 2 
sending 3 
sending 4 
[...]
sending 1820 
sending 1821 
sending 1822 
sending 1823

(client side)

Code:
Welcome to the Reliable Transmission Project. 
Please make the following numerical selections. 
 
0) Server 
1) Client 
1 
You have chosen to be the client. 
 
Please enter the packet size you would like to use (in bytes). 
50 
You have chosen a packet size of 50 bytes. 
 
Would you like the timeout interval to be determined manually or dynamically? 
 
0) Set timeout interval manually 
1) Automatic time interval 
1 
The timeout interval will be automatically ping-calculated. 
Enter the address of the server. 
127.0.0.1 
Enter a file name: 
project.pdf 
You entered: project.pdf 
The agreed upon packet size is 50 
receiving 0 
receiving 1 
receiving 2 
receiving 3 
receiving 4 
[...]
receiving 1840 
receiving 1841 
receiving 1842 
receiving 1843 
All done. Connection to server terminated. Exiting...

Running md5 checksums on both I get (after testing the program with our project writeup, project.pdf):

Code:
$ md5sum project.pdf
e1febbee4b614140677dd7c8a221f5c6  project.pdf
$ md5sum copy_of_project.pdf
9a6003fb91d80209d717c646ab3012ff  copy_of_project.pdf

These don't match, so the file clearly does not copy correctly. Even though I am able to copy over files of different types, and they work correctly (I tried it with an mp3, it played just like the original file), I am believing that extra bytes are being inserted in the file transfer somewhere. I am not sure if the checksum has something to do with this. I know I have to implement it somewhere, but I am not certain where to do this, or if the checksum even checks to see if the original bytes that are passed in from the sender in each packet are the same bytes that get to the receiver? You can try my code with any of your own files, and if it's running like it did with me, your copied file will be bigger than your original file.

I've been working on this for a few weeks and have not been able to discern what is going on? There is a lot of stuff we still have yet to do (like deliberately insert damaged packets or cause them to get lost, or acks to get lost), but I'm stuck with about 9 days left before it is due (what a way to spend summer, slaving at a massive pig of coding, eh?).

Can anyone help me out at all? Thanks!

4. Complete Name of School (University), City (State), Country, Name of Professor, and Course Number (Link to Course):

University of Minnesota, Twin Cities; Minneapolis, MN, USA, Professor Jack Tan, CSCI 4211: Csci4211/Csci5211-Computer Networks

Note: Without school/professor/course information, you will be banned if you post here! You must complete the entire template (not just parts of it).
# 2  
Old 07-16-2013
Never mind, I had figured it out. It involved simply moving the fprintf calls in the main while loops in both runClient() and runServer() before I wrote the "bytes_read" to "bytes_written" and sent them back and forth. No assistance needed here now!
This User Gave Thanks to kowit010 For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

8 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

Is this website reliable ?

edit by bakunin: content not relevant for our site (and bordering on spam) SNIPped, thread closed. My suggestion is to - before even considering to buy anything online - put more effort in research, i.e. what the web site you write a comment at, is all about. This one here is definitely not for... (1 Reply)
Discussion started by: ethansk
1 Replies

2. Ubuntu

Reliable Video Editing & DVD Burning

I have just about given up trying to find a reliable package. Imagination - Pitvi - Openshot - DVD Styler are just some of those tried, but even if success has been achieved in exporting a viable result - Brasero will not burn it this includes VOB files. It seems that there is no alternative to... (1 Reply)
Discussion started by: Royalist
1 Replies

3. SuSE

Is OpenSuSE 12.1 stable and reliable?

Hi, We are ready to update OpenSuSE for our web servers from 11.2 to either 11.4 or 12.1. 12.1 is still a beta version. Is it stable and reliable enough for production servers? Please share your valuable experiences. Thank you in advance! (5 Replies)
Discussion started by: aixlover
5 Replies

4. Programming

Reliable management of signal SIGPIPE and SIGTERM

I' m note very expert in the reliable manage of signal... but in my server I must manage SIGPIPE for the socket and SIGTERM... I've wrote this but there is something wrong... Can someone explain me with some example the reliable management of signal?? This is what I've wrote in the server ... (2 Replies)
Discussion started by: italian_boy
2 Replies

5. Programming

reliable udp and socket programming

could somebody give me hand programming the attached request. my code isn't complete and i do not really understand how should i implement that. (1 Reply)
Discussion started by: makaveli_
1 Replies

6. Shell Programming and Scripting

Most reliable way to store file contents in an array in bash

Hi Guys, I have a file which has numbers in it separated by newlines as follows: 1.113 1.456 0.556 0.021 -0.541 -0.444 I am using the following code to store these in an array in bash: FILE14=data.txt ARRAY14=(`awk '{print}' $FILE14`) (6 Replies)
Discussion started by: npatwardhan
6 Replies

7. AIX

Reliable dual-boot method for 5.3 and 6.1

Hi All, I am looking for information and advice on a reliable method to support the dual booting between AIX 5.3 and AIX 6.1 I have a 7029-6E3 with 2 x 36Gb disks, hdisk0 (altinst_rootvg) and hdisk1 (rootvg) I have previously used alt_disk_install to upgrade from 5.1->5.3, and now from... (2 Replies)
Discussion started by: KevB
2 Replies

8. Shell Programming and Scripting

Good (reliable!) check if user exists

Hi all, I've been trying to find a good check I can put it in to a shell script to see if a given user exists. Some of the things I've thought about is checking whether they have a home directory, but not all users have a home directory. I've thought about grepping the /etc/passwd file for... (4 Replies)
Discussion started by: _Spare_Ribs_
4 Replies
Login or Register to Ask a Question