https://github.com/austinjhunt/tcp-over-udp-socketprogramming

Implementation of "TCP" (a reliable transport layer protocol) over UDP with Python socket programming for Vanderbilt University CS 5283 - Computer Networks

https://github.com/austinjhunt/tcp-over-udp-socketprogramming

Science Score: 23.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    2 of 2 committers (100.0%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (8.7%) to scientific vocabulary
Last synced: 10 months ago · JSON representation

Repository

Implementation of "TCP" (a reliable transport layer protocol) over UDP with Python socket programming for Vanderbilt University CS 5283 - Computer Networks

Basic Info
  • Host: GitHub
  • Owner: austinjhunt
  • Language: Python
  • Default Branch: master
  • Size: 6.57 MB
Statistics
  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • Open Issues: 0
  • Releases: 0
Created over 4 years ago · Last pushed over 4 years ago
Metadata Files
Readme

README.md

Implementing a Reliable "Stop-and-Wait" Protocol Over UDP (and testing it with an automated framework)

Built for Vanderbilt University CS 5283 Computer Networks - Programming Assignments 2 and 3 - Implementing "TCP" over UDP

Goal: Implement a reliable protocol over UDP

User Datagram Protocol (UDP) is a minimal protocol running over IP. In this assignment you will implement a reliable message protocol over UDP. The assignment is broken into two milestones, representing programming assignments numbered 2 and 3. You will emulate a subset of TCP protocol. Features to be implemented are: - Establish a connections - Ordered data transfer - Retransmission

Tools Used

  • Apache Spark
  • CouchDB
  • Docker-Compose, Docker
  • Socket Programming

Usage Without Docker

All of the main components in the architecture (client, server, channel, aggregator) are controlled via the driver. The following outlines the usage of the driver.

``` (venv) huntaj-imac:src huntaj$ python driver.py -h usage: driver for TCP over UDP simulation [-h] [-c] [-upc UDPPORTCHANNEL] -sleepv CHANNELSLEEPV -sleepf CHANNELSLEEPFACTOR -pds PDROPSERVER -pdc PDROPCLIENT [-cli] [-sip SERVERUDPIP] [-sport SERVERUDPPORT] [-mss MAXSEGMENTSIZE] [-to TIMEOUT] [-f MSG_FILE] [-m MSG_STRING] [-d DUMP_FOLDER] [-cdb] [-srv] [-v] [-agg]

optional arguments: -h, --help show this help message and exit -c, --channel create a channel -upc UDPPORTCHANNEL, --udpportchannel UDPPORTCHANNEL port for binding socket for client <-> channel communication -sleepv CHANNELSLEEPV, --channelsleepv CHANNELSLEEPV small sleep: to reduce latency (can speed testing), set as small as possible (~0.05); to test higher latency channels, try ~0.25; required for all components for data/stats logging purposes -sleepf CHANNELSLEEPFACTOR, --channelsleepfactor CHANNELSLEEPFACTOR max delay as multiple of sleepv; do not set too high, otherwise can cause timeouts; if you see client/server timeouts, may need to adjust timeouts in your client/server; recommended client timeout: ~3s with these default parameters; required for all components for data/stats logging purposes -pds PDROPSERVER, --pdropserver PDROPSERVER probability of channel dropping an ACK from server to client; required for all components for data/stats logging purposes -pdc PDROPCLIENT, --pdropclient PDROPCLIENT probability of channel dropping a message from client to server; required for all components for data/stats logging purposes -cli, --client create a "TCP" over UDP client -sip SERVERUDPIP, --serverudpip SERVERUDPIP IP address of UDP server -sport SERVERUDPPORT, --serverudpport SERVERUDPPORT UDP Server port -mss MAXSEGMENTSIZE, --maxsegmentsize MAXSEGMENTSIZE max number of bytes client can receive or send in single segment -to TIMEOUT, --timeout TIMEOUT socket timeout -f MSGFILE, --msgfile MSGFILE optional with -cli; filename to read from to produce message that gets sent to UDP server -m MSGSTRING, --msgstring MSGSTRING optional with -cli; message to send "reliably" to UDP server -d DUMPFOLDER, --dumpfolder DUMPFOLDER path to folder in which data (times for messages as they relate to channel properties) should be written by the client -cdb, --dumpcouchdb dump time data to couchdb; this depends on COUCHDB* environment variables COUCHDBUSER, COUCHDBSERVER, COUCHDBPASSWORD, COUCHDBDATABASE; only works with --client -srv, --server create a "TCP" over UDP server -v, --verbose use verbose logging -agg, --aggregator run an aggregator (reads from couchdb database using COUCHDB* environment variables to calculate average timeto_ack for each combination of channel properties (sleepv, sleepfactor, pdropserver, pdropclient) using MapReduce `` Execute the following commands from thesrc` folder to create the respective components.

Client

python driver.py --client --channel_sleep_v 0.05 --channel_sleep_factor 4 --p_drop_server 0 --p_drop_client 0 -m "Hello i am trying to send a message" --dump_folder timedata --server_udp_port 5007 --verbose

or, if you'd rather use file contents for a message instead of a string:

python driver.py --client --channel_sleep_v 0.05 --channel_sleep_factor 4 --p_drop_server 0 --p_drop_client 0 -f path/to/file/with/message --dump_folder timedata --server_udp_port 5007 --verbose

Server

python driver.py --server --server_udp_ip 127.0.0.1 --server_udp_port 5008 --verbose --channel_sleep_v 0.05 --channel_sleep_factor 4 --p_drop_server 0 --p_drop_client 0

Channel

python driver.py --channel --channel_sleep_v 0.05 --channel_sleep_factor 4 --p_drop_server 0 --p_drop_client 0 --udp_port_channel 5007 --verbose

Usage with Docker (Recommended, Includes Analytics)

I've created a Docker image using this Dockerfile that can be used to run a client, a server, a channel, or an aggregator. The docker-compose.yml file defines a set of services (containers) that use that Docker image to run some performance tests.

How is it organized?

The docker compose file is ultimately split into 4 categories of services: 1. no-drop-* - this category contains a server, a client, and a channel that does not drop any messages 2. quarter-drop-* - this category contains a server and a client, and a channel configured with a 25% probability of dropping both client messages and server ACKs 3. half-drop-* - this category contains a server and a client, and a channel configured with a 50% probability of dropping both client messages and server ACKs 4. threequarters-drop-* - this category contains a server and a client, and a channel configured with a 75% probability of dropping both client messages and server ACKs

Each of those categories run simultaneously, where each category is a set of services whose intercommunication looks like: client<->channel<->server

Now, the client in each of those categories keeps a record of the channel properties (sleepv, sleepfactor, pdropclient, pdropserver) and also keeps track of the time it takes to successfully send and receive acknowledgment of each message chunk (where max segment size is 12 bytes).

Then, once the full message has been "reliably" sent to the server through the lossy (or non-lossy) channel, the client saves all of those individual times to a CouchDB database (running as a single couchdb service/container).

Obviously, the client in the most lossy category (threequarters-drop-*) will take the longest amount of time to finish saving the data.

Once that happens, it is up to you to log into your CouchDB server's web GUI (http://localhost:5984) using the credentials you can find in the docker-compose file, and simply create a database called 'complete'.

The existence of this new complete database on the CouchDB server will trigger the aggregator service to aggregate the data collected by all of the clients using Map Reduce via Apache Spark.

In short, for each unique tuple of channel properties (sleep_v, sleep_factor, p_drop_client, p_drop_server), the aggregator writes the average time to acknowledgement to a new database called aggregated_analytics.

Steps to Execute

  1. docker-compose up -d from project root
  2. Wait for a little while, monitor container logs with:
    1. docker logs no-drop-client
    2. docker logs quarter-drop-client
    3. docker logs half-drop-client
    4. docker logs threequarters-drop-client
  3. When you see output that looks like: Client - Using DB Info:SERVER:couchdb:5984, USER: admin, Password: 987456321, DB: analytics Client - Connecting to CouchDB server at: http://admin:987456321@couchdb:5984/" Client - Successfully connected to existing CouchDB database analytics Client - Successfully connected to existing CouchDB database analytics Client - Preparing to save 138 items to database Client - Saving completed Client - Failed to save 0 items for the threequarters-drop-client service (the client using the most lossy channel), then you can log into the CouchDB web GUI and create the completed database to trigger the aggregation.
  4. Then, you can look at the aggregator logs to verify that it is running: docker logs aggregator
    1. You will notice that the logs contain a lot of these lines while the aggregator waits on the creation of the 'complete' database in CouchDB: Aggregator - waiting for "complete" database to be created before aggregating data in db analytics Aggregator - waiting for "complete" database to be created before aggregating data in db analytics Aggregator - waiting for "complete" database to be created before aggregating data in db analytics Aggregator - waiting for "complete" database to be created before aggregating data in db analytics Aggregator - waiting for "complete" database to be created before aggregating data in db analytics Aggregator - waiting for "complete" database to be created before aggregating data in db analytics Aggregator - waiting for "complete" database to be created before aggregating data in db analytics
  5. Once you trigger the aggregator, give it a few moments and then go back to the CouchDB web GUI to see the contents of the new aggregated_analytics database, a product of Map Reduce and Apache Spark.

Owner

  • Name: Austin Hunt
  • Login: austinjhunt
  • Kind: user
  • Location: Greenville, SC
  • Company: College of Charleston

Portrait-artist-turned-computer-geek with a fused love for the visual and the technical, bringing experience with and excitement for web dev, automation, & art

GitHub Events

Total
Last Year

Committers

Last synced: 11 months ago

All Time
  • Total Commits: 7
  • Total Committers: 2
  • Avg Commits per committer: 3.5
  • Development Distribution Score (DDS): 0.143
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Austin Hunt h****j@g****u 6
Hunt h****j@c****u 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 11 months ago

All Time
  • Total issues: 0
  • Total pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Total issue authors: 0
  • Total pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels

Dependencies

Dockerfile docker
  • ubuntu latest build
docker-compose.yml docker
  • austinjhunt/py-tcp-over-udp latest
  • couchdb latest
requirements.txt pypi
  • CouchDB ==1.2
  • py4j ==0.10.9.2
  • pyspark ==3.2.0