From 6ed09e6b7024deae41159a8da6ee5cb4fc73af6c Mon Sep 17 00:00:00 2001 From: mgstabrani <mgstabrani19@gmail.com> Date: Thu, 25 Nov 2021 23:06:04 +0700 Subject: [PATCH] Fix checksum and refactor --- buffer.py | 3 --- client.py | 60 ++++++------------------------------------------------ segment.py | 20 +++++++----------- server.py | 53 +++++------------------------------------------ 4 files changed, 18 insertions(+), 118 deletions(-) diff --git a/buffer.py b/buffer.py index e3911be..1802060 100644 --- a/buffer.py +++ b/buffer.py @@ -7,7 +7,6 @@ class FileBuffer: pass def read(self, filename) -> List[Segment]: - # To-Do # return array of segment, # array of segment hanya berisi data, sementara header kosong f = open(filename, "rb") @@ -21,12 +20,10 @@ class FileBuffer: return segments def write(self, segments:List[Segment], filename): - # To-Do # write array of segment to file with open(filename, 'wb') as f: for seg in segments: data = seg.get_data() - print(data[:10]) f.write(data) return diff --git a/client.py b/client.py index bd00aa2..5e56575 100644 --- a/client.py +++ b/client.py @@ -15,7 +15,6 @@ class Client(): try: self.handshake() self.recv_file() - self.close_con() self.save_file() except ConnectionError: log("!", "Connecion error.") @@ -43,12 +42,12 @@ class Client(): log("!", "Listening for three-way handshake...") def handshake(self): - # To-Do rcvd = Segment() while 1: byte, server_addr = self.recv() rcvd.from_bytes(byte) if not rcvd.test_checksum(): + log("!", "Checksum failed.") raise ConnectionError if rcvd.getSYN(): break; @@ -60,6 +59,7 @@ class Client(): seg.set_ack_no(rcvd.get_seq_no()) seg.setSYN() seg.setACK() + seg.set_checksum(seg.count_checksum()) self.send(seg.to_bytes(), server_addr) log(f"Segment SEQ={rcvd.get_seq_no()}, SYN", "Received, Ack sent") log(f"Segment SEQ={seg.get_seq_no()}, SYN", "Sent") @@ -73,7 +73,6 @@ class Client(): return def recv_file(self): - # To-Do base = 0 # antrian ngirim data data_ret = b'' @@ -81,7 +80,6 @@ class Client(): segments = [] while True: data, server_addr = self.recv() # nerima data dari server - file_received = self.FILEPATH # deklarasi buat tempat penyimpanan berkas rcvd = Segment() rcvd.from_bytes(data) # unwrap the data @@ -92,12 +90,12 @@ class Client(): ack_segment.setACK() ack_segment.set_seq_no(0) ack_segment.set_ack_no(rcvd.get_seq_no()) + ack_segment.set_checksum(ack_segment.count_checksum()) self.send(ack_segment.to_bytes(), server_addr) log("!", f"Segment SEQ={rcvd.get_seq_no()}: Received {rcvd.isData()}, Sent {ack_segment.getACK()}") data_ret += ack_segment.get_data() - print(rcvd.bytes[12:22]) segments.append(rcvd) else: log("!", f"Data is empty") @@ -109,6 +107,7 @@ class Client(): log("!", "Closing Connection ...") seg = Segment(300, rcvd.get_seq_no()) seg.setACK() + seg.set_checksum(seg.count_checksum()) self.send(seg.to_bytes(), self.DST_ADDR) log(f"Segment SEQ={rcvd.get_seq_no()}, FIN", "Received, Ack sent") @@ -116,6 +115,7 @@ class Client(): seg = Segment(seg.get_seq_no()) seg.setFIN() + seg.set_checksum(seg.count_checksum()) self.send(seg.to_bytes(), self.DST_ADDR) log(f"Segment SEQ={seg.get_seq_no()}, FIN", "Sent") @@ -125,55 +125,14 @@ class Client(): or (rcvd.get_ack_no() != seg.get_seq_no()): raise ConnectionError log(f"Segment SEQ={seg.get_seq_no()}, FIN", "Acked") - # self.socket.close() self.segments = segments break elif not rcvd.test_checksum() or rcvd.get_seq_no() > base: - # refuse_segment = Segment() - # refuse_segment.set_seq_no(0) - # refuse_segment.set_ack_no(base) - # refuse_segment.setSYN() - # self.send(refuse_segment.to_bytes(), server_addr) - log("!", f"WARNING!!! Segment refused") elif rcvd.get_seq_no() < base: - # ack_segment = Segment() - # ack_segment.set_seq_no(0) - # ack_segment.set_ack_no(base) - # ack_segment.getACK() - # self.send(ack_segment.to_bytes(), server_addr) - log("!", f"WARNING!!! Segment already received") - - # ini mau void apa mau return data_ret yakk wkwkkwkwkwkwk - return - - def close_con(self): - # To-Do - - # byte, _ = self.recv() - # rcvd = Segment().from_bytes(byte) - # if (not rcvd.test_checksum()) or (not rcvd.getFIN()): - # raise ConnectionError - # seg = Segment(300, rcvd.get_seq_no()) - # seg.setACK() - # self.send(seg.to_bytes(), self.DST_ADDR) - # log(f"Segment SEQ={rcvd.get_seq_no()}, FIN", "Received, Ack sent") - - # seg = Segment(seg.get_seq_no()) - # seg.setFIN() - # self.send(seg.to_bytes(), self.DST_ADDR) - # log(f"Segment SEQ={seg.get_seq_no()}, FIN", "Sent") - - # byte, _ = self.recv() - # rcvd = Segment().from_bytes(byte) - # if (not rcvd.test_checksum()) or (not rcvd.getACK()) \ - # or (rcvd.get_ack_no() != seg.get_seq_no()): - # raise ConnectionError - # log(f"Segment SEQ={seg.get_seq_no()}, FIN", "Acked") - # # self.socket.close() return def save_file(self): @@ -181,15 +140,8 @@ class Client(): fb.write(self.segments, self.FILEPATH) if __name__=="__main__": - # try: - # port=int(sys.argv[1]) - # Client(port=port) - # except KeyboardInterrupt: - # pass - # except : - # Client() if len(sys.argv) > 2: - Client(port=int(sys.argv[1])) + Client(port=int(sys.argv[1]), filepath=sys.argv[2]) elif len(sys.argv) > 1: Client(port=int(sys.argv[1])) else : diff --git a/segment.py b/segment.py index 2f45e1a..7f5f180 100644 --- a/segment.py +++ b/segment.py @@ -82,15 +82,15 @@ class Segment(): return not self.bytes[8] def get_checksum(self): - return self.bytes[10] << 8 + self.bytes[11] + return (self.bytes[10] << 8) + self.bytes[11] def set_checksum(self, val): self.bytes[10] = val >> 8 & 0xff self.bytes[11] = val & 0xff def count_checksum(self): - # To-Do - # ... + byte10 = self.bytes[10] + byte11 = self.bytes[11] self.bytes[10] = 0 # dangerous self.bytes[11] = 0 # dangerous data = self.to_bytes() @@ -106,11 +106,13 @@ class Segment(): checksum += w checksum = (checksum >> 16) + (checksum & 0xFFFF) + self.bytes[10] = byte10 # dangerous + self.bytes[11] = byte11 # dangerous + return checksum def test_checksum(self): - # return self.count_checksum == self.get_checksum - return True + return self.count_checksum() == self.get_checksum() def to_bytes(self): return bytes(self.bytes) @@ -133,14 +135,6 @@ class Segment(): print(self.bytes[:50]) if __name__=="__main__": - # seg = Segment() - # seg.setFIN() - # seg.set_seq_no() - # seg.set_ack_no() - # checksum = seg.count_checksum() - # seg.set_checksum(checksum) - # seg = Segment(seqno, ackno, flag, data) - seg = Segment(200, 199) seg.from_file("halo.txt") seg.set_checksum(seg.count_checksum()) diff --git a/server.py b/server.py index eb4b6c2..1ec8d4f 100644 --- a/server.py +++ b/server.py @@ -58,11 +58,11 @@ class Server(): break def handshake(self, client_addr): - # To-DO log("!", "Commencing three-way handshake... ") segment = Segment() segment.set_seq_no(100) segment.setSYN() + segment.set_checksum(segment.count_checksum()) self.send(segment.to_bytes(), client_addr) log(f"Segment SEQ={segment.get_seq_no()}, SYN", "Sent") @@ -70,10 +70,6 @@ class Server(): recved = Segment().from_bytes(byte) if (not recved.test_checksum()) or (not recved.getACK()) \ or (recved.get_ack_no() != segment.get_seq_no()): - # print(recved.getACK()) - # print(recved.get_ack_no()) - # print(segment.get_seq_no()) - # print(recved.bytes[:12]) raise ConnectionError log(f"Segment SEQ={segment.get_seq_no()}, SYN", "Acked") @@ -81,31 +77,25 @@ class Server(): segment.set_seq_no(recved.get_ack_no()+1) segment.set_ack_no(recved.get_seq_no()) segment.setACK() + segment.set_checksum(segment.count_checksum()) self.send(segment.to_bytes(), client_addr) log(f"Segment SEQ={recved.get_seq_no()}, SYN", "Received, Ack sent") return True def send_file(self, client_addr): - # To-Do - print("====") - print(self.FILE_PATH) - print("===") list_of_segments = FileBuffer().read(self.FILE_PATH) count = len(list_of_segments) log("!", f"File segmented into {count} segments") - acked = [False for _ in range(count)] - base = 0 timeout = 0 while True: for i in range(self.N): if (base+i) < count: - print("======") - print(base+i) seg = list_of_segments[base+i] seg.set_seq_no(base+i) + seg.set_checksum(seg.count_checksum()) self.send(seg.to_bytes(), client_addr) log(f"Segment SEQ={seg.get_seq_no()}", "Sent") try: @@ -117,7 +107,6 @@ class Server(): byte, _ = self.recv() rcvd = Segment().from_bytes(byte) if rcvd.test_checksum() and rcvd.get_ack_no() == base: - print(list_of_segments[base].bytes[12:22]) log(f"Segment SEQ={rcvd.get_ack_no()}", "Acked") base += 1 if base >= count: @@ -128,41 +117,13 @@ class Server(): timeout += 1 if timeout == 3: raise ConnectionError -# ''' -# | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | -# ^ ^ -# function sender is -# Sb := 0 -# Sm := N + 1 -# while True: -# if you receive an ack number where Rn > Sb then -# Sm := (Sm − Sb) + Rn -# Sb := Rn -# if no packet is in transmission then -# Transmit packets where Sb ≤ Sn ≤ Sm. -# Packets are transmitted in order - - -# function receiver is -# Rn := 0 -# Do the following forever: -# if Sn = Rn and the packet is error free then -# Accept the packet and send it to a higher layer -# Rn := Rn + 1 -# else -# Refuse packet -# Send acknowledgement for last received packet -# ''' - def close_con(self, client_addr): - # To-Do - # self.socket.close() - # log("!", "Connection is closed") log("!", "Closing Connection ...") seg = Segment(100) seg.setFIN() + seg.set_checksum(seg.count_checksum()) self.send(seg.to_bytes(), client_addr) log(f"Segment SEQ={seg.get_seq_no()}, FIN", "Sent") @@ -179,16 +140,12 @@ class Server(): raise ConnectionError seg = Segment(seg.get_seq_no()+1, rcvd.get_seq_no()) seg.setACK() + seg.set_checksum(seg.count_checksum()) self.send(seg.to_bytes(), client_addr) log(f"Segment SEQ={rcvd.get_seq_no()}, FIN", "Received, Ack sent.") return True if __name__=="__main__": - # try: - # Server(port=int(sys.argv[1]), filepath=sys.argv[2]); - # except: - # log("!", "Using another port") - # Server(filepath=sys.argv[2]); if len(sys.argv) > 2: Server(port=int(sys.argv[1]), filepath=sys.argv[2]); elif len(sys.argv) > 1: -- GitLab