This is an old version of this course, from Fall 2015. A newer version is available here.
Jump to this week's part
Week 3 - Design
This week, I want you to submit your solution to the in-class exercise:
A message has a four-byte header with the number of lines in a text file as a binary number (the number taking all four bytes, and is in the standard network byte order, that is, big-endian).
Then, the lines follow, each terminated by '\n', that is, a new-line character.
Suppose you can get one byte (single-byte string) of the message by calling next_byt(). There are no other ways to access the bytes in the message. There is no has_next_byte() method. Here's a full comment for next_byte:
# 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 string of one character. def next_byte():
Your solution will be Python code, consisting of multiple methods. Put your top-level method first in the file. This should call other helper methods, which may call other helper methods as well.
In a comment above each method, include the author's name, with each team-member being the primary author for at least one method. You may also find it helpful to also document the method, clearly stating what the input and output values are required.
You do not need to run the code — it is OK if simple errors cause your code not to run at all. In fact, you really CAN'T run your code, since it relies on the next_byte() method, which is not available in Python. You don't even need to import everything needed by your code.
Next week's lab will be to run the code. Together, the two labs will count as one lab, with this week's for 20%, and next week's for 80% of the lab.
I will consider these quality factors when grading this week's lab, starting with the most important:
- How well does the code break the large task into smaller sub-tasks? Has each lab member written at least one method as primary author?
- Does the code read in the specified message format, without reading past the end of the file?
- Does the code illustrate an understanding of how bytes and numbers are represented and converted in Python?
- Does the code illustrate understanding of python syntax and types?
Week 4 — Implementation and Testing
In this part of the lab, you will send TCP messages between machines. Start from the template tcp.py.
This is a team assignment; each team should be two members unless a different size is approved by the instructor.
The goal of this lab is to write a Python program, to send and receive network messages using the TCP protocol.
The program has at least the following functions; 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 send by the server. Report the status to the user (e.g. "File accepted")
- Close sockets and exit.
- Ask client if s/he 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. The format of the messages is the num-lines and line-endings format used in class.
The application protocol is a simple format: For each file uploaded, the client first sends four (big-endian) bytes indicating the number of lines as an unsigned binary number.
The client then sends each of the lines, terminated only by '\n'.
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" if it accepts the file. (And "R" if it rejects it — though you are not required to reject any files.)
The server then waits for the client to send the next file
- Arguments:
- listen_port: integer designating receiving port number
- This port will likely have to be above the "system" range (0-1023).
- listen_port: integer designating receiving port number
- Operation:
- Connect to the specified listening port
- Accept a connection
- Forever:
- 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.
- (because loop never terminates, you don't need to close any sockets)
The provided next_byte function is shown below. This method is also included in the latest version of tcp.py. Unlike the "magic" method you used in your designs, this method requires a tcp data connection to operate. See the procedure below for changes you will need to make to your code to accommodate this.
# 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. # # Returns the next byte, as a string of one character. # # 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. # def next_byte(data_socket): return data_socket.recv(1)
This method is included in the latest version of the tcp.py template.
For Lab Section 011: (Tuesday Morning). If you have an old version of tcp.py, please replace the comment at the header with this comment:
# Listen for a TCP connection on a designated "listening" port # Accept the connection, creating a connection socket # Print the address and port of the sender # Repeat Forever: # Receive a message, saving it to a text-file (1.txt for first file, 2.txt for second file, etc.) # Send a single-character response 'A' to indicate that the upload was accepted. def tcp_receive(listen_port):
This comment is already included in the latest version of the tcp.py template.
Again for Section 011, please either use the new template or add the newline +'\n'
to the end of lines sent by the client:
for line_num in range(0,num_lines): line = raw_input('') tcp_socket.sendall(line+'\n')
Finally, for everyone, here is a simple example of writing a text-file in Python, taken verbatim from tutorialspoint.com. Note the use of "b" for binary mode. Please use this, even if you are on a linux machine, so that your code will work when tested on my Windows machine. 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 fo = open("foo.txt", "wb") fo.write( "Python is a great language.\nYeah its great!!\n"); # Close opend file fo.close()
Procedure
- Download the skeleton Python template: tcp.py
- Edit the header of the file to include your team members' names.
- 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.
- (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.
- Test that you are able to get ANY information through the TCP connection
- Work out any bugs in your algorithm so the server meets the specification and can read multiple messages from the client.
- Finally, add comments at the end of your Python file, with the following information:
- A description of the functionality you implemented and the results of your testing.
- Comments on your experience in completing the lab, including any problems you encountered. Briefly explain what you learned.
- Questions and suggestions.
If this base functionality turns out to be too easy, you may experiment with adding additional functions, but be sure the basic requirements are still met.
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. Optional: Demonstrate your working software to the instructor.
(Acknowledgements: The original version of this lab written by Dr. Sebern.)
Submission Instructions for Dr. Yoder
Part A: Design Submission (Due Week 3, Friday, 11pm)
Submit your lab design electronically before the deadline listed above.
Part A Submission closed. Email me any late submissions, attaching the design.py file.