Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

+ -------------------------------------------------------------------------------------------------------------- RDTSend.py from socket import * import threading import struct import sys import random # simulate packet loss def lostPacket(seq_num): prob = random.random() if

image text in transcribed+

image text in transcribed

image text in transcribed

--------------------------------------------------------------------------------------------------------------

RDTSend.py

from socket import * import threading import struct import sys import random

# simulate packet loss def lostPacket(seq_num): prob = random.random() if prob

# set timer to receive correct ACK def recvAckTimeout(t, sender_socket, seq_num, unpacker): isTimeout = False data_recv = None

def funcTimeout(): nonlocal isTimeout isTimeout = True

# start funcTimeout() after t seconds timer = threading.Timer(t, funcTimeout) timer.start()

# set recv to be non-blocking, so as to keep fetching pkt from buffer sender_socket.setblocking(0)

while isTimeout is False: try: data_recv, _ = sender_socket.recvfrom(1024) except BlockingIOError: pass

if data_recv is not None: try: unpacked_data = unpacker.unpack(data_recv) except struct.error as emsg: print("Unpack data error: ", emsg) sys.exit(1)

# receive wrong ACK from sender if unpacked_data[0] != seq_num: print("\t Receive wrong ACK for seq num %d" % seq_num) # receive correct ACK and stop timer else: print("\t Receive ACK for seq num %d" % seq_num) timer.cancel() return False return True

#send packet with seq_num def sendPacket(sender_socket, RECV_IP, RECV_PORT, pkt, seq_num, packer, unpacker): packed_data = None while True: try: # pack data into binary if packed_data is None: packed_data = packer.pack(seq_num, bytes(pkt, encoding='utf-8')) except struct.error as emsg: print("Pack data error: ", emsg) sys.exit(1) if lostPacket(seq_num) is False: try: sender_socket.sendto(packed_data, (RECV_IP, RECV_PORT)) print('Packet (seq num: %d) sent' % seq_num) except error as emsg: print("Socket send error: ", emsg) sys.exit(1) if recvAckTimeout(2, sender_socket, seq_num, unpacker): print('\t Receive ACK timeout, resending packet (seq num: %d) ...' % seq_num) continue else: break

def main(argv): SEND_IP = "127.0.0.1" SEND_PORT = 6666

RECV_IP = "127.0.0.1" RECV_PORT = 7777

try: sender_socket = socket(AF_INET, SOCK_DGRAM) sender_socket.bind( (SEND_IP, SEND_PORT) ) except error as emsg: print("Socket error: ", emsg) sys.exit(1)

# define the format of send/receive packets try: packer = struct.Struct('I 32s') unpacker = struct.Struct('I') except struct.error as emsg: print("Struct error: ", emsg) sys.exit(1) try: f = open(argv[1]) contents = f.read() except IOError as emsg: print("File IO error: ", emsg) sys.exit(1) pkt_data = [contents[i:i+32] for i in range(0, len(contents), 32)] f.close() # stop-wait using seq num seq_num = 0 for pkt in pkt_data: sendPacket(sender_socket, RECV_IP, RECV_PORT, pkt, seq_num, packer, unpacker) seq_num = 1 if seq_num == 0 else 0

sender_socket.close()

if __name__ == '__main__': if len(sys.argv) != 2: print("Usage: python3 RDTSend.py ") sys.exit(1) main(sys.argv)

--------------------------------------------------------------------------------------------------------------------------------------

RDTRecieve.py :

from socket import * import sys import struct import random

def lostACK(seq_num): prob = random.random() if prob

def main(argv): SEND_IP = "127.0.0.1" SEND_PORT = 6666

RECV_IP = "127.0.0.1" RECV_PORT = 7777

try: receiver_socket = socket(AF_INET, SOCK_DGRAM) receiver_socket.bind( (RECV_IP, RECV_PORT) ) except error as emsg: print("Socket error: ", emsg) sys.exit(1)

try: packer = struct.Struct('I') unpacker = struct.Struct('I 32s') except struct.error as emsg: print("Struct error: ", emsg) sys.exit(1) try: f = open("recv.txt", 'w') except IOError as emsg: print("File IO error: ", emsg) sys.exit(1)

expt_seq_num = 0

receiver_socket.settimeout(10)

while True: try: data, _ = receiver_socket.recvfrom(1024) except timeout: print('Socket timeout, terminate the receiver program.') break

# unpack received data

# if packet received has expected seq_num, decode and write the content into #the aboved opened file print("Receive expected packet with seq num: %d" % expt_seq_num) # create corresponding ACK # send the ACK to the sender if lostACK() returns false print("\t ACK %d sent to the client" % expt_seq_num) # change expected sequence number for next packet # if packet received has wrong seq_num, resend previous ack print("Receive unexpected packet with wrong seq_num, resending previous ACK ...") prev_seq_num = 1 if expt_seq_num == 0 else 0 print("\t ACK %d resent to the client" % prev_seq_num) f.close() receiver_socket.close()

if __name__ == '__main__': if len(sys.argv) > 1: print("Usage: python3 RDTReceive.py") sys.exit(1) main(sys.argv)

--------------------------------------------------------------------------------------------------------------

hku.txt

The University of Hong Kong (HKU) is a public research university in Hong Kong. Founded in 1911, its origins trace back to the Hong Kong College of Medicine for Chinese, which was founded in 1887. It is the oldest tertiary institution in Hong Kong. HKU was also the first university established by the British Empire in East Asia. As of 2020, HKU ranks third in Asia and 22nd internationally by QS, and fourth in Asia and 35th internationally by THE. It has been commonly regarded as one of the most internationalized universities in the world as well as one of the most prestigious universities in Asia. Today, HKU has ten academic faculties with English as the main language of instruction. HKU also ranks highly in the sciences, dentistry, biomedicine, education, humanities, law, economics, business administration, linguistics, political science, and the social sciences. The origins of The University of Hong Kong can be traced back to the Hong Kong College of Medicine for Chinese founded in 1887 by Ho Kai later known as Sir Kai Ho Kai, which was later incorporated as the university's faculty of medicine. It was renamed the Hong Kong College of Medicine in 1907. The college became HKU's medical school in 1911.

Introduction In this lab, we will use Python socket programming to implement a simple application-layer stop-and-wait RDT protocol. We have introduced in lectures that the transport-layer protocol, UDP, does not implement RDT, and applications can implement their RDT protocol over UDP. In this lab exercise, we are going to implement a stop-and-wait RDT protocol between a sender program and a receiver program, which communicate over UDP sockets. The simple RDT pro- tocol is similar to RDT 3.0 with sequence number, timer, ACK and retransmission, but without checksum (i.e., we consider the channel may lose data/ACK packets but does not flip bits in the packets). Step 2: Open RDTSend.py using a text editor, which contains the complete implementation of the sender program. The sender reads a file (e.g., hku.txt) and sends the file contents to the receiver using a protocol similar to RDT 3.0's sender protocol (except for using checksum). Study the sender program carefully. You will learn how file content is packed together with sequence number into binary data to be sent through UDP socket. a. The sender is to be started by command python3 RDTSend.py . By default, you can run both the sender program and the receiver program on the same machine, i.e., using localhost 127.0.0.1"; data packets are sent from the sender's port 6666 to the receiver's port 7777, and ACK packets are sent from the receiver's port 7777 to the sender's port 6666. b. In the main function, we use the struct module to pack packet contents into binary data. For example, I represents an unsigned integer number and 32s means a 32byte-long string. With packer = struct.Struct('I 32s'), we create a Struct object which we will use to pack an unsigned integer number and a 32-byte string together; with unpacker = struct.Struct('I')", we create a Struct object which we will use to unpack received binary data into an unsigned integer number. The sender reads contents from the file provided and stores them as 32-byte strings into array pkt data.The sender adopts sequence numbers 0 and 1 to send all strings by calling sendPacket() function multiple times. c. In sendPacket() function, the sender constructs a data packet by packing the sequence number and the 32-byte string (which is converted to bytes first using bytes() function), sends it to the receiver and starts a timer (in recvAckTimeouto function), with default timeout of 2 seconds. The Python built-in function bytes() is used to return an immutable bytes object initialized with the given data. d. In recvAckTimeout() function, a timer is created, which is a Timer object in the threading module, and started using the start() function. The function funcTimeout is invoked when the timer times out. The sender then waits for ACK from the receiver. We set the sender socket to be in the nonblocking mode, in order to allow the sender to stop sender socket.recyfrom( upon timer timeout (by default the socket recyfrom function is in blocking mode, such that it will keep waiting for data from the sender). The sender uses unpack() function to unpack received binary data into a tuple whose entries correspond to the original packed items in the received packet; in our case of ACK packet, the tuple only contains one entry which is the sequence number. The sender then handles ACK carrying the expected sequence number and wrong sequence number in the same way as RDT3.0 sender. e. As we are running sender and receiver programs on the same machine, it is difficult to observe packet loss. In the sender program, we add a lostPacket() function, which allows us to simulate loss of the current packet with a certain probability (default to 0.1), i.e., by not sending the packet out if lostPacket( function returns true. Step 3: Open RDTReceive.py using a text editor and you will find that it provides a sketch of the receiver program. Complete the receiver program following the hints given as #...." In the while loop, to achieve the following service: When the receiver receives a packet with expected sequence number, it writes the content into file recv.txt" and sends corresponding ACK to the sender (if lostACKO function returns false); otherwise, it will resend the previous ACK to the sender. The lostACK() function is used to simulate the loss of ACK, i.e., by not sending the ACK packet out. We provided the code to set a 10-second timeout (using socket settimeout() function) on the receiver's blocking receiver, socket.recvfrom() operation, i.e., if the receiver is not receiving any data within 10 seconds, the receiver's socket is closed and the receiver program exits. Introduction In this lab, we will use Python socket programming to implement a simple application-layer stop-and-wait RDT protocol. We have introduced in lectures that the transport-layer protocol, UDP, does not implement RDT, and applications can implement their RDT protocol over UDP. In this lab exercise, we are going to implement a stop-and-wait RDT protocol between a sender program and a receiver program, which communicate over UDP sockets. The simple RDT pro- tocol is similar to RDT 3.0 with sequence number, timer, ACK and retransmission, but without checksum (i.e., we consider the channel may lose data/ACK packets but does not flip bits in the packets). Step 2: Open RDTSend.py using a text editor, which contains the complete implementation of the sender program. The sender reads a file (e.g., hku.txt) and sends the file contents to the receiver using a protocol similar to RDT 3.0's sender protocol (except for using checksum). Study the sender program carefully. You will learn how file content is packed together with sequence number into binary data to be sent through UDP socket. a. The sender is to be started by command python3 RDTSend.py . By default, you can run both the sender program and the receiver program on the same machine, i.e., using localhost 127.0.0.1"; data packets are sent from the sender's port 6666 to the receiver's port 7777, and ACK packets are sent from the receiver's port 7777 to the sender's port 6666. b. In the main function, we use the struct module to pack packet contents into binary data. For example, I represents an unsigned integer number and 32s means a 32byte-long string. With packer = struct.Struct('I 32s'), we create a Struct object which we will use to pack an unsigned integer number and a 32-byte string together; with unpacker = struct.Struct('I')", we create a Struct object which we will use to unpack received binary data into an unsigned integer number. The sender reads contents from the file provided and stores them as 32-byte strings into array pkt data.The sender adopts sequence numbers 0 and 1 to send all strings by calling sendPacket() function multiple times. c. In sendPacket() function, the sender constructs a data packet by packing the sequence number and the 32-byte string (which is converted to bytes first using bytes() function), sends it to the receiver and starts a timer (in recvAckTimeouto function), with default timeout of 2 seconds. The Python built-in function bytes() is used to return an immutable bytes object initialized with the given data. d. In recvAckTimeout() function, a timer is created, which is a Timer object in the threading module, and started using the start() function. The function funcTimeout is invoked when the timer times out. The sender then waits for ACK from the receiver. We set the sender socket to be in the nonblocking mode, in order to allow the sender to stop sender socket.recyfrom( upon timer timeout (by default the socket recyfrom function is in blocking mode, such that it will keep waiting for data from the sender). The sender uses unpack() function to unpack received binary data into a tuple whose entries correspond to the original packed items in the received packet; in our case of ACK packet, the tuple only contains one entry which is the sequence number. The sender then handles ACK carrying the expected sequence number and wrong sequence number in the same way as RDT3.0 sender. e. As we are running sender and receiver programs on the same machine, it is difficult to observe packet loss. In the sender program, we add a lostPacket() function, which allows us to simulate loss of the current packet with a certain probability (default to 0.1), i.e., by not sending the packet out if lostPacket( function returns true. Step 3: Open RDTReceive.py using a text editor and you will find that it provides a sketch of the receiver program. Complete the receiver program following the hints given as #...." In the while loop, to achieve the following service: When the receiver receives a packet with expected sequence number, it writes the content into file recv.txt" and sends corresponding ACK to the sender (if lostACKO function returns false); otherwise, it will resend the previous ACK to the sender. The lostACK() function is used to simulate the loss of ACK, i.e., by not sending the ACK packet out. We provided the code to set a 10-second timeout (using socket settimeout() function) on the receiver's blocking receiver, socket.recvfrom() operation, i.e., if the receiver is not receiving any data within 10 seconds, the receiver's socket is closed and the receiver program exits

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Machine Learning And Knowledge Discovery In Databases European Conference Ecml Pkdd 2015 Porto Portugal September 7 11 2015 Proceedings Part 3 Lnai 9286

Authors: Albert Bifet ,Michael May ,Bianca Zadrozny ,Ricard Gavalda ,Dino Pedreschi ,Francesco Bonchi ,Jaime Cardoso ,Myra Spiliopoulou

1st Edition

ISBN: 3319234609, 978-3319234601

More Books

Students also viewed these Databases questions