CS 352 Fall 2019 Programming

Project Part 2

Python代码编写 For part 1 of the project, your team will implement a simple go-back-N protocol similar to TCP. This protocol is called the…

  1. Overview:

For part 1 of the project, your team will implement a simple go-back-N protocol similar to TCP. This protocol is called the 352 Reliable Data Protocol (RDP) version 1 (352 RDP v1). You will realize it as a Python (version 3) module that uses UDP as the underlying transport protocol. Later versions will add other features like security, flow control and congestion control.

As part of the project part 1, you will be given 3 files. You can find them in the Sakai site under

“Resources” -> “Project resources” -> “Part 1” .

  1.  sock352.py : This is a skeleton definition of the class and methods you need to write. You should modify this file with your implementation. That is, fill in the methods with your own code.
  1.  client1.py : A Python client program that uses CS 352 sockets. You may not alter the source code for this file.
  1.  server1.py: A Python server program that uses CS 352 sockets. You may not alter the source code for this file.

Your library must implement the following methods as defined in the sock352.py file, note that some of the functions may not require you to do anything: Python代码编写

init (udp_port1, udp_port2)

socket ()

bind (address)

connect (address)

listen(backlog)

accept ()

close ()

send (buffer)

recv (numBytes)

Python Version: Python代码编写

I strongly recommend you use python 3. Whichever version you use you must tell us in the readme file.

These function map to the existing Python methods for sockets. See this link:

https://docs.python.org/2/howto/sockets.html for the definitions of these functions. The one exception init() call. This call takes two parameters, which are the UDP port that the rest of the CS 352 RDP library will use for communication between hosts, one is for receiving and one is for sending. Setting the udp_port to zero should use the default ports of your choosing.

For part 1 of the project, you will only need to make a single connection work over a single set of ports  for a single thread. The goal is to correctly implement a go-back-N protocol for one connection, for example, when sending a single file between a client and server.

Python代码编写
Python代码编写

Figure 1: Layering in CS 352 Sockets

  1. Architecture

Figure 1 shows the architecture of the 352 socket layer. All communications go through a single UDP socket. A set of ports which are managed by 352 sockets exists on top of the UDP socket.

To allow 2 instances of 352 sockets to communicate on the same machine, 2 UDP sockets must be used, one for each instance. As these can not have the same UDP port number, they must have different port numbers. In this case, each instance must use 2 different UDP ports, one for sending and one for receiving.

  1. The 352 RDP v1 protocol: Python代码编写

Recall as in TCP, 352 RDP v1 maps the abstraction of a logical byte stream onto a model of an unreliable packet network. 352 RDP v1 thus closely follows TCP for the underlying packet protocol. A connection has 3 phases: Set-up, data transfer, and termination. 352 RDP v1 uses a much simpler timeout strategy than TCP for handling lost packets.

Packet structure:

The CS 352 RDP v1 packet as defined as a C structure, which must be translated into a Python

struct:

/* a CS 352 RDP protocol packet header */ struct 

__attribute__ ((__packed__)) sock352_pkt_hdr { uint8_t

version; /* version number */

uint8_t flags                          ; /* for connection set up, tear-down, control */

uint8_t opt_ptr                       ; /* option type between the header and payload*/

uint8_t protocol                     ; /* higher-level protocol */

uint16_t header_len              ; /* length of the header */

uint16_t checksum                 ; /* checksum of the packet */

uint32_t source_port              ; /* source port */

uint32_t dest_port                  ; /* destination port */

uint64_t sequence_no           ; /* sequence number */

uint64_t ack_no                     ; /* acknowledgement number */

uint32_t window                   ; /* receiver advertised window in bytes*/

uint32_t payload_len            ; /* length of the payload*/

}; typedef  struct  sock352_pkt_hdr sock352_pkt_hdr_t ; /* typedef shortcut */

Fields in Red (version,flags,header_len,sequence_no,ack_no,payload_len) must be filled in correctly in part 1, while the Blue fields can be ignored for this part of the project. They should still be included in the struct, but they should always hold zero.

Note that uintX_t is an X-bit unsigned integer., as defined in <sys/types.h>. At the packet level, all these fields are defined to be in network byte-order (big-endian, most significant byte first). Python代码编写

In Python, you will need to use the struct module to pack and unpack binary data (see this link for a description of the struct library: https://docs.python.org/2/library/struct.html ) A struct object takes a formating string and allows you to create a binary object based on the format and Python variables. This is called a pack operation. The inverse, or unpack, takes a binary object and unpacks it into a set of Python variables. Recall for the format string, B = Byte, H = Half-Word (16 bits) , L=Long (32 bits) Q=Quad (64bits), and the “!” means use network byte order. Some example code to pack a CS 352 packet header might look like this:

sock352PktHdrData = '!BBBBHHLLQQLL'

udpPkt_hdr_data = struct.Struct(sock352PktHdrData)

header = udpPkt_header_data.pack(version, flags, opt_ptr, protocol, checksum,source_port, dest_port, sequence_no, ack_no, window, payload_len)

For part 1, in the packet, the version field should be set of 0x1. The protocol, opt_ptr, source_port and dest_port fields should all be set to zero. Future versions of the protocol might add port spaces and options. The header_len field will always be set to the size of the header, in bytes.

An address for the CS 352 RDP is slightly different from the normal socket address, as found in the sock352.h file. The main difference is the addition of a port layer on top of the UDP port space, as seen in the cs352_port field. This might be used in later versions of the protocol.

Connection Set-up: Python代码编写

352 RDP follows the same connection management protocol as TCP. See Chapter 3.5.6, pages 252-258 of Kurose and Ross for a more detailed description. The version field of the header should always be set to 1.

Flags:

The bit flags needed are set in the flags field of the packet header. The exact bit definitions of the flags are:

Flag Name                           Byte Value (Hex)                      Byte Value (Binary)                           Meaning

SOCK352_SYN                     0x01                                         00000001                                         Connection

initiation

SOCK352_FIN                      0x02                                         00000010                                          Connection end

SOCK352_ACK                     0x04                                         00000100                                         Acknowledgement #

SOCK352_RESET                  0x08                                         00001000                                         Reset                the

connection

SOCK352_HAS_OPT            0xA0                                         00010000                                          Option field is valid

The client initiates a connection by sending a packet with the SYN bit set in the flags field, picking a random sequence number, and setting the sequence_no field to this number. If no connection is currently open, the server responds with both the SYN and ACK bits set, picks a random number for it’s sequence_no field and sets the ack_no field to the client’s incoming sequence_no+1 . If there is an existing connection, the server responds with the sequence_no+1 , but the RESET flag set.

Data exchange: Python代码编写

352 RDP follows a simplified Go-Back-N protocol for data exchange, as described in section Kurose and Ross., Chapter 3.4.3, pages 218-223 and extended to TCP style byte streams as described in Chapter 3.5.2, pages 233-238.

When the client sends data, if it is larger than the maximum UDP packet size (64K bytes), it is first broken up into segments, that is, parts of the application byte-stream, of up to 64K. If the client makes a call smaller than 64K, then the data is sent in a single UDP packet of that size, with the payload_len field set appropriately. Segments are acknowledged as the last segment received inorder (that is, go-back-N). Data is delivered to the higher level application in-order based on the recv() calls made. If you are having difficulties you can try 32k maximum packet size instead of 64k, this sometimes helps.

For CS 352 RDP version 1, the window size can be ignored, this means we are assuming the size of the window is always greater than the total amount of data to be sent.

Here is a simulation to help you understand what is going on:

http://www.ccs-labs.org/teaching/rn/animations/gbn_sr/

Timeouts and retransmissions:

352 RDP v1 uses a single timer model of timeouts and re-transmission, similar to TCP in that there should be a single timer per connection, although each segment has a logical timeout. The timeout for a segment is 0.2 seconds. That is, if a packet has not been acknowledged after 0.2 seconds it should be re-transmitted, along with any packets sent afterwards as per go back N. The logical timeout would be set again set to 0.2 seconds in the future for that segment. The timeout used for a connection should be the timeout of the oldest segment.

There are two strategies for implementing timeouts. One approaches uses Unix signals and other uses a separate thread. These will be covered in class and recitation. I strongly recommend using a seperate thread to receive acknowledgments and keep track of timeouts and sending data on the first thread.

Connection termination:

Connection termination will follow a similar algorithm to TCP, first one side sends a message with FIN bit set, then the other side replies with FIN and ACK set, then the first side replies with ACK set.

  1. Invoking the client and server: Python代码编写

The client and server take a number of arguments :

-f <the file name to send or to save>

-d <the destination host to send to>

-u <the UDP port to use for receiving>

-v <the UDP port to use for sending> (optional)

If you are running both the client and server on the same machine, you would, for example, in one terminal window, first run the server:

server2.py -f savedFile.pdf -u 8888 -v 9999

In a second terminal window, run the client:

client2.py -d localhost -f sendFile.pdf -u 9999 -v 8888

NOTE: When testing please retype the commands as copy-pasting from PDF files may work  strangely

Notice how the send and receive ports are swapped. If we were running on different machines, a single UDP socket (port) could be used for both sending and receiving.Remember to find a way to test what happens when packets are dropped and to test with files ranging from a few bytes to many megabytes.

  1. New In Part 2

Since we are doing flow control, the receiver must keep a buffer of received data, every me recv is called, the specified amount of data is returned and removed from the buffer. The buffer is of size W,W=262kb for this project. If the buffer is empty and recv is called, wait until there is something to return. Alternately, if there is no more room in the buffer, send() calls by the sender should not return or send anything until there is room. This is kept track of by the widow size field of each packet as in real TCP. Whenever you send an ack, include the room in your buffer at the moment in the window feild as in real tcp. Lastly, you must send an ack when your buffer gets more room even if you did not get any packets.

Note that just like real TCP this is a sliding window protocol and you must never send more packets than will fit in the buffer.

  1. Grading: Python代码编写

Functionality: 80% Style: 20%

Functionality:

We will run the client.py program and the server.py program on different, or possibly the same, machines. The client.py program opens a single file, sends to the server, and then both close the socket and exit. See the source code for more details. They will both run on ilab machines. The size of the file may range from a few bytes to many megabytes. We will then use checksums to make sure the entire file has sent correctly. We will insert pauses into the program to make sure that you don’t send packets when the window is full, and that you start again when the window is empty. Part 1 needs to be working in order to pass the part 2 tests.

ASSUME ANY CODE THAT HAS NOT BEEN TESTED ON AN ILAB MACHINE DOES NOT WORK

Style:

Style points are given by the instructor and TA after reading the code. Style is subjective, but will be graded on a scale from 1-5 where 1 is incomprehensible code and 5 means it is perfectly clear what the programmer intended. Style points may also be taken off for things like not exiting properly or other minor functional problems.

  1. What to hand in Python代码编写

You must hand in a single file, either zip, tar, gzipped tar, bzipped tar or WinRAR (.zip, .tar, .tgz, .rar) that contains: (1) your sock352.py library file, and (2) any other files for your library source code. (3)A README file.

更多代写:JavaScript代写 多邻国代考 finance代写 英文文献引用 accounting代写 美国report代写