feat(udp): summary command completed
This commit is contained in:
parent
73b4e06d02
commit
fe23170908
@ -9,9 +9,10 @@ WORKDIR /server
|
|||||||
|
|
||||||
# Create files with random content in the /server directory
|
# Create files with random content in the /server directory
|
||||||
RUN mkdir /server_directory
|
RUN mkdir /server_directory
|
||||||
# these files is only 750 bytes
|
|
||||||
|
# These files is only 750 bytes, can fit inside a UDP/TCP packet
|
||||||
RUN dd if=/dev/urandom of=/server_directory/file_server.txt bs=1 count=750
|
RUN dd if=/dev/urandom of=/server_directory/file_server.txt bs=1 count=750
|
||||||
RUN dd if=/dev/urandom of=/server_directory/image_server.png bs=1 count=750
|
RUN dd if=/dev/urandom of=/server_directory/image_server.png bs=1 count=750
|
||||||
|
|
||||||
# Start your Python application
|
# generate a file that has random numbers
|
||||||
#CMD python server.py --port_number 12000 --debug 1
|
RUN for _ in $(seq 1 150); do shuf -i 0-1000 -n 1 >> /server_directory/numbers.txt; done
|
||||||
|
150
server_directory/numbers.txt
Normal file
150
server_directory/numbers.txt
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
970
|
||||||
|
408
|
||||||
|
627
|
||||||
|
774
|
||||||
|
374
|
||||||
|
425
|
||||||
|
292
|
||||||
|
570
|
||||||
|
681
|
||||||
|
971
|
||||||
|
141
|
||||||
|
468
|
||||||
|
271
|
||||||
|
120
|
||||||
|
450
|
||||||
|
298
|
||||||
|
802
|
||||||
|
34
|
||||||
|
448
|
||||||
|
979
|
||||||
|
181
|
||||||
|
117
|
||||||
|
322
|
||||||
|
885
|
||||||
|
733
|
||||||
|
31
|
||||||
|
818
|
||||||
|
582
|
||||||
|
83
|
||||||
|
524
|
||||||
|
104
|
||||||
|
285
|
||||||
|
932
|
||||||
|
964
|
||||||
|
292
|
||||||
|
306
|
||||||
|
621
|
||||||
|
584
|
||||||
|
109
|
||||||
|
302
|
||||||
|
555
|
||||||
|
250
|
||||||
|
2
|
||||||
|
59
|
||||||
|
602
|
||||||
|
452
|
||||||
|
357
|
||||||
|
404
|
||||||
|
486
|
||||||
|
37
|
||||||
|
616
|
||||||
|
667
|
||||||
|
154
|
||||||
|
938
|
||||||
|
552
|
||||||
|
887
|
||||||
|
969
|
||||||
|
602
|
||||||
|
701
|
||||||
|
284
|
||||||
|
358
|
||||||
|
37
|
||||||
|
802
|
||||||
|
290
|
||||||
|
1
|
||||||
|
94
|
||||||
|
829
|
||||||
|
854
|
||||||
|
678
|
||||||
|
938
|
||||||
|
156
|
||||||
|
466
|
||||||
|
420
|
||||||
|
391
|
||||||
|
757
|
||||||
|
22
|
||||||
|
843
|
||||||
|
346
|
||||||
|
658
|
||||||
|
330
|
||||||
|
383
|
||||||
|
274
|
||||||
|
229
|
||||||
|
537
|
||||||
|
444
|
||||||
|
14
|
||||||
|
656
|
||||||
|
646
|
||||||
|
616
|
||||||
|
357
|
||||||
|
930
|
||||||
|
975
|
||||||
|
626
|
||||||
|
964
|
||||||
|
497
|
||||||
|
860
|
||||||
|
290
|
||||||
|
558
|
||||||
|
714
|
||||||
|
969
|
||||||
|
496
|
||||||
|
871
|
||||||
|
667
|
||||||
|
148
|
||||||
|
262
|
||||||
|
424
|
||||||
|
402
|
||||||
|
337
|
||||||
|
770
|
||||||
|
61
|
||||||
|
899
|
||||||
|
153
|
||||||
|
567
|
||||||
|
129
|
||||||
|
922
|
||||||
|
12
|
||||||
|
375
|
||||||
|
810
|
||||||
|
658
|
||||||
|
991
|
||||||
|
399
|
||||||
|
820
|
||||||
|
198
|
||||||
|
25
|
||||||
|
17
|
||||||
|
696
|
||||||
|
885
|
||||||
|
307
|
||||||
|
254
|
||||||
|
600
|
||||||
|
508
|
||||||
|
983
|
||||||
|
703
|
||||||
|
175
|
||||||
|
363
|
||||||
|
197
|
||||||
|
831
|
||||||
|
998
|
||||||
|
534
|
||||||
|
833
|
||||||
|
291
|
||||||
|
434
|
||||||
|
218
|
||||||
|
858
|
||||||
|
795
|
||||||
|
140
|
||||||
|
102
|
||||||
|
170
|
||||||
|
182
|
||||||
|
992
|
@ -112,6 +112,10 @@ class Client:
|
|||||||
f"myftp> - {self.protocol} - Summary file {filename} from the server"
|
f"myftp> - {self.protocol} - Summary file {filename} from the server"
|
||||||
) if self.debug else None
|
) if self.debug else None
|
||||||
|
|
||||||
|
first_byte = (summary_request_opcode << 5) + len(filename)
|
||||||
|
|
||||||
|
second_byte_to_n_byte = filename.encode("ascii")
|
||||||
|
|
||||||
# change command handling
|
# change command handling
|
||||||
elif change_command_pattern.match(command):
|
elif change_command_pattern.match(command):
|
||||||
command_name, old_filename, new_filename = command.split()
|
command_name, old_filename, new_filename = command.split()
|
||||||
@ -125,7 +129,7 @@ class Client:
|
|||||||
first_byte: int = unknown_request_opcode << 5
|
first_byte: int = unknown_request_opcode << 5
|
||||||
|
|
||||||
# get or put case
|
# get or put case
|
||||||
if command_name == "get":
|
if command_name == "get" or command_name == "summary":
|
||||||
payload = first_byte.to_bytes(1, "big") + second_byte_to_n_byte # type: ignore
|
payload = first_byte.to_bytes(1, "big") + second_byte_to_n_byte # type: ignore
|
||||||
|
|
||||||
elif command_name == "put":
|
elif command_name == "put":
|
||||||
@ -135,9 +139,6 @@ class Client:
|
|||||||
else first_byte.to_bytes(1, "big") # type: ignore
|
else first_byte.to_bytes(1, "big") # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
elif command_name == "summary":
|
|
||||||
pass
|
|
||||||
|
|
||||||
elif command == "change":
|
elif command == "change":
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -124,6 +124,20 @@ class Server:
|
|||||||
filename = None
|
filename = None
|
||||||
response_data = None
|
response_data = None
|
||||||
|
|
||||||
|
elif request_type == "summary":
|
||||||
|
# empty filename error
|
||||||
|
if filename_length_in_bytes <= 0:
|
||||||
|
rescode = rescode_fail_dict["file_not_error_rescode"]
|
||||||
|
else:
|
||||||
|
(
|
||||||
|
rescode,
|
||||||
|
filename, # "summary.txt"
|
||||||
|
filename_length_in_bytes, # of the summary file
|
||||||
|
response_data, # summary.txt file content
|
||||||
|
) = self.process_summary_req(
|
||||||
|
filename_length_in_bytes, req_payload[1:]
|
||||||
|
)
|
||||||
|
|
||||||
elif request_type == "unknown":
|
elif request_type == "unknown":
|
||||||
rescode = rescode_fail_dict["unknown_request_rescode"]
|
rescode = rescode_fail_dict["unknown_request_rescode"]
|
||||||
filename_length_in_bytes = None
|
filename_length_in_bytes = None
|
||||||
@ -174,6 +188,64 @@ class Server:
|
|||||||
|
|
||||||
return request_type, filename_length_in_bytes
|
return request_type, filename_length_in_bytes
|
||||||
|
|
||||||
|
def process_summary_req(
|
||||||
|
self, filename_length: int, req_payload: bytes
|
||||||
|
) -> Tuple[int, Optional[str], Optional[int], Optional[bytes]]:
|
||||||
|
"""
|
||||||
|
Find the filename mentioned
|
||||||
|
Calculate the min,max,avg
|
||||||
|
Put those numbers into a file called summary.txt
|
||||||
|
"""
|
||||||
|
filename = req_payload[:filename_length].decode("ascii")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"myftp> - {self.protocol} - Summarizing the file named {filename} on the server"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(os.path.join(self.directory_path, filename), "r") as file:
|
||||||
|
numbers = [int(line.strip()) for line in file if line.strip().isdigit()]
|
||||||
|
|
||||||
|
# Find the largest, smallest, and calculate the average
|
||||||
|
largest_number = max(numbers)
|
||||||
|
smallest_number = min(numbers)
|
||||||
|
average_value = sum(numbers) / len(numbers) if numbers else 0
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"myftp> - {self.protocol} - File {filename} summarized successfully. The max is {largest_number}, the min is {smallest_number}, the average is {average_value}"
|
||||||
|
)
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(self.directory_path, "summary.txt"), "w"
|
||||||
|
) as summary_file:
|
||||||
|
summary_file.write(f"min: {smallest_number}\n")
|
||||||
|
summary_file.write(f"max: {largest_number}\n")
|
||||||
|
summary_file.write(f"avg: {average_value}\n")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"myftp> - {self.protocol} - Created file summary.txt summarized successfully. Sending it back to the client"
|
||||||
|
)
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(self.directory_path, "summary.txt"), "rb"
|
||||||
|
) as summary_file:
|
||||||
|
binary_content = summary_file.read()
|
||||||
|
|
||||||
|
return (
|
||||||
|
rescode_success_dict["correct_summary_request_rescode"],
|
||||||
|
"summary.txt",
|
||||||
|
11,
|
||||||
|
binary_content,
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
traceback_info = traceback.format_exc()
|
||||||
|
|
||||||
|
print(f"myftp> - {self.protocol} - {error} happened.")
|
||||||
|
|
||||||
|
print(traceback_info)
|
||||||
|
return rescode_fail_dict["file_not_error_rescode"], None, None, None
|
||||||
|
|
||||||
def process_put_req(self, filename_length: int, req_payload: bytes) -> int:
|
def process_put_req(self, filename_length: int, req_payload: bytes) -> int:
|
||||||
"""
|
"""
|
||||||
Reconstruct file put by client
|
Reconstruct file put by client
|
||||||
|
Loading…
x
Reference in New Issue
Block a user