Skip to content
Snippets Groups Projects
Commit 8ff385c2 authored by mgstabrani's avatar mgstabrani
Browse files

connect server and client

parent 3145799e
No related merge requests found
...@@ -26,6 +26,7 @@ class FileBuffer: ...@@ -26,6 +26,7 @@ class FileBuffer:
with open(filename, 'wb') as f: with open(filename, 'wb') as f:
for seg in segments: for seg in segments:
data = seg.get_data() data = seg.get_data()
print(data[:10])
f.write(data) f.write(data)
return return
......
import socket import socket
import sys import sys
from common import * from common import *
from buffer import FileBuffer
class Client(): class Client():
...@@ -10,9 +11,14 @@ class Client(): ...@@ -10,9 +11,14 @@ class Client():
self.init_socket() self.init_socket()
self.broadcast() self.broadcast()
self.handshake() try:
self.recv_file() self.handshake()
self.close_con() self.recv_file()
self.close_con()
self.save_file()
except ConnectionError:
log("!", "Connecion error.")
pass
def init_socket(self): def init_socket(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
...@@ -67,43 +73,57 @@ class Client(): ...@@ -67,43 +73,57 @@ class Client():
def recv_file(self): def recv_file(self):
# To-Do # To-Do
rcvd = Segment()
base = 0 # antrian ngirim data base = 0 # antrian ngirim data
data_ret = b'' data_ret = b''
log("!", f"Waiting for server to send data") log("!", f"Waiting for server to send data")
segments = []
while True: while True:
data, server_addr = self.recv() # nerima data dari server data, server_addr = self.recv() # nerima data dari server
file_received = self.FILEPATH # deklarasi buat tempat penyimpanan berkas file_received = self.FILEPATH # deklarasi buat tempat penyimpanan berkas
rcvd = Segment()
rcvd.from_bytes(data) # unwrap the data 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 if rcvd.isData(): # check jika segmennya bertipe data
ack_segment = Segment() ack_segment = Segment()
ack_segment.setACK() ack_segment.setACK()
ack_segment.set_seq_no(0) 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) 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() data_ret += ack_segment.get_data()
print(rcvd.bytes[12:22])
segments.append(rcvd)
else: else:
log(f"Data is empty") log("!", f"Data is empty")
base += 1 base += 1
elif rcvd.getFIN(): elif rcvd.getFIN():
finack_segment = Segment() # break, will go to close_con
finack_segment.set_seq_no(0) log("!", "Closing Connection ...")
finack_segment.set_ack_no(0) seg = Segment(300, rcvd.get_seq_no())
finack_segment.setFIN() seg.setACK()
finack_segment.setACK() self.send(seg.to_bytes(), self.DST_ADDR)
self.send(finack_segment.to_bytes(), server_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 break
elif not rcvd.test_checksum() or rcvd.get_seq_no() > base: elif not rcvd.test_checksum() or rcvd.get_seq_no() > base:
...@@ -115,7 +135,7 @@ class Client(): ...@@ -115,7 +135,7 @@ class Client():
log("!", f"WARNING!!! Segment refused") log("!", f"WARNING!!! Segment refused")
elif rcvd.get_seq_no < base: elif rcvd.get_seq_no() < base:
ack_segment = Segment() ack_segment = Segment()
ack_segment.set_seq_no(0) ack_segment.set_seq_no(0)
ack_segment.set_ack_no(base) ack_segment.set_ack_no(base)
...@@ -123,42 +143,52 @@ class Client(): ...@@ -123,42 +143,52 @@ class Client():
self.send(ack_segment.to_bytes(), server_addr) self.send(ack_segment.to_bytes(), server_addr)
log("!", f"WARNING!!! Segment already received") log("!", f"WARNING!!! Segment already received")
break
# ini mau void apa mau return data_ret yakk wkwkkwkwkwkwk # ini mau void apa mau return data_ret yakk wkwkkwkwkwkwk
return return
def close_con(self): def close_con(self):
# To-Do # 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() # byte, _ = self.recv()
rcvd = Segment().from_bytes(byte) # rcvd = Segment().from_bytes(byte)
if (not rcvd.test_checksum()) or (not rcvd.getACK()) \ # if (not rcvd.test_checksum()) or (not rcvd.getFIN()):
or (rcvd.get_ack_no() != seg.get_seq_no()): # raise ConnectionError
raise ConnectionError # seg = Segment(300, rcvd.get_seq_no())
log(f"Segment SEQ={seg.get_seq_no()}, FIN", "Acked") # seg.setACK()
# self.socket.close() # 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 return
def save_file(self):
fb = FileBuffer()
fb.write(self.segments, self.FILEPATH)
if __name__=="__main__": if __name__=="__main__":
try: # try:
port=int(sys.argv[1]) # port=int(sys.argv[1])
Client(port=port) # Client(port=port)
except KeyboardInterrupt: # except KeyboardInterrupt:
pass # pass
except : # 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() Client()
\ No newline at end of file
...@@ -2,19 +2,22 @@ import socket ...@@ -2,19 +2,22 @@ import socket
import sys import sys
import os import os
from common import * from common import *
from buffer import FileBuffer
from typing import List
class Server(): 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.SERVER_PORT = port
self.FILE_PATH = filepath self.FILE_PATH = filepath
self.clients = [] self.clients = []
self.N = 1
self.init_socket() self.init_socket()
self.listen() self.listen()
for client in self.clients : for client in self.clients :
self.handshake(client) self.handshake(client)
# self.send_file(client) self.send_file(client)
self.close_con(client) self.close_con(client)
def init_socket(self): def init_socket(self):
...@@ -51,6 +54,7 @@ class Server(): ...@@ -51,6 +54,7 @@ class Server():
choice = input() choice = input()
if choice == "n": if choice == "n":
print() print()
self.socket.settimeout(3)
break break
def handshake(self, client_addr): def handshake(self, client_addr):
...@@ -84,22 +88,65 @@ class Server(): ...@@ -84,22 +88,65 @@ class Server():
def send_file(self, client_addr): def send_file(self, client_addr):
# To-Do # To-Do
file_size = os.path.getsize(self.FILE_PATH) print("====")
print(self.FILE_PATH)
with open(self.FILE_PATH, "rb") as f: print("===")
file = f.read() list_of_segments = FileBuffer().read(self.FILE_PATH)
log("!", "File is loaded") count = len(list_of_segments)
log("!", f"File segmented into {count} segments")
segments = Segment()
base = 0
log("!", f"File segmented into {len(file) // SEG_SIZE} segments") timeout = 0
while True:
self.send(self.FILE_PATH + f"-{file_size}", client_addr) for i in range(self.N):
log("!", "File path and size sent") if (base+i) < count:
print("======")
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): def close_con(self, client_addr):
# To-Do # To-Do
...@@ -110,7 +157,7 @@ class Server(): ...@@ -110,7 +157,7 @@ class Server():
seg = Segment(100) seg = Segment(100)
seg.setFIN() seg.setFIN()
self.send(seg.to_bytes(), client_addr) 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() byte , _ = self.recv()
rcvd = Segment().from_bytes(byte) rcvd = Segment().from_bytes(byte)
...@@ -130,7 +177,15 @@ class Server(): ...@@ -130,7 +177,15 @@ class Server():
return True return True
if __name__=="__main__": if __name__=="__main__":
try: # try:
Server(port=sys.argv[1], filepath=sys.argv[2]); # Server(port=int(sys.argv[1]), filepath=sys.argv[2]);
except: # except:
Server(); # log("!", "Using another port")
\ No newline at end of file # 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()
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment