def read(receiver): received = [] max_index = -1 stream_id = get_stream_id(receiver) total_len = get_stream_length(stream_id, receiver) while len(received) != total_len: try: raw_payload, addr = receiver.recvfrom(1024) packet = get_packet(raw_payload) index = packet["index"] if packet["stream_id"] == stream_id and packet[ "type"] == "DATA" and is_valid( raw_payload) and random.random() > 0.3: receiver.sendto( make_payload(stream_id, "CONTROL", "ACK", index), addr) if index > max_index: max_index = index if not is_index_in_chunks(received, index): received.append((packet["data"], index)) else: receiver.sendto( make_payload(stream_id, "CONTROL", "NACK", index), addr) except: for i in range(max_index + 1): if not is_index_in_chunks(received, i): receiver.sendto( make_payload(stream_id, "CONTROL", "NACK", i), addr) return join_chunks(received)
def write(val, sender): stream_id = str(uuid.uuid4()) receiver = sender.connection msgs = split2chunks(val) data2send = create_packets(msgs, stream_id) window = 1 pointer = 0 waiting = set() ssthresh = 6 init_write(stream_id, sender, receiver) init_stream_len(stream_id, len(data2send), sender, receiver) while pointer < len(data2send) or len(waiting) != 0: while len(waiting) < window and pointer < len(data2send): if pointer != 3 and pointer != 5 and pointer != 15: sender.sendto(data2send[pointer], receiver) waiting.add(pointer) pointer += 1 with suppress(BlockingIOError): while True: payload, addr = sender.recvfrom(1024, socket.MSG_DONTWAIT) packet = get_packet(payload) if packet["type"] == "CONTROL" and packet["data"] == "NACK": index = packet["index"] sender.sendto(data2send[index], receiver) window *= 2 / 3 elif packet["type"] == "CONTROL" and packet["data"] == "ACK": index = packet["index"] if index in waiting: waiting.remove(index) window = window + 1 if window < ssthresh else window + 0.5
def get_stream_length(stream_id, receiver): while True: with suppress(BlockingIOError): payload, addrs = receiver.recvfrom(1024) packet = get_packet(payload) if is_valid(payload) and packet["type"] == "LENGTH": receiver.sendto(make_payload(stream_id, "LENGTH", "ACK", 0), addrs) return int(packet["data"])
def init_write(stream_id, sender, receiver): sender.sendto(make_payload(stream_id, "INIT", stream_id, 0), receiver) while True: try: resp, addr = sender.recvfrom(1024) packet = get_packet(resp) if packet["type"] == "INIT" and packet["data"] == "ACK": break except: sender.sendto(make_payload(stream_id, "INIT", stream_id, 0), receiver) continue
def get_stream_id(receiver): while True: with suppress(BlockingIOError): payload, addrs = receiver.recvfrom(1024) packet = get_packet(payload) if is_valid(payload) and packet["type"] == "INIT": stream_id = packet["data"] receiver.sendto(make_payload(stream_id, "INIT", "ACK", 0), addrs) return stream_id
def init_stream_len(stream_id, length, sender, receiver): sender.sendto(make_payload(stream_id, "LENGTH", str(length), 0), receiver) while True: try: resp, addr = sender.recvfrom(1024) packet = get_packet(resp) if packet["type"] == "LENGTH" and packet["data"] == "ACK": break except: sender.sendto( make_payload(stream_id, "LENGTH", str(len(data2send)), 0), receiver) continue