CS118-Project-2
README.md

Project Report

C++ code that creates a server to connects using UDP datagrams, and a client that sends packets with a 512-byte payload for the server to save as a binary file

Brandon Truong 705326387 Kade Adams 505123178 Michael Zhan 805384414

Contributions

Brandon: Implemented code involving shared.cpp and server.cpp, and worked on debugging code using the autograder

Kade: Implemented code involving client.cpp and shared.cpp, and worked on debugging code using the autograder

Michael: Implemented code involving client.cpp and shared.cpp, and worked on debugging code using the autograder

High Level Design

Server Side:

C++ code that creates a server through BSD sockets, connecting to specified port and able to receive UDP packets from various hosts that are transferring file data. File data is then saved to a specified folder based on the connection ID given to that particular host.

  1. Server Design Part
    • Uses BSD Sockets to set up the server using UDP type, which accepts packets with a 12-byte header and up to 512-byte payload. The server first accepts connections through a 3-way handshake using SYN, SYN-ACK, ACK, giving the client an assigned connection ID, and saving the transferred payload as .file within the specified folder. The server handles packets sent in any order, up to RWND, and sends an empty payload with acknowledgements containing the expected sequence.

Client Side:

C++ code that creates a client through BSD sockets, connecting to a specified port that is connected to the server side, and allows sending of file split into multiple packets depending on the size of the file and allows receiving of ACK packets from the server.

  1. General Idea -Use BSD sockets to set up client using UDP type and use the socket when connected to server side in order to send packets with a max size of 524 bytes, 512 bytes for the payload and 12 bytes for the header. We first use a 3-way handshake in order to set up the connection with the server and send a syn packet, receive a syn ack, then proceed to send packets that relate to sending the contents of the file we want to send while receiving acks for each packet that we send. We finish by sending and receiving fin packets in order to properly close the connection between the client and server side. We also implement congestion control and timeout timers to ensure that we are not dealing with too much overhead at one time or sending out too many packets and that if a packet is lost, the timer times out and we send the packet again.

Shared.h:

C++ code that uses a header file for easy referencing between client and server implementations, and multiple helper functions as well as structs that make processing data easier.

Makefile

The Makefile allows for

  • make(default)
  • client
  • server
  • clean
  • tarball

Testing

We ran our tests manually with very small files(only one packet of information) to ensure that our base implementations were working with different forms of loss and delays.

We then ran the autograder both with ./run_autograder and python3, checking the /absolute/client.txt and server.txt for issues that arose when tests were failed.

Before actually running autograder, we added numerous cerr statements throughout our code so that we could test each function and code portions functionality to make sure everything did what it was supposed to and that our entire program didn’t break. We could step through the cerr’s to see where our program stalled, stopped, stepped through, what different variable outputted at certain times, and in general make sure that packets and packet contents were properly sent and received.

For example: python3 $SOURCE/run_tests.py ServerTests.test3_5 > temp3_5.txt

3.5. Server able to receive a large file (10 MiB bytes) and save it in 1.file (with reordered and delayed packets) ... DEBUG:CS118:Starting: /autograder/submission/server 7301 /autograder/absolute/ DEBUG:CS118:Starting: /autograder/source/reference-implementation/lossy-proxy.py localhost 7201 localhost 7301 0.05 0.01 DEBUG:CS118:Starting: /autograder/submission/client localhost 7201 /file_1M DEBUG:CS118:diff "/file_1M" "/autograder/absolute//1.file" OK

Problems

  • One of the initial problems we ran into was how to send the packets in the proper format across the socket. We realized that initially our packets were getting messed up because the byte order was incorrect. So we figured out how to properly use htons, htonl, ntohs, and ntohl in order to ensure proper byte order on both sides of the socket.
  • Another problem we encountered was that initially, we were reading data into a string on the server side. This was however, leading us to have differences between the file on the client side and the file on the server side. This was because with large binary files it was inevitable that a null character was somewhere within it which would terminate our string and cause our files to be different. To fix this we used a vector of characters on the server side which fixed our problem.
  • Another problem we had was exactly how to do timeouts. While you can initially set the timeout for all receives with setsockopt() this is a pain to constantly change and can lead to other issues if you want a specific timeout for only one receive. However, we learned that you can use the select() call with your socket file descriptor and specify a specific timeout there which made timeouts much easier especially on the client side. -Another problem was properly getting autograder to work as we realized that much of the implementation we tested manually and thought was fine would actually fail the tests within autograder. We had to modify our code a decent amount for it to conform to the tests within autograder -Another problem was trying to figure out how to properly merge our changes. Since we were changing multiple lines of code and sometimes the same lines of code at the same time, it was a bit difficult to merge all the changes and required us to discuss what our code was doing to each other so that we could understand each others implementations

Libraries

-include <stdio.h> -include <stdlib.h> -include <errno.h> -include <sys/types.h> -include <sys/socket.h> -include <sys/wait.h> -include <netinet/in.h> -include <unistd.h> -include <time.h> -include <arpa/inet.h> -include -include -include -include <string.h> -include -include <arpa/inet.h> -include <netdb.h> -include <unordered_map> -include -include <sys/select.h> -include <sys/time.h>

Acknowledgement

-Piazza