def __init__(self, address, sock, archivoElegido, log): Thread.__init__(self) #Direccion del cliente que se esta comunicando self.address = address #Socket que esta siendo usado por el servidor para comunicarse con el cliente self.sock = sock #Archivo que se ha elegido en el servidor para ser enviado al cliente self.archivoElegido = archivoElegido #Log en el que se escriben los resultados del programa self.log = log #Monitor para ver la cantidad de paquetes y bytes enviados self.monitor = Monitor(serverAddress[0], serverAddress[1], address, archivoElegido) #Inicio de un nuevo thread para el cliente con la direccion IP address print('Iniciando un nuevo thread para {}'.format(address)) #Creacion del socket UDP self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #Caracteristicas del socket UDP self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, BUFFER_SIZE) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, BUFFER_SIZE)
#Comando que indica que el cliente esta listo para recibir archivos BEG_RECV = b'BEG_RECV' SEND = b'SEND' RECV = b'RECV' #Comando que indica que el archivo se recibio correctamente OK = b'OK' #Comando que indica que hubo un error en la comunicacion o que el archivo no se recibio adecuadamente ERR = b'ERR' #Comando que indica la finalizacion de la transmision del archivo enviado END_TRANSMISSION = b'END_TRANSMISSION' #Comando que indica la finalizacion del protocolo FIN = b'FIN' #Se define el tamanio del buffer buffer = 1024 #Se crea un monitor monitor = Monitor(serverAddress[0], serverAddress[1], '', '') try: tcpsock.connect(serverAddress) #Se envia el mensaje de que se esta listo para recibir archivos print('El cliente esta listo para recibir archivos: {}'.format(BEG_RECV)) sent = sock.sendto(BEG_RECV, serverAddress) data, address = sock.recvfrom(buffer) print('Esperando SEND') cent = False while not cent: try: print('Esperando SEND') data, address = sock.recvfrom(buffer) print(data) if data == SEND:
class ClientHandler(Thread): def __init__(self, address, sock, archivoElegido, log): Thread.__init__(self) #Direccion del cliente que se esta comunicando self.address = address #Socket que esta siendo usado por el servidor para comunicarse con el cliente self.sock = sock #Archivo que se ha elegido en el servidor para ser enviado al cliente self.archivoElegido = archivoElegido #Log en el que se escriben los resultados del programa self.log = log #Monitor para ver la cantidad de paquetes y bytes enviados self.monitor = Monitor(serverAddress[0], serverAddress[1], address, archivoElegido) #Inicio de un nuevo thread para el cliente con la direccion IP address print('Iniciando un nuevo thread para {}'.format(address)) #Creacion del socket UDP self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #Caracteristicas del socket UDP self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, BUFFER_SIZE) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, BUFFER_SIZE) def run(self): # Se abre el archivo f = open(self.archivoElegido, 'rb') #Se lee un chunk de archivo de tamanio BUFFER_SIZE data = f.read(BUFFER_SIZE) #Se envia un paquete con el nombre del archivo que se va a transferir self.sock.sendto(self.archivoElegido[11:].encode(), self.address) #Se inicializa un digest que se generara con el mensaje usando el algoritmo MD5 digest = hashlib.md5() #Se captura la fecha en que se inicia la transmision del archivo fechaInicioTransmision = datetime.datetime.now() self.monitor.start() #Mientras aun haya datos por leer y por enviar while data: #Si se pueden enviar aun datos al cliente, se actualiza el digest y se aniade un paquete if (self.sock.sendto(data, self.address)): self.monitor.addPacket(len(data)) digest.update(data) data = f.read(BUFFER_SIZE) #Una vez se ha culminado el envio de la informacion, se envia el mensaje END_TRANSMISSION self.sock.sendto(END_TRANSMISSION, self.address) # Se recibe la fecha en que el cliente recibio el ultimo paquete del archivo fecha_fin, _ = self.sock.recvfrom(BUFFER_SIZE) paq_recibidos, _ = self.sock.recvfrom(BUFFER_SIZE) bytes_recibidos, _ = self.sock.recvfrom(BUFFER_SIZE) duracionTransmision = datetime.datetime.strptime( fecha_fin.decode(), '%Y-%m-%d %H:%M:%S.%f') - fechaInicioTransmision paq_recibidos, bytes_recibidos = paq_recibidos.decode( ), bytes_recibidos.decode() print("La duracion total de la transmision fue de: %f s" % (duracionTransmision.total_seconds())) #Se envia el digest generado del mensaje/archivo print('Se ha enviado el digest') digestE = digest.hexdigest().encode() self.sock.sendto(digestE, self.address) #El servidor recibe del cliente si, al realizar la comprobacion del hash, el archivo fue recibido tal cual se transmition entregaExitosa, _ = self.sock.recvfrom(BUFFER_SIZE) if entregaExitosa == OK: self.monitor.finish(True) else: self.monitor.finish(False) print('Comando recibido: ', repr(entregaExitosa)) #Se obtiene el reporte de estadisticas generado por el monitor stats = self.monitor.getReport() print(stats) #Se escribe en el log un mensaje de la forma IP_Cliente:Puerto;Mensaje_Recibido_Correcto?OK:ERR;DURACION_TRANSMISION;NUM_PAQUETES_ENVIADOS;NUM_BYTES_ENVIADOS;NUM_PAQUETES_RECIBIDOS;NUM_BYTES_RECIBIDOS; self.log.write(self.address[0] + ':' + str(self.address[1]) + ';' + repr(entregaExitosa)[2:-1] + ';' + str(duracionTransmision.total_seconds()) + ';' + str(stats['Packets_sent']) + ';' + str(stats['Bytes_sent']) + ';' + paq_recibidos + ';' + bytes_recibidos + ';\n') #Se finaliza la comunicacion con el cliente print('Finalizando exitosamente la comunicacion con: ' + self.address[0] + ':' + str(self.address[1])) #Se envia el comando de finalizacion de envio del archivo print('Enviando comando: ', repr(FIN)) self.sock.sendto(FIN, self.address) #Se cierra el socket self.sock.close()