diff --git a/buffer.py b/buffer.py
index 5dca9f8115fbfab193a1c3389da510af7fdf6d72..e3911be2e4032317a7884c24080d4d0d2049121e 100644
--- a/buffer.py
+++ b/buffer.py
@@ -26,6 +26,7 @@ class FileBuffer:
         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 321b6613fea47d8675c68eead0e034d5f5e9ea11..4be6e27a27c6bee02a2eceaaeb79b7511c399a08 100644
--- a/client.py
+++ b/client.py
@@ -1,6 +1,7 @@
 import socket
 import sys
 from common import *
+from buffer import FileBuffer
 
 class Client():
 
@@ -10,9 +11,14 @@ class Client():
 
         self.init_socket()
         self.broadcast()
-        self.handshake()
-        self.recv_file()
-        self.close_con()
+        try:
+            self.handshake()
+            self.recv_file()
+            self.close_con()
+            self.save_file()
+        except ConnectionError:
+            log("!", "Connecion error.")
+            pass
 
     def init_socket(self):
         self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@@ -67,43 +73,57 @@ class Client():
 
     def recv_file(self):
         # To-Do
-        rcvd = Segment()
-
         base = 0 # antrian ngirim data
         data_ret = b''
 
         log("!", f"Waiting for server to send data")
-
+        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
 
-            if rcvd.test_checksum() and rcvd.get_seq_no == base: # untuk ngecek valid checksumnya dan memastikan ini urutan awal
+            if rcvd.test_checksum() and rcvd.get_seq_no() == base: # untuk ngecek valid checksumnya dan memastikan ini urutan awal
 
                 if rcvd.isData(): # check jika segmennya bertipe data
                     ack_segment = Segment()
                     ack_segment.setACK()
                     ack_segment.set_seq_no(0)
-                    ack_segment.set_ack_no(rcvd.get_seq_no+1)
+                    ack_segment.set_ack_no(rcvd.get_seq_no())
                     self.send(ack_segment.to_bytes(), server_addr)
 
-                    log(f"Segment SEQ={rcvd.get_seq_no()}: Received {rcvd.isData()}, Sent {ack_segment.getACK()}")
+                    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")
+                    log("!", f"Data is empty")
 
                 base += 1
 
             elif rcvd.getFIN():
-                finack_segment = Segment()
-                finack_segment.set_seq_no(0)
-                finack_segment.set_ack_no(0)
-                finack_segment.setFIN()
-                finack_segment.setACK()
-                self.send(finack_segment.to_bytes(), server_addr)
+                # break, will go to close_con
+                log("!", "Closing Connection ...")
+                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()
+                self.segments = segments
                 break
             
             elif not rcvd.test_checksum() or rcvd.get_seq_no() > base:
@@ -115,7 +135,7 @@ class Client():
 
                 log("!", f"WARNING!!! Segment refused")
 
-            elif rcvd.get_seq_no < base:
+            elif rcvd.get_seq_no() < base:
                 ack_segment = Segment()
                 ack_segment.set_seq_no(0)
                 ack_segment.set_ack_no(base)
@@ -123,42 +143,52 @@ class Client():
                 self.send(ack_segment.to_bytes(), server_addr)
 
                 log("!", f"WARNING!!! Segment already received")
+                break
         
         # ini mau void apa mau return data_ret yakk wkwkkwkwkwkwk
         return
 
     def close_con(self):
         # To-Do
-        log("!", "Closing Connection ...")
-
-        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()
+        # 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):
+        fb = FileBuffer()
+        fb.write(self.segments, self.FILEPATH)
+
 if __name__=="__main__":
-    try:
-        port=int(sys.argv[1])
-        Client(port=port)
-    except KeyboardInterrupt:
-        pass
-    except :
+    # 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]))
+    elif len(sys.argv) > 1:
+        Client(port=int(sys.argv[1]))
+    else :
         Client()
\ No newline at end of file
diff --git a/server.py b/server.py
index 0240bccd0b92b4b74dcc55c74022d248f3c87dc6..f33a0b47d4fd5126a40d4b56bdcc080194ea56c4 100644
--- a/server.py
+++ b/server.py
@@ -2,19 +2,22 @@ import socket
 import sys
 import os
 from common import *
+from buffer import FileBuffer
+from typing import List
 
 class Server():
 
-    def __init__(self, port=10000, filepath="data/halo.txt"):
+    def __init__(self, port=10000, filepath="data/calender.pdf"):
         self.SERVER_PORT = port
         self.FILE_PATH = filepath
         self.clients = []
+        self.N = 1
 
         self.init_socket()
         self.listen()
         for client in self.clients :
             self.handshake(client)
-            # self.send_file(client)
+            self.send_file(client)
             self.close_con(client)
 
     def init_socket(self):
@@ -51,6 +54,7 @@ class Server():
             choice = input()
             if choice == "n":
                 print()
+                self.socket.settimeout(3)
                 break
 
     def handshake(self, client_addr):
@@ -84,22 +88,65 @@ class Server():
 
     def send_file(self, client_addr):
         # To-Do
-        file_size = os.path.getsize(self.FILE_PATH)
-
-        with open(self.FILE_PATH, "rb") as f:
-            file = f.read()
-        log("!", "File is loaded")
-
-        segments = Segment()
-
-        log("!", f"File segmented into {len(file) // SEG_SIZE} segments")
-
-        self.send(self.FILE_PATH + f"-{file_size}", client_addr)
-        log("!", "File path and size sent")
-
-        print()
+        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")
+
+        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)
+                    self.send(seg.to_bytes(), client_addr)
+                    log(f"Segment SEQ={seg.get_seq_no()}", "Sent")
+            try:
+                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_seq_no()}", "Acked")
+                    base += 1
+                if base >= count:
+                    break
+                timeout = 0
+            except socket.timeout:
+                log("!", "Connection timeout. ")
+                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
+# '''
 
-        return True
 
     def close_con(self, client_addr):
         # To-Do
@@ -110,7 +157,7 @@ class Server():
         seg = Segment(100)
         seg.setFIN()
         self.send(seg.to_bytes(), client_addr)
-        log(f"Segment SEQ={seg.get_seq_no()}, FIN", "")
+        log(f"Segment SEQ={seg.get_seq_no()}, FIN", "Sent")
 
         byte , _ = self.recv()
         rcvd = Segment().from_bytes(byte)
@@ -130,7 +177,15 @@ class Server():
         return True
 
 if __name__=="__main__":
-    try:
-        Server(port=sys.argv[1], filepath=sys.argv[2]);
-    except:
-        Server();
\ No newline at end of file
+    # 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:
+        Server(port=int(sys.argv[1]))
+    else :
+        Server()
+