Professor Instructions----Please follow instructions in the attached PDF. Please test on an ilab machine since i will be testing there.
Internet Technology Rutgers assignment---PYTHON
PLEASE HELP. DUE IN 48 HOURS. THANKS
Sock352.py file
Server1.py file
CS 352 Spring 2017 Programming Project Part 1 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 2) module that uses UDP as the underlying transport protocol. Later versions will add security, port spaces, and concurrency. 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 2. client1.py A Python client program that uses CS 352 sockets. You may not alter the source code for this file 3. serverl.py: APython 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: init(udp_portl, udp_port2) socket() bind (address) connect (address) listen (backlog) accept( close() send (buffer) recv (numBytes) UDP Sockets Figure 1: Layering in CS 352 Sockets 2. 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 UDP ports, one for sending and one for receiving. 3. The 352 RDP v1 protocol: 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 attributepackedsock352 pkt hdr uint8 t version; uint8 t flags; uint8t opt_ptr; uint8_t protocol; uint16 t header_Len; length of the header * uint16t checksum; uint32t source port; source port */ uint32t dest_port; uint64 t sequence no sequence number/ uint64 t ack no; uint32_t window; uint32_t payload Le length of the payload / /*version number *for connection set up, tear-down, control option type between the header and payload/ /* higher-level protocol / /checksum of the packet / /* destination port / ackn /*receiver advertised window in bytes/ nt number */ 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. Note that uintX_t is an X-bit unsigned integer., as defined in
. At the packet level, all these fields are defined to be in network byte-order (big-endian, most significant byte first). 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 librar 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: y: ) A struct object takes a sock352PktHdrDataBBBBHHLLOOLL udpPkt_hdr_datastruct.Struct (sock352PktHdrData) header udpPkt_header_data.pack (version, flags, opt ptr, protocol, checksum, k (version, flags, opt 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 will add port spaces and options. The header_len field will always be set to the size of the header, in 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 will be used in later versions of the protocol. Connection Set-up: 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 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, and 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. Connection termination: Connection termination will follow a similar algorithm as TCP, although simplified. In this model, each side closes it's send side separately, see pages 255-256 of Kurose and Ross and pages 39-40 of Stevens. In version 1, it is OK for the client to end the connection with a FIN bit set when it both gets the last ACK and close has been called. That is, close cannot terminate until the last ACK is received from the server. The sever can terminate the connection under the same conditions. 3. Invoking the client and server: The client and server take a number of arguments -f -d -u (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: server1.py f savedFile.pdf -u 8888 -v 9999 In a second terminal window, run the client: clientl.py d localhost f sendFile.pdf u 9999 -v 8888 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. 4. Grading: Functionality: 80% Style: 20% Functionality: We will run the client.py program using our module (called the 'course client)' against the server.py program using your module (the 'student server), and the client.py using your module (the 'student client) against the server.py linked to our module (course server). We will send a file and see if the checksum on the client and server match the correct checksums. 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. The size of the file may range from a few bytes to many megabytes. There will be a total of 4 tests, as below, and each test is worth 20% of the total grade: (1) student client, course server, in-order packets. (2) course client, student server, in-order packets (3) student client, course server, random 20% packets dropped by the course module. (4) course client, student server, random 20% packets dropped by the course module. 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. 4. What to hand in You must hand in a single archived file, either zip, tar, gzipped tar, bzipped tar or WinRAR (zip,.tar, tgz, .rar) that contains: (1) the client1.py source code, (2) the serverl.py source code, (3) your sock352.py library file, and (4) any other files for your library source code. import binascii import socket as syssock import struct import sys # these functions are global to the class and # define the UDP ports all messages are sent # and received from init (UDPportTX, UDPportRx): pass def # nitialize your UDP socket here class socket: def-init--(self): # fill in your code here return def bind(self,address): return def connect (self, address) : # fill in your code here return def listen (self,backlog): return def accept (self): (clientsocket, address) (1,1) # change this to your code return (clientsocket,address) def close(self): # fill in your code here return def send(self, buffer): return bytesent def recv(self,nbytes): bytessent # fill in your code here bytesreceived 0 # fill in your code here return bytesreceived #1 /usr/bin/python # This is the CS 352 Spring 2017 Client for the 1st programming # project import argparse import time import struct import md5 import os import sock352 def main() # parse all the arguments to the client parser argparse.ArgumentParser(description-'CS 352 Socket Server) parser.add_argument"-f,-filename, help-'Filename to Receiver, required-False) parser .add-argument('-p','--port', help='CS 352 Socket Port (optional for part 1)', required-False) parser.add_ argument(-u', '- -udpportRx', help-'UDP port to use for receiving', required-True) parser.add_ argument(-v', ' - -udpportTx', help-'UDP port to use for sending', required-False) args vars (parser.parseargs) # open the file for writing filename args ['filename'] udpportRx = args [' udpportRx'] if (args['udpportTx']): udpportTxargs['udpportTx'] else udpportTx = '. # the port is not used in part 1 assignment, except as a placeholder if (args[ port']): port - args['port'1 else port 1111 if (filename): try: fdopen(filename, "wb") usefileTrue except: print ( "error opening file: %s" % (filename)) exit(-1) else: pass # This is where we set the transmit and receive # ports the server uses for the underlying UDP # sockets. If we are running the client and # server on different machines, these ports # need to be different, otherwise we can # use the same ports if (udpportTx): sock352.init(udpportTx,udpportRx) else: sock352.init(udpportRx, udpportRx) ssock352.socket() # set the fragment size we will read on FRAGMENTSIZE-4096 # binding the host to empty allows reception on # all network interfaces s.bind(("port)) s.listen(5) # when accept returns, the client is connected (s2,address)s.accept() # this receives the size of the file # as a 4 byte integer in network byte order (big endian) longPackerstruct.Struct("!L") longs2.recv(4) fn-longPackerunpack(long) filelen -fn[0] # the MD5 computes a unique hash for all the data mdhashmd5.new() bytes to receive-filelen start_stamp-time.clock) # main loop to receive the data from the client while (bytes_to_receive > 0): if (bytes_to_receive -FRAGMENTSIZE) fragments2.recv (FRAGMENTSIZE) else: fragment-s2.recv(bytes_to_receive) mdhash.update(fragment) bytes-to-receive bytes-to-receive fd.write(fragment) len(fragment) - end stamp-time.clock() lapsed_seconds end_stamp - start_stamp # finish computing the MD5 hash local_digest - mdhash.digest) # receive the size of the remote hash dllongPacker.unpack (s2.recv(4)) digestlen - dl[e] remote_digest -s2.recv(digestlen) # check is the size matches if (len (remote_digest) !- digestlen): raise RuntimeError("socket error") # compare the two digests, byte for byte for i, server_byte in enumerate(local_digest): client_byte - remote_digest[il if (client_byte-server_byte): print( "digest failed at byte %d %c %c (i,client-byte, server-byte)) " % if (lapsed seconds0.0): print ("server!: received %d bytes in %0.6f seconds, %0.6f MB/s (filelen, lapsed-seconds, " % (filelen/lapsed_seconds)/(1024 1024))) else: print fd.close() s2.close) ("server!: received %d bytes in %d seconds, inf MB/s (filelen, lapsed-seconds)) " % CS 352 Spring 2017 Programming Project Part 1 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 2) module that uses UDP as the underlying transport protocol. Later versions will add security, port spaces, and concurrency. 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 2. client1.py A Python client program that uses CS 352 sockets. You may not alter the source code for this file 3. serverl.py: APython 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: init(udp_portl, udp_port2) socket() bind (address) connect (address) listen (backlog) accept( close() send (buffer) recv (numBytes) UDP Sockets Figure 1: Layering in CS 352 Sockets 2. 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 UDP ports, one for sending and one for receiving. 3. The 352 RDP v1 protocol: 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 attributepackedsock352 pkt hdr uint8 t version; uint8 t flags; uint8t opt_ptr; uint8_t protocol; uint16 t header_Len; length of the header * uint16t checksum; uint32t source port; source port */ uint32t dest_port; uint64 t sequence no sequence number/ uint64 t ack no; uint32_t window; uint32_t payload Le length of the payload / /*version number *for connection set up, tear-down, control option type between the header and payload/ /* higher-level protocol / /checksum of the packet / /* destination port / ackn /*receiver advertised window in bytes/ nt number */ 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. Note that uintX_t is an X-bit unsigned integer., as defined in . At the packet level, all these fields are defined to be in network byte-order (big-endian, most significant byte first). 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 librar 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: y: ) A struct object takes a sock352PktHdrDataBBBBHHLLOOLL udpPkt_hdr_datastruct.Struct (sock352PktHdrData) header udpPkt_header_data.pack (version, flags, opt ptr, protocol, checksum, k (version, flags, opt 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 will add port spaces and options. The header_len field will always be set to the size of the header, in 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 will be used in later versions of the protocol. Connection Set-up: 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 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, and 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. Connection termination: Connection termination will follow a similar algorithm as TCP, although simplified. In this model, each side closes it's send side separately, see pages 255-256 of Kurose and Ross and pages 39-40 of Stevens. In version 1, it is OK for the client to end the connection with a FIN bit set when it both gets the last ACK and close has been called. That is, close cannot terminate until the last ACK is received from the server. The sever can terminate the connection under the same conditions. 3. Invoking the client and server: The client and server take a number of arguments -f -d -u (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: server1.py f savedFile.pdf -u 8888 -v 9999 In a second terminal window, run the client: clientl.py d localhost f sendFile.pdf u 9999 -v 8888 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. 4. Grading: Functionality: 80% Style: 20% Functionality: We will run the client.py program using our module (called the 'course client)' against the server.py program using your module (the 'student server), and the client.py using your module (the 'student client) against the server.py linked to our module (course server). We will send a file and see if the checksum on the client and server match the correct checksums. 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. The size of the file may range from a few bytes to many megabytes. There will be a total of 4 tests, as below, and each test is worth 20% of the total grade: (1) student client, course server, in-order packets. (2) course client, student server, in-order packets (3) student client, course server, random 20% packets dropped by the course module. (4) course client, student server, random 20% packets dropped by the course module. 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. 4. What to hand in You must hand in a single archived file, either zip, tar, gzipped tar, bzipped tar or WinRAR (zip,.tar, tgz, .rar) that contains: (1) the client1.py source code, (2) the serverl.py source code, (3) your sock352.py library file, and (4) any other files for your library source code. import binascii import socket as syssock import struct import sys # these functions are global to the class and # define the UDP ports all messages are sent # and received from init (UDPportTX, UDPportRx): pass def # nitialize your UDP socket here class socket: def-init--(self): # fill in your code here return def bind(self,address): return def connect (self, address) : # fill in your code here return def listen (self,backlog): return def accept (self): (clientsocket, address) (1,1) # change this to your code return (clientsocket,address) def close(self): # fill in your code here return def send(self, buffer): return bytesent def recv(self,nbytes): bytessent # fill in your code here bytesreceived 0 # fill in your code here return bytesreceived #1 /usr/bin/python # This is the CS 352 Spring 2017 Client for the 1st programming # project import argparse import time import struct import md5 import os import sock352 def main() # parse all the arguments to the client parser argparse.ArgumentParser(description-'CS 352 Socket Server) parser.add_argument"-f,-filename, help-'Filename to Receiver, required-False) parser .add-argument('-p','--port', help='CS 352 Socket Port (optional for part 1)', required-False) parser.add_ argument(-u', '- -udpportRx', help-'UDP port to use for receiving', required-True) parser.add_ argument(-v', ' - -udpportTx', help-'UDP port to use for sending', required-False) args vars (parser.parseargs) # open the file for writing filename args ['filename'] udpportRx = args [' udpportRx'] if (args['udpportTx']): udpportTxargs['udpportTx'] else udpportTx = '. # the port is not used in part 1 assignment, except as a placeholder if (args[ port']): port - args['port'1 else port 1111 if (filename): try: fdopen(filename, "wb") usefileTrue except: print ( "error opening file: %s" % (filename)) exit(-1) else: pass # This is where we set the transmit and receive # ports the server uses for the underlying UDP # sockets. If we are running the client and # server on different machines, these ports # need to be different, otherwise we can # use the same ports if (udpportTx): sock352.init(udpportTx,udpportRx) else: sock352.init(udpportRx, udpportRx) ssock352.socket() # set the fragment size we will read on FRAGMENTSIZE-4096 # binding the host to empty allows reception on # all network interfaces s.bind(("port)) s.listen(5) # when accept returns, the client is connected (s2,address)s.accept() # this receives the size of the file # as a 4 byte integer in network byte order (big endian) longPackerstruct.Struct("!L") longs2.recv(4) fn-longPackerunpack(long) filelen -fn[0] # the MD5 computes a unique hash for all the data mdhashmd5.new() bytes to receive-filelen start_stamp-time.clock) # main loop to receive the data from the client while (bytes_to_receive > 0): if (bytes_to_receive -FRAGMENTSIZE) fragments2.recv (FRAGMENTSIZE) else: fragment-s2.recv(bytes_to_receive) mdhash.update(fragment) bytes-to-receive bytes-to-receive fd.write(fragment) len(fragment) - end stamp-time.clock() lapsed_seconds end_stamp - start_stamp # finish computing the MD5 hash local_digest - mdhash.digest) # receive the size of the remote hash dllongPacker.unpack (s2.recv(4)) digestlen - dl[e] remote_digest -s2.recv(digestlen) # check is the size matches if (len (remote_digest) !- digestlen): raise RuntimeError("socket error") # compare the two digests, byte for byte for i, server_byte in enumerate(local_digest): client_byte - remote_digest[il if (client_byte-server_byte): print( "digest failed at byte %d %c %c (i,client-byte, server-byte)) " % if (lapsed seconds0.0): print ("server!: received %d bytes in %0.6f seconds, %0.6f MB/s (filelen, lapsed-seconds, " % (filelen/lapsed_seconds)/(1024 1024))) else: print fd.close() s2.close) ("server!: received %d bytes in %d seconds, inf MB/s (filelen, lapsed-seconds)) " %