FTP Upload socket.error [Errno 104] Connection reset by peer

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
rabe0577
User
Beiträge: 6
Registriert: Dienstag 15. September 2015, 19:23

Nabend zusammen,
bin ganz neu in der Programmierung mit Python und brauche eigentlich nur ein kleines upload Script. Jedoch will mein bisheriges kleines Script nicht so wie ich es will.

Code: Alles auswählen

import ftplib
import os,sys
import datetime
 
try:
        sys.argv[1]
except IndexError:
        print "usage:",__file__,"<dir>"
        exit()
 
ftp_dir="/ZIELORDNER"
server="IP FTP ZIELSERVER"
user="FTP USER ZIELSERVER"
pw="FTP PASSWORT ZIELSERVER"
 
sdir = " ".join(sys.argv[1:])
ftp = ftplib.FTP(server)
ftp.login(user, pw)
 
ftp.cwd(ftp_dir)
targetname=datetime.datetime.now().strftime("%d.%m.%y_%H-%M")

ftp.mkd(targetname)
 
tp=os.popen("nice -1 tar cf - "+sdir)
 
ftp.storbinary('STOR %s' % targetname+"/Upload.tar", tp)
 
ftp.close()
Ich möchte, dass wenn man das Script ausführt, ein Ordner mit dem aktuellen Datum und der Uhrzeit angelegt wird. Anschließend sollen die Dateien die als Argument, hinter dem ausführen des Scripts eingegeben werden, in eine .tar gesteckt werden und auf den FTP geladen werden. Komprimiert sollen sie nicht werden.

Das funktioniert auch fast alles so weit gut. Wenn ich jedoch einen bestimmten Ordner mit etwa 6 GB als Argument eintrage, bricht das Script immer bei 2 GB ab und gibt mir diese Fehlermeldung aus:

Code: Alles auswählen

Traceback (most recent call last):
  File "/ftp_backup/ftp_backup.py", line 38, in <module>
    ftp.storbinary('STOR %s' % targetname+"/Upload.tar", tp)
  File "/usr/lib/python2.7/ftplib.py", line 465, in storbinary
    conn.sendall(buf)
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 104] Connection reset by peer
tar: -: Nur 2048 von 10240 Bytes geschrieben
tar: Error is not recoverable: exiting now
Woran kann das liegen? Gibt es bei Python irgendeine Beschränkung, in der vorgegeben wird, wie groß maximal eine hochzuladene Datei sein darf, oder was mache ich falsch? Habe ich vielleicht irgendwas vergessen, oder kann man es sogar komplett anders bzw. performanter programmieren?

Gruß Janik
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Ohne auf den Rest deines Scripts einzugehen:

Der Fehler "Connection reset by peer" bedeutet, dass der Server die Verbindung zurückgesetzt hat.
Möglicherweise ist der maximale Upload auf Seite des Servers je Datei so konfiguriert, dass er maximal 2GB sein darf, oder das darunterliegende Dateisystem kann keine größeren Dateien speichern.
rabe0577
User
Beiträge: 6
Registriert: Dienstag 15. September 2015, 19:23

Das habe ich auch schon vermutet. Jedoch hab ich mir dann mal eine 10 GB Testdatei heruntergeladen und diese auf den Server hochgeladen. Funktionierte ohne Probleme und wurde auch ohne Probleme gespeichert.

Das verwirrt mich nämlich ein wenig. Dann kann es ja eigentlich nur noch an meinem Script liegen, oder gibt es noch andere mögliche Fehlerquellen?
BlackJack

@rabe0577: Hast Du die 10 GB-Datei mit dem Skript hochgeladen oder mit einem anderen FTP-Client? Gibt es das Problem nur bei dem „bestimmten Ordner“ oder bei jedem mit mehr als 2 GB an Daten? Hast Du Zugriff auf das Fehlerprotokoll vom FTP-Server um zu sehen was dort als Grund für den Verbindungsabbruch angegeben wird?

Der ``nice``-Aufruf dürfte unnötig sein weil selbst lokal der Flaschenhals bei nicht komprimierendem ``tar`` der Datendurchsatz der Festplatte sein dürfte. Falls nicht (SSD statt HDD zum Beispiel) dann bremst der Netzwerkverkehr das Ganze aus. ``-f -`` ist ebenfalls unnötig weil die Standardausgabe, nun ja die Standardausgabe ist wenn man keine Datei mit ``-f`` angibt. :-)

In neuem Python-Code sollte man übrigens eher das `subprocess`-Modul anstelle von `os.popen()` verwenden.

Die Kombination von ``%`` und ``+`` beim Zusammensetzen des FTP-Befehls ist schräg. Da reicht *eine* literale Zeichenkette und er ``%``-Operator, beziehungsweise würde ich persönlich den durch die `format()`-Methode ersetzen.
Antworten