Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.

Commit a73ec11

Browse files
committed
passive-active mode implemented in commands PASV and PORT
1 parent f20a298 commit a73ec11

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

client/client.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
FTP_SERVER_ADDR = '127.0.0.1' # Dirección del servidor
77
FTP_CONTROL_PORT = 21 # Puerto del servidor FTP para manejar sesiones. Este valor no cambia
88
PASV_MODE = 0 # Indicador de modo pasivo (0=inactivo 1=activo)
9-
PASV_SOCKET = None # Socket de transferencia utilizado en modo pasivo
9+
DATA_SOCKET = None # Socket de transferencia utilizado para transferencia de datos
1010
BUFFER_SIZE = 1024
1111
TYPE = None
1212

@@ -70,7 +70,6 @@ def argument_handler(min_required_args, max_required_args, given_args):
7070
else:
7171
return "200"
7272

73-
7473
# Funciones para manejar comandos ---------------------------------------------------------------------------------------------
7574

7675
# Control de acceso:
@@ -260,17 +259,33 @@ def cmd_PORT(socket, *args):
260259
ip_parts = args[0].split('.')
261260
if len(ip_parts) != 4:
262261
raise ValueError("La dirección IP debe tener exactamente cuatro partes.")
262+
263+
# Iniciando socket de datos local
264+
data_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
265+
data_socket.bind((args[0], int(args[1])))
266+
data_socket.listen(1)
267+
268+
# Obtener la dirección IP y el puerto del socket de datos para enviar al servidor
269+
data_ip, data_port = data_socket.getsockname()
270+
ip_parts = data_ip.split('.')
271+
263272
# Convertir la dirección IP y el puerto a formato de cadena para el comando PORT
264-
port_high, port_low = divmod(args[1], 256)
273+
port_high, port_low = divmod(data_port, 256)
265274
port_str = f"{port_high},{port_low}"
266-
command = f"PORT {','.join(ip_parts)}0,{port_str}"
267-
if PASV_SOCKET:
268-
PASV_SOCKET.close()
269-
PASV_SOCKET = None
270-
PASV_MODE = 0
271-
return send(socket, command)
272-
else:
273-
return response
275+
command = f"PORT {','.join(ip_parts)},{port_str}"
276+
277+
# Verificando respuesta esperada
278+
response = send(socket, command)
279+
if response.startswith('227'):
280+
# Cerrar el socket pasivo si está abierto
281+
if DATA_SOCKET is not None:
282+
DATA_SOCKET.close()
283+
DATA_SOCKET = None
284+
PASV_MODE = 0
285+
# Si el servidor responde con un código de éxito, proceder con la transferencia de datos
286+
print("Conexión activa establecida.")
287+
DATA_SOCKET = data_socket
288+
return response
274289

275290
def cmd_PASV(socket, *args):
276291
"""Envía el comando PASV al servidor FTP para establecer el modo pasivo (el servidor escucha conexiones y el cliente la inicia)."""
@@ -299,7 +314,6 @@ def cmd_PASV(socket, *args):
299314
else:
300315
print(response)
301316
return None
302-
303317

304318
# Información del sistema:
305319
def cmd_SYST(socket, *args):
@@ -490,10 +504,8 @@ def cmd_SITE(socket, *args):
490504
print(cmd_REST(socket, *args))
491505
elif command == 'site':
492506
print(cmd_SITE(socket, *args))
493-
494507
else:
495508
print("502: Comando no reconocido, por favor intente de nuevo.")
496-
497509
except Exception as e:
498510
print(f"Error: {e}")
499511

0 commit comments

Comments
 (0)