Archivo nuevo super simple pah explicarlo po wena weon oh

main
bfernand 2025-12-03 14:46:28 -03:00
parent 5cf27fb016
commit 02f67f9a06
1 changed files with 349 additions and 0 deletions

View File

@ -0,0 +1,349 @@
"""
TRANSFERENCIA DE ARCHIVOS - SIN TUPLAS NI DICCIONARIOS
Versión ultra simplificada para explicación
"""
# ========================================
# IMPORTS
# ========================================
import socket
import threading
import tkinter as tk
import os
# ========================================
# VARIABLES GLOBALES
# ========================================
MI_IP = ""
PUERTO = 5000
BUFFER_TAMANO = 4096
ARCHIVO_A_ENVIAR = ""
IP_DESTINO = ""
# ========================================
# FUNCIONES DE RED
# ========================================
def conseguir_mi_ip():
"""Consigue la IP de esta computadora"""
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip_numero = s.getsockname()[0]
s.close()
return ip_numero
except:
return "127.0.0.1"
def escuchar_archivos():
"""Escucha conexiones y recibe archivos"""
# Crear carpeta para archivos recibidos
if not os.path.exists("recibidos"):
os.makedirs("recibidos")
# Crear socket servidor
servidor_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
servidor_socket.bind(("0.0.0.0", PUERTO))
servidor_socket.listen(5)
print(f"Escuchando en puerto {PUERTO}...")
while True:
# Esperar conexión
cliente_socket, direccion_cliente = servidor_socket.accept()
ip_cliente = direccion_cliente[0] # Solo tomamos la IP (no el puerto)
print(f"Conexión desde: {ip_cliente}")
# Recibir información del archivo
info_archivo = cliente_socket.recv(1024).decode()
# Separar nombre y tamaño
if "|" in info_archivo:
partes = info_archivo.split("|")
nombre_archivo = partes[0]
tamaño_archivo = int(partes[1])
# Guardar archivo
ruta_completa = "recibidos/" + nombre_archivo
# Evitar sobrescribir archivos
contador = 1
while os.path.exists(ruta_completa):
nombre_base = nombre_archivo.split(".")[0]
extension = nombre_archivo.split(".")[-1]
ruta_completa = f"recibidos/{nombre_base}_{contador}.{extension}"
contador += 1
# Abrir archivo para escribir
archivo_destino = open(ruta_completa, "wb")
# Recibir datos en partes
bytes_recibidos = 0
while bytes_recibidos < tamaño_archivo:
datos = cliente_socket.recv(BUFFER_TAMANO)
archivo_destino.write(datos)
bytes_recibidos += len(datos)
# Cerrar archivo
archivo_destino.close()
print(f"Archivo guardado: {ruta_completa}")
# Enviar confirmación
cliente_socket.send(b"OK")
# Cerrar conexión
cliente_socket.close()
def mandar_archivo(ruta, ip):
"""Envía un archivo a otra computadora"""
# Verificar que el archivo existe
if not os.path.exists(ruta):
return False
# Obtener información del archivo
nombre_archivo = os.path.basename(ruta)
tamaño_archivo = os.path.getsize(ruta)
try:
# Crear socket cliente
cliente_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cliente_socket.settimeout(10)
# Conectar al destino
cliente_socket.connect((ip, PUERTO))
# Enviar información del archivo
mensaje_info = nombre_archivo + "|" + str(tamaño_archivo)
cliente_socket.send(mensaje_info.encode())
# Abrir y enviar archivo
archivo_origen = open(ruta, "rb")
while True:
datos = archivo_origen.read(BUFFER_TAMANO)
if not datos:
break
cliente_socket.send(datos)
# Cerrar archivo
archivo_origen.close()
# Esperar confirmación
respuesta = cliente_socket.recv(1024)
cliente_socket.close()
if respuesta == b"OK":
return True
else:
return False
except Exception as error:
print(f"Error: {error}")
return False
def buscar_computadoras():
"""Busca otras computadoras en la red"""
computadoras_encontradas = []
# Obtener base de IP
partes_ip = MI_IP.split(".")
if len(partes_ip) == 4:
ip_base = partes_ip[0] + "." + partes_ip[1] + "." + partes_ip[2]
# Probar primeras 20 IPs
for ultimo_numero in range(1, 21):
ip_completa = ip_base + "." + str(ultimo_numero)
# Saltar nuestra propia IP
if ip_completa == MI_IP:
continue
# Intentar conectar
try:
s = socket.socket()
s.settimeout(0.2)
s.connect((ip_completa, PUERTO))
computadoras_encontradas.append(ip_completa)
s.close()
except:
pass
return computadoras_encontradas
# ========================================
# INTERFAZ GRÁFICA
# ========================================
class AplicacionTransferencia:
def __init__(self):
# Crear ventana principal
self.ventana_principal = tk.Tk()
self.ventana_principal.title("Enviar Archivos")
self.ventana_principal.geometry("400x450")
# Variables de la aplicación
global MI_IP
MI_IP = conseguir_mi_ip()
# Lista para equipos encontrados
self.lista_equipos = []
# Crear interfaz
self.crear_interfaz_grafica()
# Iniciar servidor en segundo plano
hilo_servidor = threading.Thread(target=escuchar_archivos)
hilo_servidor.daemon = True
hilo_servidor.start()
def crear_interfaz_grafica(self):
"""Crea todos los elementos visuales"""
# Título
etiqueta_titulo = tk.Label(self.ventana_principal,
text="Enviar Archivos",
font=("Arial", 18))
etiqueta_titulo.pack(pady=20)
# Mostrar IP local
etiqueta_ip = tk.Label(self.ventana_principal,
text="Tu IP: " + MI_IP,
font=("Arial", 12))
etiqueta_ip.pack(pady=10)
# Línea separadora
linea = tk.Frame(self.ventana_principal, height=2, bg="gray")
linea.pack(fill="x", padx=20, pady=10)
# Botón para buscar
boton_buscar = tk.Button(self.ventana_principal,
text="Buscar Equipos",
command=self.buscar,
font=("Arial", 12))
boton_buscar.pack(pady=10)
# Lista para mostrar equipos
self.lista_widget = tk.Listbox(self.ventana_principal, height=6)
self.lista_widget.pack(pady=10, padx=20, fill="x")
# Botón para seleccionar archivo
boton_archivo = tk.Button(self.ventana_principal,
text="Seleccionar Archivo",
command=self.seleccionar,
font=("Arial", 12))
boton_archivo.pack(pady=10)
# Etiqueta para información
self.etiqueta_info = tk.Label(self.ventana_principal,
text="Esperando...",
font=("Arial", 10))
self.etiqueta_info.pack(pady=5)
# Botón para enviar
self.boton_enviar = tk.Button(self.ventana_principal,
text="ENVIAR",
command=self.enviar,
font=("Arial", 12),
state="disabled")
self.boton_enviar.pack(pady=10)
# Etiqueta para estado
self.etiqueta_estado = tk.Label(self.ventana_principal,
text="",
font=("Arial", 10))
self.etiqueta_estado.pack(pady=10)
def buscar(self):
"""Busca otros equipos en la red"""
# Limpiar lista
self.lista_widget.delete(0, tk.END)
self.etiqueta_info.config(text="Buscando...")
# Buscar computadoras
self.lista_equipos = buscar_computadoras()
# Mostrar resultados
if len(self.lista_equipos) > 0:
for equipo in self.lista_equipos:
self.lista_widget.insert(tk.END, equipo)
self.etiqueta_info.config(text=f"Encontrados: {len(self.lista_equipos)}")
else:
self.etiqueta_info.config(text="No se encontraron equipos")
def seleccionar(self):
"""Permite seleccionar un archivo"""
# Importar aquí para no cargarlo al inicio
from tkinter import filedialog
archivo = filedialog.askopenfilename(title="Elegir archivo")
if archivo:
global ARCHIVO_A_ENVIAR
ARCHIVO_A_ENVIAR = archivo
nombre = os.path.basename(archivo)
tamaño = os.path.getsize(archivo)
self.etiqueta_info.config(text=f"Listo: {nombre}")
self.boton_enviar.config(state="normal")
def enviar(self):
"""Envía el archivo seleccionado"""
# Obtener selección de la lista
indices_seleccionados = self.lista_widget.curselection()
if len(indices_seleccionados) == 0:
self.etiqueta_estado.config(text="Error: Selecciona un equipo")
return
indice = indices_seleccionados[0]
# Verificar índice válido
if indice < 0 or indice >= len(self.lista_equipos):
self.etiqueta_estado.config(text="Error: Equipo no válido")
return
# Obtener IP de destino
global IP_DESTINO
IP_DESTINO = self.lista_equipos[indice]
# Verificar archivo seleccionado
if not ARCHIVO_A_ENVIAR:
self.etiqueta_estado.config(text="Error: No hay archivo")
return
# Cambiar estado
self.etiqueta_estado.config(text="Enviando...")
self.boton_enviar.config(state="disabled")
# Enviar en segundo plano
hilo_envio = threading.Thread(target=self.enviar_en_segundo_plano)
hilo_envio.daemon = True
hilo_envio.start()
def enviar_en_segundo_plano(self):
"""Envía el archivo sin bloquear la interfaz"""
resultado = mandar_archivo(ARCHIVO_A_ENVIAR, IP_DESTINO)
# Actualizar interfaz
if resultado:
self.etiqueta_estado.config(text="¡Archivo enviado!")
else:
self.etiqueta_estado.config(text="Error al enviar")
self.boton_enviar.config(state="normal")
def iniciar(self):
"""Comienza la aplicación"""
self.ventana_principal.mainloop()
# ========================================
# PROGRAMA PRINCIPAL
# ========================================
if __name__ == "__main__":
print("Iniciando aplicación...")
print(f"IP Local: {MI_IP}")
print(f"Puerto: {PUERTO}")
# Crear y ejecutar aplicación
app = AplicacionTransferencia()
app.iniciar()