Envío de un archivo a través de sockets TCP en Python
He podido copiar con éxito el contenido del archivo (imagen) a un nuevo archivo. Sin embargo, cuando intento lo mismo sobre sockets TCP me enfrento a problemas. El bucle del servidor no está saliendo. El bucle cliente sale cuando llega al EOF, sin embargo el servidor no puede reconocer 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á el captura de pantalla:
Servidor
Cliente
Editar 1: Datos extra copiados. Hacer que el archivo " no esté completo." La primera columna muestra la imagen que se ha recibido. Parece ser más grande que el enviado. Debido a esto, no soy capaz de abrir la imagen. Parece un archivo dañado.
Edit 2: Así es como lo hago en la consola. Los tamaños de archivo son los mismos aquí.
5 answers
El cliente debe notificar que terminó de enviar, utilizando socket.shutdown
(no socket.close
que cierra tanto la parte de lectura / escritura del zócalo):
...
print "Done Sending"
s.shutdown(socket.SHUT_WR)
print s.recv(1024)
s.close()
UPDATE
El cliente envía 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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-02 05:22:57
Eliminar el código siguiente
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 de tamaño.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-26 12:27:24
El problema es extra 13 bytes que server.py recibe en la salida. 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, probado con diferentes formatos y tamaños de archivos. Si alguien sabe a qué se refiere este inicio de 13 bytes, por favor responda.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-03 19:34:51
Poner el archivo dentro de while True
así
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()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-13 16:59:57
Puede cambiar la condición de su bucle de acuerdo con el siguiente código, cuando la longitud de l es menor que el tamaño del búfer, significa que alcanzó el final del archivo
while (True):
print "Receiving..."
l = c.recv(1024)
f.write(l)
if len(l) < 1024:
break
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-12 13:20:12