forked from egemenyrlmz/peer2peer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaws_client.py
More file actions
192 lines (152 loc) · 6.58 KB
/
aws_client.py
File metadata and controls
192 lines (152 loc) · 6.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import socket
import threading
import sys
import os
#write here aws server public ip address
SERVER_HOST = 'x.x.x.x'
SERVER_PORT = 5500
def handle_incoming_messages(sock, is_receiver=False):
"""
Continuously read incoming data from the server
and handle messages such as 'RECEIVER_LIST|...', 'FILE|...', or 'ERROR|...'.
If 'is_receiver' is True, we also handle incoming file data.
"""
while True:
try:
header = sock.recv(1024)
if not header:
print("[!] Lost connection to the server.")
break
msg = header.decode('utf-8')
parts = msg.split("|")
if parts[0] == "RECEIVER_LIST":
# Format: "RECEIVER_LIST|receiver1,receiver2,receiver3"
if len(parts) == 2:
receiver_list = parts[1].split(",") if parts[1] else []
#print("[*] Updated receiver list:", receiver_list)
elif parts[0] == "ERROR":
# Example: "ERROR|Receiver not found"
print("[!] Error from server:", msg)
elif parts[0] == "FILE" and is_receiver:
# Expected format: "FILE|sender_name|filename|filesize"
if len(parts) == 4:
_, sender_name, filename, filesize = parts
filesize = int(filesize)
print(f"[+] Incoming file '{filename}' ({filesize} bytes) from {sender_name}")
# Ask the user if they want to rename the file
new_filename = input(
f"[?] Enter a new name for the file (press Enter to keep '{filename}'): ").strip()
if new_filename == "":
new_filename = filename # Use the original filename if no new name is provided
# Read the actual file data in a loop until we get 'filesize' bytes
file_data = b""
bytes_received = 0
while bytes_received < filesize:
chunk = sock.recv(4096)
if not chunk:
print("[!] Connection lost while receiving file data.")
return
file_data += chunk
bytes_received += len(chunk)
# Construct the path to the Desktop
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
file_path = os.path.join(desktop_path, new_filename)
# Save the file to the Desktop
with open(file_path, 'wb') as f:
f.write(file_data)
print(f"[+] File '{new_filename}' received and saved to Desktop. ({len(file_data)} bytes)")
else:
print("[!] Invalid FILE header format.")
else:
# You can implement other message types or simply ignore
pass
except ConnectionResetError:
print("[!] Connection reset by server.")
break
except Exception as e:
print(f"[!] Error reading server messages: {e}")
break
print("[*] Incoming messages thread exiting.")
def sender_mode(name):
"""
Sender mode.
1. Connect to the server and identify as "SENDER|<name>".
2. Start a thread to continuously handle incoming messages (e.g., RECEIVER_LIST).
3. Prompt user to send files to a specific receiver.
"""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER_HOST, SERVER_PORT))
s.sendall(f"SENDER|{name}".encode('utf-8'))
print("[*] Connected to server as a sender.")
# Listener thread (not handling FILE downloads, so is_receiver=False)
listener_thread = threading.Thread(target=handle_incoming_messages, args=(s, False), daemon=True)
listener_thread.start()
try:
while True:
command = input("Enter command (e.g., send bob sample.txt): ").strip()
if not command:
continue
parts = command.split()
if len(parts) == 3 and parts[0] == "send":
_, target_receiver, filename = parts
if not os.path.isfile(filename):
print(f"[DEBUG] Filename provided: {filename}")
print("[!] File not found.")
continue
filesize = os.path.getsize(filename)
# Send the header: "SEND|receiver_name|filename|filesize"
header = f"SEND|{target_receiver}|{filename}|{filesize}"
s.sendall(header.encode('utf-8'))
# Send file data in chunks
with open(filename, 'rb') as f:
while True:
chunk = f.read(4096)
if not chunk:
break
s.sendall(chunk)
print(f"[+] Sent file '{filename}' ({filesize} bytes) to {target_receiver}")
else:
print("[!] Invalid command. Example: send bob sample.txt")
except KeyboardInterrupt:
print("[!] Sender shutting down via Ctrl+C.")
finally:
s.close()
print("[*] Socket closed.")
def receiver_mode(name):
"""
Receiver mode.
1. Connect to the server and identify as "RECEIVER|<name>".
2. Start a thread to continuously handle incoming messages (including FILEs).
"""
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER_HOST, SERVER_PORT))
s.sendall(f"RECEIVER|{name}".encode('utf-8'))
print("[*] Connected to server as a receiver.")
# Listener thread that *can* receive files, so is_receiver=True
listener_thread = threading.Thread(target=handle_incoming_messages, args=(s, True), daemon=True)
listener_thread.start()
print("[*] Press Ctrl+C to exit.")
try:
while True:
# Typically, a receiver just waits for incoming files or messages
pass
except KeyboardInterrupt:
print("\n[!] Receiver shutting down.")
finally:
s.close()
print("[*] Socket closed.")
if __name__ == "__main__":
# Usage:
# python aws_client.py RECEIVER alice
# python aws_client.py SENDER bob
if len(sys.argv) != 3:
print(f"Usage: python {sys.argv[0]} <ROLE> <NAME>")
sys.exit(1)
role = sys.argv[1].upper()
name = sys.argv[2]
if role == "RECEIVER":
receiver_mode(name)
elif role == "SENDER":
sender_mode(name)
else:
print("[!] Invalid role. Please enter RECEIVER or SENDER.")