CS2911
Network Protocols

This is an old version of this course, from Fall 2016. A newer version is available here.

Resources

You can work the entire lab (except the demo) as prelab. Although this is not required, I recommend it because Lab 5 (HTTP) is one of the hardest labs of the quarter. Please work in teams of two unless approved by the instructor. Please submit only one report per team.

Assignment

In this week's lab, you will send messages between machines using TCP. Start from the template tcp.py and your code from last week. In this lab, the server receives the messages using your code from last week. The client code that sends the messages is provided in the template.

This is a team assignment; each team should be two members unless a different size is approved by the instructor.

The program has at least the following methods; you should add others to improve the modularity of your procedures.

main()

This method is provided in its entirety in the template.

Prompts the user for the network operation to perform (tcp send or tcp receive) and then calls the selected function with appropriate argument values (as specified in the constants at the start of the program)

  • This method is invoked with a main() function call at the end of the program.

tcp_send(server_host, server_port, message)

This method is provided in its entirety in the template.

This method creates a single TCP connection to the already-waiting server and sends multiple files to the server. It checks the single-character status received from the server and displays it to the user.

  • Arguments:
    • server_host: string with destination IP address or host name
    • server_port: integer designating destination port number
      • This port will likely have to be above the "system" range (0-1023).
  • Operation:
    • Prompt the user for the number of lines to send. Pack and send this number as a four-byte big-endian unsigned integer
    • Prompt the user for each line. Send each line as it is written.
    • Await the status byte sent by the server. Report the status to the user (e.g. "File accepted")
    • Close sockets and exit.
    • Ask client if he/she would like to send another message.

tcp_receive(listen_port)

Listen for a TCP connection on a specified port, receive and display multiple messages from a single client over a single socket, and send a one-character response.

Multiple files will be sent, each as a separate message over the same TCP channel.

For each file uploaded, the same format is used as in last week's lab: the client first sends four (big-endian) bytes indicating the number of lines as a binary number. The client then sends each of the lines as ASCII text, terminated only by '\n'.

Multipe messages are sent over the same TCP connection. The server saves the file with a sequential number — 1.txt for the first upload, 2.txt for the second upload, etc.

The server responds with "A" to indicate it accepts the file, or "Q" to indicate it is quitting if the file contains zero lines. You may optionally save the zero-line message or not.

The server then waits for the client to send the next file, or closes the connection if the file contained zero lines.

  • Arguments:
    • listen_port: integer designating receiving port number
      • This port will likely have to be above the "system" range (0-1023). Port numbers in the System range can usually only be opened by a program running as Administrator or root.
  • Operation:
    • Connect to the specified listening port
    • Accept a connection
    • Until a zero-line message is received:
      • Receive a message
      • Save the message, the first message to the file 1.txt, the next message to the file 2.txt, etc. Files uploaded over previous socket connections are overwritten.
      • Send a single-character response.
    • Close the sockets

The provided next_byte function is shown below. This method is also included in the template tcp.py. Unlike the "magic" method you used in your designs, this method requires a tcp data connection to operate. As described in the procedure below, you will need to pass extra arguments to get the data socket to the next_byte calls. Do not use global variables.

# Read the next byte from the socket data_socket.
# The data_socket argument should be an open tcp data connection socket, not a tcp listening socket.
#
# Read the next byte from the server.
# If the byte is not yet available, this method blocks (waits)
#   until the byte becomes available.
# If there are no more bytes, this method blocks indefinitely.
#
# Returns the next byte, as a bytes object with a single byte in it
# 
def next_byte(data_socket):
   return data_socket.recv(1) 

This method is included in the tcp.py template.

Below is a simple example of writing a text-file in Python, taken from tutorialspoint.com and updated to Python 3. Note the use of "b" for binary mode. Please use this, even if you are on a linux machine. In Python 3 (on any platform), you must use binary mode if you wish to write raw bytes to a file. If you open a file in text mode, it will automatically encode the text in UTF-8. On Windows machine, if you write in text mode (without the b), '\n' is converted to '\r\n', which may not be what you intend — especially in next week's lab when you write binary image data to files.

#!/usr/bin/python

# Open a file
output_file = open("foo.txt", "wb")
# We are writing raw bytes (plain ASCII text) to the file
# If you open the file in binary mode,
# you must write a bytes object, not a str.
# (This is a very good thing!)
output_file.write(b"Python is a great language.\nYeah it's great!!\n")

# Close file
output_file.close()

This example code is not included in the tcp.py template. For (way too much) more information, see the documentation of the Python 3 open method.

Procedure 

  1. Download the skeleton Python template: tcp.py
  2. Edit the header of the file to include your team members' names.
  3. Adapt your design from last week to the body of tcp.py. You will need to pass extra arguments to get the data socket to the next_byte calls. Do not use global variables!
  4. (optional) Use Wireshark to view the messages as they travel between nodes. You may want to filter the messages with a filter like ip.addr==192.185.16.126, where you replace 192.185.16.126 with the IP address of the other machine. This might help with debugging.
  5. Test that you are able to get ANY information through the TCP connection
  6. Work out any bugs in your algorithm so the server meets the specification and can read multiple messages from the client.

Divide up the primary responsibility for parts of the program in an equitable way. Each team member should be given at least one method to write. In the comments for the method, include the author of the method like this: # Author: Phileas Fogg

Test your software by running two copies of the program on two different systems (network nodes). For debugging purposes, you may wish to test your program on your local machine with localhost.

(Acknowledgements: This lab written by Dr. Sebern and Dr. Yoder)