Question
+ -------------------------------------------------------------------------------------------------------------- RDTSend.py from socket import * import threading import struct import sys import random # simulate packet loss def lostPacket(seq_num): prob = random.random() if
+
--------------------------------------------------------------------------------------------------------------
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
--------------------------------------------------------------------------------------------------------------------------------------
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.pyStep by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started