Enviar un archivo a través de sockets TCP en Python

He podido copiar el contenido del archivo (imagen) a un nuevo archivo. Sin embargo, cuando bash lo mismo a través de sockets TCP, estoy enfrentando problemas. El bucle del servidor no está saliendo. El bucle del cliente se cierra cuando alcanza el EOF, sin embargo, el servidor no puede reconocer el EOF.

Aquí está el código:

Servidor

import socket # Import socket module s = socket.socket() # Create a socket object host = socket.gethostname() # Get local machine name port = 12345 # Reserve a port for your service. s.bind((host, port)) # Bind to the port f = open('torecv.png','wb') s.listen(5) # Now wait for client connection. while True: c, addr = s.accept() # Establish connection with client. print 'Got connection from', addr print "Receiving..." l = c.recv(1024) while (l): print "Receiving..." f.write(l) l = c.recv(1024) f.close() print "Done Receiving" c.send('Thank you for connecting') c.close() # Close the connection 

Cliente

 import socket # Import socket module s = socket.socket() # Create a socket object host = socket.gethostname() # Get local machine name port = 12345 # Reserve a port for your service. s.connect((host, port)) s.send("Hello server!") f = open('tosend.png','rb') print 'Sending...' l = f.read(1024) while (l): print 'Sending...' s.send(l) l = f.read(1024) f.close() print "Done Sending" print s.recv(1024) s.close # Close the socket when done 

Aquí está la captura de pantalla:

Servidor Servidor

Cliente Cliente

Edición 1: Datos extra copiados. Haciendo el archivo “no completo”. La primera columna muestra la imagen que se ha recibido. Parece ser más grande que el enviado. Debido a esto, no puedo abrir la imagen. Parece un archivo corrupto.

Tamaños de archivo

Edición 2: Así es como lo hago en la consola. Los tamaños de archivo son los mismos aquí. Consola de PythonMismos tamaños de archivo

El cliente debe notificar que finalizó el envío, utilizando socket.shutdown (no socket.close que cierra ambas partes de lectura / escritura del socket):

 ... print "Done Sending" s.shutdown(socket.SHUT_WR) print s.recv(1024) s.close() 

ACTUALIZAR

¡El cliente envía el Hello server! al servidor; que se escribe en el archivo en el lado del servidor.

 s.send("Hello server!") 

Retire la línea anterior para evitarlo.

Eliminar el código de abajo

 s.send("Hello server!") 

porque su envío s.send("Hello server!") al servidor, por lo que su archivo de salida es algo más grande en tamaño.

El problema es de 13 bytes adicionales que server.py recibe al inicio. Para resolver eso, escriba “l = c.recv (1024)” dos veces antes del bucle while como se muestra a continuación.

 print "Receiving..." l = c.recv(1024) #this receives 13 bytes which is corrupting the data l = c.recv(1024) # Now actual data starts receiving while (l): 

Esto resuelve el problema, intentado con diferentes formatos y tamaños de archivos. Si alguien sabe a qué se refiere este inicio de 13 bytes, responda.

Poner el archivo en el interior while True como tal

 while True: f = open('torecv.png','wb') c, addr = s.accept() # Establish connection with client. print 'Got connection from', addr print "Receiving..." l = c.recv(1024) while (l): print "Receiving..." f.write(l) l = c.recv(1024) f.close() print "Done Receiving" c.send('Thank you for connecting') c.close() 

puede cambiar su condición de bucle de acuerdo con el siguiente código, cuando la longitud de l es menor que el tamaño del búfer significa que llegó al final del archivo

 while (True): print "Receiving..." l = c.recv(1024) f.write(l) if len(l) < 1024: break