Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- import getopt
- import time
- from random import randint as rand
- from pprint import pprint
- import Checksum
- import BasicSender
- '''
- This is a skeleton sender class. Create a fantastic transport protocol here.
- '''
- class Sender(BasicSender.BasicSender):
- def __init__(self, dest, port, filename, debug=True, sackMode=False):
- super(Sender, self).__init__(dest, port, filename, debug)
- self.sackMode = sackMode
- self.debug = debug
- self.start_seq_num = 1
- self.timeout = 0.5
- self.chunk_size = 1024
- self.max_bytes = 1472
- self.window_size = 7
- self.msg_queue = self.generate_queue()
- def generate_queue(self):
- queue = []
- seq_num = self.start_seq_num + 1
- while 1:
- chunk = self.infile.read(self.chunk_size)
- if not chunk:
- break
- msg = self.make_packet('dat', seq_num, chunk)
- seq_num += 1
- queue += [msg]
- return queue
- # Main sending loop.
- def start(self):
- self.log("Starting RTP Connection")
- self.handshake()
- self.data_transfer()
- self.send_fin()
- # while 1: pass
- def handshake(self):
- self.log("Starting Handshake...")
- while True:
- hello_msg = self.make_packet('syn', self.start_seq_num, '')
- self.send(hello_msg)
- ans = self.receive(self.timeout)
- if ans:
- msg_type, seqno, data, checksum = self.split_packet(ans)
- if Checksum.validate_checksum(ans) and \
- ((msg_type == 'ack' and seqno == str(self.start_seq_num + 1)) or
- (msg_type == 'sack' and seqno == str(self.start_seq_num + 1) + ';')):
- break
- self.log("Trying Handshake Again...")
- self.log("Done Handshake\n")
- def data_transfer(self):
- self.log("Starting Data Transfer...")
- index = len(self.msg_queue)
- vis = []
- counter, last_index = 0, 0
- start_time = time.time()
- while True:
- if counter >= 3:
- # print 'a', counter, last_index, index
- self.send(self.msg_queue[last_index])
- else:
- for i in range(self.window_size):
- if index >= len(self.msg_queue):
- break
- if str(i + 1 + self.start_seq_num) not in vis:
- packet = self.msg_queue[index]
- self.send(packet)
- index += 1
- ans = self.receive(self.timeout)
- # print ans, len(self.msg_queue), counter
- if ans and Checksum.validate_checksum(ans):
- msg_type, seqno, data, checksum = self.split_packet(ans)
- if msg_type == 'sack':
- res = self.treat_sack_msg(seqno, index)
- if res is True:
- break
- else:
- vis, index = res
- if index == last_index:
- counter += 1
- else:
- counter = 0
- last_index = index
- continue
- elif msg_type == 'ack':
- vis = []
- index = int(seqno) - 2 - self.start_seq_num + 1
- else :
- index = max(index - self.window_size, 0)
- else:
- index = max(index - self.window_size, 0)
- if index == last_index:
- counter += 1
- else:
- counter = 0
- last_index = index
- if index >= len(self.msg_queue):
- break
- elapsed_time = time.time() - start_time
- print 'Time ', elapsed_time
- self.log("Done Data Transfer\n")
- def log(self, text):
- if self.debug:
- print text
- def send_fin(self):
- seq_no = self.start_seq_num + len(self.msg_queue) + 1
- final_msg = self.make_packet('fin', seq_no, '')
- self.log("Starting fin Transfer...")
- while True:
- self.send(final_msg)
- ans = self.receive(self.timeout)
- if ans:
- msg_type, seqno, data, checksum = self.split_packet(ans)
- if Checksum.validate_checksum(ans) and \
- ((msg_type == 'ack' and seqno == str(seq_no+1)) or
- (msg_type == 'sack' and seqno == str(seq_no+1) + ';')):
- break
- self.log("Done fin Transfer...")
- def treat_sack_msg(self, seqno, index):
- cum_ack, sacks = seqno.split(';')
- cum_ack = int(cum_ack)
- if cum_ack > len(self.msg_queue) + self.start_seq_num:
- return True
- sacks = sacks.split(',')
- return sacks, cum_ack - 1 - self.start_seq_num
- '''
- This will be run if you run this script from the command line. You should not
- change any of this; the grader may rely on the behavior here to test your
- submission.
- '''
- if __name__ == "__main__":
- def usage():
- print "BEARS-TP Sender"
- print "-f FILE | --file=FILE The file to transfer; if empty reads from STDIN"
- print "-p PORT | --port=PORT The destination port, defaults to 33122"
- print "-a ADDRESS | --address=ADDRESS The receiver address or hostname, defaults to localhost"
- print "-d | --debug Print debug messages"
- print "-h | --help Print this usage message"
- print "-k | --sack Enable selective acknowledgement mode"
- try:
- opts, args = getopt.getopt(sys.argv[1:],
- "f:p:a:dk", ["file=", "port=", "address=", "debug=", "sack="])
- except:
- usage()
- exit()
- port = 33122
- dest = "localhost"
- filename = None
- debug = False
- sackMode = False
- for o, a in opts:
- if o in ("-f", "--file="):
- filename = a
- elif o in ("-p", "--port="):
- port = int(a)
- elif o in ("-a", "--address="):
- dest = a
- elif o in ("-d", "--debug="):
- debug = True
- elif o in ("-k", "--sack="):
- sackMode = True
- s = Sender(dest, port, filename, debug, sackMode)
- try:
- s.start()
- except (KeyboardInterrupt, SystemExit):
- exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement