Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feedback #1

Open
wants to merge 87 commits into
base: feedback
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
66b2e11
Setting up GitHub Classroom Feedback
github-classroom[bot] Nov 7, 2023
4305367
feat: argument parser
nadilahmad13 Nov 7, 2023
01d9d56
feat: server socket connection
nadilahmad13 Nov 7, 2023
95fd46b
docs: Create README.md
WildanGhaly Nov 22, 2023
6a8a25e
feat: logger class
nadilahmad13 Nov 22, 2023
565b2cc
init: add folder structure
WildanGhaly Nov 22, 2023
59d0237
Merge pull request #2 from Sister20/Feat/logger
nadilahmad13 Nov 22, 2023
a16fcda
Merge pull request #3 from Sister20/folder-structure
WildanGhaly Nov 22, 2023
b7d57df
Merge pull request #4 from Sister20/staging
nadilahmad13 Nov 22, 2023
aa8c395
feat: segment flag
nadilahmad13 Nov 22, 2023
1e4d2f7
Merge pull request #5 from Sister20/Feat/SegmentFlag
nadilahmad13 Nov 22, 2023
4474aef
refactor(segmentflag): simplify operations
nadilahmad13 Nov 22, 2023
f7e475e
feat: add constant
WildanGhaly Nov 22, 2023
5e12174
feat: add segment
WildanGhaly Nov 22, 2023
f111aba
Merge pull request #6 from Sister20/Feat/Segment
WildanGhaly Nov 22, 2023
fbb15e6
feat: add message info
WildanGhaly Nov 23, 2023
564ff29
Merge pull request #7 from Sister20/Feat/MessageInfo
WildanGhaly Nov 23, 2023
74f2c3c
feat: connection draft
WildanGhaly Nov 23, 2023
29d52d6
feat: Menghindari tubes menjadi 0 (Change socket type)
MHEN007 Nov 23, 2023
882ef29
fix: update constructor for MessageInfo
WildanGhaly Nov 23, 2023
f7bbc55
Merge pull request #8 from Sister20/Fix/init-MessageInfo
WildanGhaly Nov 23, 2023
5eff2f4
feat(connection): listen on port
nadilahmad13 Nov 23, 2023
159ac54
chore: remove deps
nadilahmad13 Nov 23, 2023
b831d51
feat: connection but still meledak
WildanGhaly Nov 23, 2023
70e6c98
fix: Memperbaiki host yang salah
henryanandsr Nov 23, 2023
525f83c
Merge pull request #9 from Sister20/Feat/connection
nadilahmad13 Nov 23, 2023
55fe4cb
feat: file transfer draft
nadilahmad13 Nov 25, 2023
89e1d47
feat: file connection
nadilahmad13 Nov 25, 2023
97aae1c
feat: test case
nadilahmad13 Nov 25, 2023
9ca47c1
chore: remove vid karena kegedean
nadilahmad13 Nov 25, 2023
a5dbb59
Merge pull request #10 from Sister20/Feat/filetransfer
nadilahmad13 Nov 25, 2023
f1b60ea
feat: Timeout Implementation
MHEN007 Nov 25, 2023
36dd904
fix : timeout
henryanandsr Nov 25, 2023
cdfc0e4
Merge pull request #11 from Sister20/Feat/Timeout
nadilahmad13 Nov 25, 2023
20a212f
chore: add test files
nadilahmad13 Nov 26, 2023
b3e46bf
chore: remove print and change window size
nadilahmad13 Nov 26, 2023
2f61e4d
feat: logger
nadilahmad13 Nov 26, 2023
34667f4
feat: add dummy seek mechanism (NOT DONE)
WildanGhaly Nov 26, 2023
043497f
Merge pull request #12 from Sister20/Feat/seek
WildanGhaly Nov 26, 2023
32d3838
feat: add real seek to client
WildanGhaly Nov 26, 2023
d8b6069
Merge pull request #13 from Sister20/Feat/RealSeek
WildanGhaly Nov 26, 2023
5e3b6fd
test: add test case
WildanGhaly Nov 26, 2023
490642c
fix: fix error handling's error on error handling
WildanGhaly Nov 26, 2023
8259055
Merge pull request #14 from Sister20/Fix/ErrorHandling
WildanGhaly Nov 26, 2023
da85ea2
refactor : client and server waiting connection
henryanandsr Nov 26, 2023
3cb5e48
chore: ignore outputs
nadilahmad13 Nov 26, 2023
514efd9
fix: starvation on time out
nadilahmad13 Nov 26, 2023
92f3f6c
fix: FIN Loss
MHEN007 Nov 26, 2023
0421741
Merge pull request #15 from Sister20/staging
MHEN007 Nov 26, 2023
b89898a
feat: add send metadata mechanism
WildanGhaly Nov 27, 2023
02949eb
Merge pull request #16 from Sister20/Feat/SendMetadata
WildanGhaly Nov 27, 2023
5982daa
refactor: remove message info and simplify connection
nadilahmad13 Nov 27, 2023
b2344a9
Merge pull request #17 from Sister20/refactor/messages
nadilahmad13 Nov 27, 2023
d60add5
feat: end to end connection setup
MHEN007 Nov 27, 2023
e0c80bf
docs: how to run end to end
nadilahmad13 Nov 27, 2023
f60f046
Merge pull request #18 from Sister20/Feat/endtoend
MHEN007 Nov 27, 2023
f47958d
refactor: lib imports
nadilahmad13 Nov 27, 2023
c2e20a8
refactor: 3WH connection and add parallelization
nadilahmad13 Nov 27, 2023
96509ad
chore: keep and ignores
nadilahmad13 Nov 27, 2023
fb066d1
Merge branch 'main' of https://github.com/Sister20/tugas-besar-if3130…
nadilahmad13 Nov 27, 2023
26b9840
Merge branch 'staging' of https://github.com/Sister20/tugas-besar-if3…
nadilahmad13 Nov 27, 2023
1f309ba
chore: add logs
nadilahmad13 Nov 27, 2023
6900b6c
Merge pull request #22 from Sister20/staging
nadilahmad13 Nov 28, 2023
3c35f4b
Merge pull request #23 from Sister20/Feat/parallel
nadilahmad13 Nov 28, 2023
f24a3f6
fix: handled unexpected stuffs and change logs
nadilahmad13 Nov 28, 2023
c6bd384
fix: typing error
WildanGhaly Nov 28, 2023
6b419f5
feat : add bonus 3
henryanandsr Nov 28, 2023
5867128
feat: Create GameManager
MHEN007 Nov 28, 2023
a299618
feat: add hamming algorithm
WildanGhaly Nov 28, 2023
07ec795
fix: fix metadata using hamming
WildanGhaly Nov 28, 2023
f71bb47
fix: fix md5 hash error
WildanGhaly Nov 28, 2023
62e43c3
Merge pull request #24 from Sister20/Feat/Hamming
WildanGhaly Nov 28, 2023
1295fe1
feat : add tic tac toe games
henryanandsr Nov 28, 2023
6173083
Merge pull request #25 from Sister20/staging
MHEN007 Nov 28, 2023
80819ae
docs: readme
nadilahmad13 Nov 28, 2023
8a31db3
Update README.md
henryanandsr Nov 28, 2023
78e1a36
fix: fix checksum mechanism
WildanGhaly Nov 28, 2023
ecca940
Merge pull request #26 from Sister20/Fix/Checksum
WildanGhaly Nov 28, 2023
c220936
Merge branch 'staging' into Feat/TicTacToe
henryanandsr Nov 28, 2023
99903ff
feat: tic tac toe
henryanandsr Nov 28, 2023
6de73d5
Merge pull request #27 from Sister20/Feat/TicTacToe
henryanandsr Nov 28, 2023
267eb95
feat: add threading for breaking down bytes
WildanGhaly Nov 28, 2023
dc11622
fix : fin not received
henryanandsr Nov 28, 2023
aabf28e
fix: error nya willy
nadilahmad13 Nov 28, 2023
a9bc3d4
feat: loading bar
nadilahmad13 Nov 28, 2023
957f795
docs: readme
nadilahmad13 Nov 28, 2023
3074525
Merge pull request #28 from Sister20/staging
nadilahmad13 Nov 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.pyc
__pycache__/
output/*
!output/.gitkeep
77 changes: 77 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# IF3130 - Jaringan Komputer 2023
> Tugas Besar - IF3130 Jaringan Komputer 2023

## About
This is a simple file transfer program using UDP protocol. The program is written in Python 3.10 and tested on Windows 11 and MacOS.

## Contributors
Kelompok 1 K03 - GunungE

| NIM | Nama |
| --- | --- |
| 13521004 | Henry Anand Septian Radityo (Manusia Rasis) |
| 13521007 | Matthew Mahendra (Si Bucin ke Bandung Mulu) |
| 13521015 | Hidayatullah Wildan Ghaly (Manusia Penggali) |
| 13521024 | Ahmad Nadil (yg paling normal) |

![Kelompok 1 K03](input/penampakan.jpg)

## Features
### Main Features
- Reliable data transfer using UDP protocol and sliding window protocol
- Handle data transfer in bad network condition (Tested using Clumsy)

### Bonus Features
- Streaming process using Seek()
- Metadata transfer (file name and extension)
- Peer to Peer file transfer
- Parallel processing for handshake and data transfer in server
- Error Correcting Codes (ECC) using Hamming Code
- End to End device communication
- TicTacToe game using UDP protocol

## How to Run
1. Run the server
```bash
python server.py -i <server_ip> -p <server_port> -f <file_input_path>
```

2. Run the client
```bash
python client.py -ci <client_ip> -cp <client_port> -i <server_ip> -p <server_port> -f <file_output_path>
```

*There is default value for each argument, so you can run the program without any argument*

Alternatively, you can run the main program to switch between server and client mode
```bash
python main.py
```

## Folder Structure
```bash
┣ 📂.github
┃ ┗ 📜.keep
┣ 📂lib
┃ ┣ 📜__init__.py
┃ ┣ 📜Connection.py
┃ ┣ 📜Constant.py
┃ ┣ 📜Hamming.py
┃ ┣ 📜Logger.py
┃ ┣ 📜Node.py
┃ ┣ 📜Segment.py
┃ ┣ 📜SegmentFlag.py
┃ ┗ 📜Utils.py
┣ 📂output
┃ ┗ 📜.gitkeep
┣ 📜.gitignore
┣ 📜client.py
┣ 📜main.py
┣ 📜README.md
┗ 📜server.py
```

## References
- [Hamming Code](https://www.geeksforgeeks.org/hamming-code-implementation-in-python/)
- [CRC](https://www.geeksforgeeks.org/cyclic-redundancy-check-python/)
- [UDP Socket](https://www.geeksforgeeks.org/udp-server-client-implementation-c/)
216 changes: 216 additions & 0 deletions client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import argparse
import json
import socket

from lib import *
from lib.GameState import GameState


class Client(Node):
def __init__(self, connection: Connection, server_ip: str, server_port: str, folder_path: str = None):
self.connection = connection
self.server_ip = server_ip
self.server_port = server_port
self.folder_path = folder_path
self.file_path = None
self.file = []
self.log = Logger("Client")
self.buffer_size = 1024
self.segment = Segment()
self.gameState = None
self.player_number = None

def run(self):
if (self.three_way_handshake()):
self.listen_file()

def run_game(self):
self.three_way_handshake()

while True :
# listen for client number
try:
segment_data, _ = self.connection.listen(1)
if(segment_data.is_syn_flag and segment_data.get_header()['seqNumber'] == 0):
#inisialisasi
self.log.success_log(f"Received segment {segment_data.get_header()['seqNumber']} from {self.server_ip}:{self.server_port} with data {segment_data.get_data().decode()}")
self.segment = Segment()
self.segment.set_seq_number(0)
self.segment.set_flag([False, True, False])
self.connection.send(self.server_ip, self.server_port, self.segment)
self.player_number = segment_data.get_data().decode()
elif (segment_data.is_syn_ack_flag and segment_data.get_header()['seqNumber'] == 1):
# init game state
self.gameState = GameState(self.player_number, json.loads(segment_data.get_data().decode()))
if (self.gameState.clientNumber == '2'):
self.gameState.printBoard()
self.segment = Segment()
self.segment.set_seq_number(1)
self.segment.set_flag([False, True, False])
# print disini
self.connection.send(self.server_ip, self.server_port, self.segment)
elif (segment_data.is_syn_ack_flag and segment_data.get_header()['seqNumber'] == 2):
if(self.gameState.clientNumber == self.player_number):
self.gameState.board = json.loads(segment_data.get_data().decode())
self.gameState.printBoard()

move = self.gameState.input_mark()
self.segment = Segment()
self.segment.set_data(json.dumps(move).encode())
self.segment.set_flag([True, True, False])
self.connection.send(self.server_ip, self.server_port, self.segment)
elif(segment_data.get_header()['seqNumber'] == 3):
self.gameState.board = json.loads(segment_data.get_data().decode())
self.log.success_log("[!] Board Updated")
self.gameState.printBoard()
self.log.alert_log("[!] Waiting for opponent...")
self.segment = Segment()
self.segment.set_flag([False, True, False])
self.connection.send(self.server_ip, self.server_port, self.segment)

elif(segment_data.is_fin_flag and segment_data.get_header()['seqNumber'] == 4):
print(segment_data.get_data().decode())
break
except socket.timeout:
self.connection.send(self.server_ip, self.server_port, self.segment)
except Exception as e:
self.log.warning_log(f'[!] Unknown error occured, exiting...')
exit()

def three_way_handshake(self):
# Send initial connection
self.log.alert_log(f"[!] Starting 3-way handshake with {self.server_ip}:{self.server_port}")
# Initial Connection
self.segment.update_checksum()
# print("Nilai checksum: ", self.segment.get_header()['checksum'])
self.connection.send(self.server_ip, self.server_port, self.segment)

while True:
try:
msg, _ = self.connection.listen(TIMEOUT_LISTEN)
self.segment = msg
# Send SYN-ACK
if self.segment.is_syn_flag():
self.segment = Segment()
self.segment.set_flag([True, True, False])
self.log.alert_log(f"[!] Sending SYN-ACK to {self.server_ip}:{self.server_port}")
self.connection.send(ip_remote=self.server_ip, port_remote=self.server_port, message=self.segment)
# Resend SYN-ACK
elif self.segment.is_syn_ack_flag():
self.log.alert_log(f'[!] Resending SYN-ACK to {self.server_ip}:{self.server_port}')
self.connection.send(ip_remote=self.server_ip, port_remote=self.server_port, message=self.segment)
# Complete
elif self.segment.is_ack_flag():
self.log.alert_log(f"[!] ACK received from {self.server_ip}:{self.server_port}")
break
# Received a segment with no flag (file)
else:
self.log.warning_log(f"[!] Received a segment with no flag (file), resetting connection...")
# Send SYN-ACK
self.segment = Segment()
self.segment.set_flag([True, True, False])
self.log.alert_log(f"[!] Sending SYN-ACK to {self.server_ip}:{self.server_port}")
self.connection.send(ip_remote=self.server_ip, port_remote=self.server_port, message=self.segment)
except socket.timeout:
if self.segment.is_syn_ack_flag():
self.log.warning_log("[!] [TIMEOUT] ACK Response Timed out, retrying...")
# self.connection.send(ip_remote=self.server_ip, port_remote=self.server_port, message=self.segment)
else:
self.log.warning_log("[!] [TIMEOUT] SYN Response Timed out")
return 0

except Exception as e:
self.log.warning_log(f"[!] Error: {e}")
return 0
return 1

def listen_file(self):
N = WINDOW_SIZE
Rn = 0
Sn = 0
METADATA_SEQ = -1
hamming = Hamming()

# Terima file, pengulangan hingga file selesai
while True:
try:
file_segment, _ = self.connection.listen()
Sn = file_segment.get_header()['seqNumber']
self.log.success_log(f"Received segment {Sn} from {self.server_ip}:{self.server_port}")
flag = file_segment.get_flag()

if (Sn == METADATA_SEQ):
self.file_path = (Utils.decode_metadata(file_segment.get_data())).decode('UTF-8')
self.log.success_log(f"[!] Receiving file {self.file_path}")
ack = Segment()
ack.set_flag([False, True, False])
ack.set_ack_number(Sn)
self.log.alert_log(f"[!] Sending metadata ACK to {self.server_ip}:{self.server_port}")
self.connection.send(self.server_ip, self.server_port, ack)
METADATA_SEQ -= 1
continue

# Jika FIN, maka kirim FIN ACK
elif flag.fin:
self.log.success_log(f"[!] FIN received from {self.server_ip}:{self.server_port}")
# ack ke server
ack = Segment()
ack.set_flag([False, True, True])
self.connection.send(ip_remote=self.server_ip, port_remote=self.server_port, message=ack)
self.log.alert_log(f"[!] Sending ACK FIN to {self.server_ip}:{self.server_port}")
filePath = self.folder_path + '/' + self.file_path
md5 = Utils.printmd5(filePath)
self.log.success_log(f"MD5 Hash: {md5}")
break

elif Sn == Rn:
data = file_segment.get_data()
if data:
decodedData = hamming.breakdownBytes(data)
file = open(self.folder_path + '/' +
self.file_path, 'ab')
file.seek(Sn)
file.write(decodedData)
file.close()
Rn += 1

# Kirim ACK
ack = Segment()
ack.set_flag([False, True, False])
ack.set_ack_number(Sn)

self.connection.send(ip_remote=self.server_ip, port_remote=self.server_port, message=ack)
self.log.alert_log(f"[!] Sending ACK {Sn} to {self.server_ip}:{self.server_port}")
else:
self.log.warning_log(f'[!] Segment {Sn} is refused, expected {Rn}, timing out...')
self.connection.send(ip_remote=self.server_ip, port_remote=self.server_port, message=ack)

except socket.timeout:
self.log.warning_log("[!] [TIMEOUT] Response Timed out, retrying...")

except Exception as e:
self.log.warning_log("aaaaaaaaaa", e)
# break


def load_args():
arg = argparse.ArgumentParser()
arg.add_argument('-ci', '--clientip', type=str, default='localhost', help='ip the client is on')
arg.add_argument('-cp', '--clientport', type=int, default=7331, help='port the client is on')
arg.add_argument('-i', '--ip', type=str, default='localhost', help='ip to listen on')
arg.add_argument('-p', '--port', type=int, default=1337, help='port to listen on')
arg.add_argument('-f', '--folder', type=str, default='output', help='path to folder output')
arg.add_argument('-g', '--game', type=str, default='0', help='turn on or off game')
args = arg.parse_args()
return args


if __name__ == "__main__":
args = load_args()
print(args.clientip, args.clientport)
if args.game == '0':
klien = Client(Connection(ip = args.clientip, port=args.clientport), server_ip=args.ip, server_port=args.port, folder_path=args.folder)
klien.run()
else :
klien = Client(Connection(ip = args.clientip, port=args.clientport), server_ip=args.ip, server_port=args.port)
klien.run_game()
Binary file added input/Home.mp3
Binary file not shown.
Binary file added input/diretide2020_treasure_idle.webm
Binary file not shown.
Binary file added input/flower.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions input/ha.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Warna cerah yang terlihat
Diriku mahir sembunyi rasa
Sebenarnya hitam pekat
Kututup rapat, jadi rahasia
Satu dua kali, 'ku tak apa-apa
Kamu pikir hidupku baik-baik saja?
Siapa yang peduli kupunya air mata?
Kamu hanya pinta diri berikan tawa
Ha-ha, ha-ha
Ha-ha, ha-ha, ha-ha
Wajah riangku perisai jitu
Ha-ha, ha-ha
Ha-ha, ha-ha, ha-ha
Tapi sampai kapan kubegitu?
Malam hari berwahana
Pikiran liarku juaranya
Bukan 'ku tak berusaha
Ingin kulepas sekuat tenaga
Satu dua kali, 'ku tak apa-apa
Kamu pikir hidupku baik-baik saja?
Siapa yang peduli kupunya air mata?
Kamu hanya pinta diri berikan tawa, ho-oh
Ha-ha, ha-ha
Ha-ha, ha-ha, ha-ha
Wajah riangku perisai jitu
Ha-ha, ha-ha
Ha-ha, ha-ha, ha-ha
Tapi sampai kapan kubegitu?
Aku bulan yang terangi
Malam-malammu yang sepi
Lalu siapa yang temani
Rasa gelisah kupikul sendiri
Ha-ho
(Ha-ha, ha-ha)
Ha-hm, yeah
(Ha-ha, ha-ha)
Ha-oh
(Ha-ha, ha-ha)
Hu-hu-hu
Ha-ha, ha-ha
Ha-ha, ha-ha, ha-ha
Wajah riangku perisai jitu
Ha-ha, ha-ha
Ha-ha, ha-ha, ha-ha
Tapi sampai kapan kubegitu?
Ha-ha, ha-ha
Ha-ha, ha-ha, ha-ha
Wajah riangku perisai jitu (wajah riangku)
Ha-ha, ha-ha
Ha-ha, ha-ha, ha-ha (hu-uu)
Tapi sampai kapan kubegitu?
Binary file added input/pebble.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added input/penampakan.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading