feat(tcp): added tcp capabilities
- Added example commands
This commit is contained in:
parent
81bf298cd6
commit
de1e931fe9
@ -10,6 +10,15 @@ Zero. Only python standard libs were used. Tested on Python 3.11
|
|||||||
|
|
||||||
You can run `python3 src/myftp/client.py --directory <insert valid directory that you have read/write permissions>` to start the client or `python3 src/myftp/client.py --debug 1 --directory <insert valid directory that you have read/write permissions>` for debugging purposes.
|
You can run `python3 src/myftp/client.py --directory <insert valid directory that you have read/write permissions>` to start the client or `python3 src/myftp/client.py --debug 1 --directory <insert valid directory that you have read/write permissions>` for debugging purposes.
|
||||||
|
|
||||||
|
Some example test commands:
|
||||||
|
|
||||||
|
- `get file_server.txt`
|
||||||
|
- `summary numbers.txt`
|
||||||
|
- `put file_local.txt`
|
||||||
|
- `put image_local.png`
|
||||||
|
- `change file_server.txt file_server1.txt`
|
||||||
|
- `help`
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
|
||||||
By default, the server IP address or hostname or server name will be `0.0.0.0` or `localhost` (meaning it will bind to all interfaces). The `--port_number` flag, if not specified will be by default `12000`.
|
By default, the server IP address or hostname or server name will be `0.0.0.0` or `localhost` (meaning it will bind to all interfaces). The `--port_number` flag, if not specified will be by default `12000`.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# Description: FTP client (both UDP and TCP implemented)
|
# Description: FTP client (both UDP and TCP implemented)
|
||||||
|
|
||||||
|
|
||||||
from socket import socket, AF_INET, SOCK_DGRAM
|
from socket import socket, AF_INET, SOCK_DGRAM, SOCK_STREAM
|
||||||
from typing import Pattern, Tuple, Optional
|
from typing import Pattern, Tuple, Optional
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
import traceback
|
import traceback
|
||||||
@ -58,8 +58,15 @@ class Client:
|
|||||||
self.debug = debug
|
self.debug = debug
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
client_socket = socket(AF_INET, SOCK_DGRAM)
|
self.client_socket = socket(
|
||||||
client_socket.settimeout(10)
|
AF_INET, (SOCK_DGRAM if self.protocol == "UDP" else SOCK_STREAM)
|
||||||
|
)
|
||||||
|
self.client_socket.settimeout(10)
|
||||||
|
|
||||||
|
# only if using TCP
|
||||||
|
self.client_socket.connect(
|
||||||
|
(self.server_name, self.server_port)
|
||||||
|
) if self.protocol == "TCP" else None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
@ -68,7 +75,7 @@ class Client:
|
|||||||
|
|
||||||
# handling the "bye" command
|
# handling the "bye" command
|
||||||
if command == "bye":
|
if command == "bye":
|
||||||
client_socket.close()
|
self.client_socket.close()
|
||||||
print(f"myftp> - {self.protocol} - Session is terminated")
|
print(f"myftp> - {self.protocol} - Session is terminated")
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -160,9 +167,12 @@ class Client:
|
|||||||
f"myftp> - {self.protocol} - sent payload {bin(int.from_bytes(payload, byteorder='big'))[2:]} to the server" # type: ignore
|
f"myftp> - {self.protocol} - sent payload {bin(int.from_bytes(payload, byteorder='big'))[2:]} to the server" # type: ignore
|
||||||
) if self.debug else None
|
) if self.debug else None
|
||||||
|
|
||||||
client_socket.sendto(payload, (self.server_name, self.server_port)) # type: ignore
|
if self.protocol == "UDP":
|
||||||
|
self.client_socket.sendto(payload, (self.server_name, self.server_port)) # type: ignore
|
||||||
|
else:
|
||||||
|
self.client_socket.sendall(payload) # type: ignore
|
||||||
|
|
||||||
response_payload = client_socket.recv(2048)
|
response_payload = self.client_socket.recv(2048)
|
||||||
|
|
||||||
self.parse_response_payload(response_payload)
|
self.parse_response_payload(response_payload)
|
||||||
|
|
||||||
@ -185,7 +195,7 @@ class Client:
|
|||||||
print(traceback_info)
|
print(traceback_info)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
client_socket.close()
|
self.client_socket.close()
|
||||||
|
|
||||||
def parse_response_payload(self, response_payload: bytes):
|
def parse_response_payload(self, response_payload: bytes):
|
||||||
first_byte = bytes([response_payload[0]])
|
first_byte = bytes([response_payload[0]])
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# Description: FTP server (both UDP and TCP implemented)
|
# Description: FTP server (both UDP and TCP implemented)
|
||||||
|
|
||||||
|
|
||||||
from socket import socket, AF_INET, SOCK_DGRAM
|
from socket import socket, AF_INET, SOCK_DGRAM, SOCK_STREAM
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from typing import Optional, Tuple
|
from typing import Optional, Tuple
|
||||||
import traceback
|
import traceback
|
||||||
@ -50,8 +50,14 @@ class Server:
|
|||||||
self.debug = debug
|
self.debug = debug
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.server_socket = socket(AF_INET, SOCK_DGRAM)
|
server_socket = socket(
|
||||||
self.server_socket.bind((self.server_name, self.server_port))
|
AF_INET, (SOCK_DGRAM if self.protocol == "UDP" else SOCK_STREAM)
|
||||||
|
)
|
||||||
|
|
||||||
|
server_socket.bind((self.server_name, self.server_port))
|
||||||
|
|
||||||
|
# only needed for TCP
|
||||||
|
server_socket.listen(5) if self.protocol == "TCP" else None
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"myftp> - {self.protocol} - Server is ready to receive at {self.server_name}:{self.server_port}"
|
f"myftp> - {self.protocol} - Server is ready to receive at {self.server_name}:{self.server_port}"
|
||||||
@ -60,12 +66,27 @@ class Server:
|
|||||||
shut_down = False
|
shut_down = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if self.protocol == "TCP":
|
||||||
|
client_socket, clientAddress = server_socket.accept()
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"myftp> - {self.protocol} Connected to TCP client at {clientAddress}"
|
||||||
|
) if self.debug else None
|
||||||
|
|
||||||
while not shut_down:
|
while not shut_down:
|
||||||
print(
|
print(
|
||||||
f"myftp> - {self.protocol} ------------------------------------------------------------------"
|
f"myftp> - {self.protocol} ------------------------------------------------------------------"
|
||||||
) if self.debug else None
|
) if self.debug else None
|
||||||
|
|
||||||
req_payload, clientAddress = self.server_socket.recvfrom(2048)
|
if self.protocol == "UDP":
|
||||||
|
req_payload, clientAddress = server_socket.recvfrom(2048)
|
||||||
|
else:
|
||||||
|
req_payload = client_socket.recv(2048) # type: ignore
|
||||||
|
|
||||||
|
# TCP client disconnected
|
||||||
|
if not req_payload:
|
||||||
|
client_socket.close() # type: ignore
|
||||||
|
return
|
||||||
|
|
||||||
first_byte = bytes([req_payload[0]])
|
first_byte = bytes([req_payload[0]])
|
||||||
|
|
||||||
@ -74,7 +95,7 @@ class Server:
|
|||||||
)
|
)
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"myftp> - {self.protocol} - Received message from client at {clientAddress}: {req_payload}"
|
f"myftp> - {self.protocol} - Received message from client at {clientAddress}: {req_payload}" # type: ignore
|
||||||
) if self.debug else None
|
) if self.debug else None
|
||||||
|
|
||||||
# help request handling
|
# help request handling
|
||||||
@ -159,15 +180,22 @@ class Server:
|
|||||||
response_data=response_data, # type:ignore
|
response_data=response_data, # type:ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
self.server_socket.sendto(res_payload, clientAddress)
|
if self.protocol == "UDP":
|
||||||
|
server_socket.sendto(res_payload, clientAddress) # type: ignore
|
||||||
|
else:
|
||||||
|
client_socket.sendall(res_payload) # type: ignore
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"myftp> - {self.protocol} - Sent message to client at {clientAddress}: {res_payload}"
|
f"myftp> - {self.protocol} - Sent message to client at {clientAddress}: {res_payload}" # type: ignore
|
||||||
) if self.debug else None
|
) if self.debug else None
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
shut_down = True
|
shut_down = True
|
||||||
self.server_socket.close()
|
if self.protocol == "UDP":
|
||||||
|
server_socket.close()
|
||||||
|
else:
|
||||||
|
client_socket.close() # type: ignore
|
||||||
|
|
||||||
print(f"myftp> - {self.protocol} - Server shutting down")
|
print(f"myftp> - {self.protocol} - Server shutting down")
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user