web-dev-qa-db-fra.com

Envoi d’un fichier sur TCP sockets in Python

J'ai réussi à copier le contenu du fichier (image) dans un nouveau fichier. Cependant, lorsque j'essaie la même chose avec TCP sockets, je suis confronté à des problèmes. La boucle du serveur ne se ferme pas. La boucle client se ferme lorsqu'elle atteint l'EOF, mais le serveur ne parvient pas à reconnaître EOF. .

Voici le code:

Serveur

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

Client

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

Voici la capture d'écran:

Serveur Server

Client Client

Edit 1: Extra data copied over. Rendre le fichier "non complet". La première colonne montre l'image qui a été reçue. Il semble être plus grand que celui envoyé. Pour cette raison, je ne peux pas ouvrir l'image. Cela ressemble à un fichier corrompu.

File sizes

Edit 2: Voici comment je le fais dans la console. La taille des fichiers est la même ici. Python ConsoleSame file sizes

36
Swaathi Kakarla

Le client doit notifier qu'il a fini d'envoyer, en utilisant socket.shutdown (pas socket.close qui ferme les deux parties lecture/écriture du socket):

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

[~ # ~] met à jour [~ # ~]

Le client envoie Hello server! sur le serveur; qui est écrit dans le fichier côté serveur.

s.send("Hello server!")

Supprimez la ligne ci-dessus pour l'éviter.

27
falsetru

Supprimer le code ci-dessous

s.send("Hello server!")

parce que vous envoyez s.send("Hello server!") au serveur, votre fichier de sortie est donc un peu plus volumineux.

5
Rama Krishna

Vous pouvez envoyer un drapeau pour arrêter la boucle sur le serveur

par exemple

serveur:

import socket
s = socket.socket()
s.bind(("localhost", 5000))
s.listen(1)
c,a = s.accept()
filetodown = open("img.png", "wb")
while True:
   print("Receiving....")
   data = c.recv(1024)
   if data == b"DONE":
           print("Done Receiving.")
           break
   filetodown.write(data)
filetodown.close()
c.send("Thank you for connecting.")
c.shutdown(2)
c.close()
s.close()
#Done :)

clinet:

import socket
s = socket.socket()
s.connect(("localhost", 5000))
filetosend = open("img.png", "rb")
data = filetosend.read(1024)
while data:
    print("Sending...")
    s.send(data)
    data = filetosend.read(1024)
filetosend.close()
s.send(b"DONE")
print("Done Sending.")
print(s.recv(1024))
s.shutdown(2)
s.close()
#Done :)
1
J0KER11

Le problème est 13 octets supplémentaires que server.py reçoit au début. Pour résoudre ce problème, écrivez "l = c.recv (1024)" deux fois avant la boucle while comme ci-dessous.

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):

Cela résout le problème, essayé avec différents formats et tailles de fichiers. Si quelqu'un sait à quoi se réfèrent ces 13 octets de départ, veuillez répondre.

1
gajendra

Mettre le fichier à l'intérieur while True ainsi

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()   
0
Irviano Yoe

vous pouvez changer votre condition de boucle en fonction du code suivant, lorsque la longueur de l est inférieure à la taille de la mémoire tampon, cela signifie qu'elle a atteint la fin du fichier

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