Seite 1 von 5

FTP-Übertragung langsam

Verfasst: 16.09.2015 12:49
von texti
Hallo Ihr da draußen!
Wie im Betreff schon geschrieben, ist bei mir der Upload einer großen Datei (etwa 13GB) per FTP ziemlich langsam bzw. die vorhandene Bandbreite wird nur zu etwa 1/4 genutzt (siehe Monitor Fritzbox).

Bild

Der Code dazu ist hier:

Code: Alles auswählen

  dateiname$=tag$+"daten.rar"
  If OpenFTP(1, "ftp-adresse", "benutzer", "passwort")
    Ergebnis = SendFTPFile(1, "x:\backup\"+dateiname$, dateiname$,1)
    bytenull=0
    Repeat
      Delay(1000)
      byteold=byteaktuell
      byteaktuell=FTPProgress(1)
      byteintervall=byteaktuell-byteold
      If byteintervall<10
        bytenull=bytenull+1
       Else
        bytenull=0
      EndIf
      SetGadgetText(10,"TE-FTP - sende Zeichen: "+FormatByteSize(byteaktuell/1024/1024)+" MB - "+FormatByteSize(byteintervall/1024)+" kByte/s")
    Until (FTPProgress(1) = -3 Or FTPProgress(1) = -2) Or (bytenull>30)
  EndIf
  CloseFTP(1)
Was mache ich falsch, oder wie kann die vorhandene Bandbreite voll ausgenutzt werden, damit der Upload schneller geht? Mit Filezilla (gleiche Datei, gleicher FTP-Server) funktioniert es.

Vielen Dank schon mal für Eure Mühe.

Gruß
texti

Re: FTP-Übertragung langsam

Verfasst: 16.09.2015 19:12
von Andesdaf
möglicherweise hilft es, den Debugger auszuschalten.

Re: FTP-Übertragung langsam

Verfasst: 16.09.2015 19:46
von Kiffi
... oder mal testweise den Asynchronous-Parameter auf #False stellen. Dann aktualisiert sich Deine GUI zwar nicht, aber Du kannst zumindest schauen, ob sich die Geschwindigkeit ändert.

Grüße ... Peter

Re: FTP-Übertragung langsam

Verfasst: 16.09.2015 21:04
von HeX0R
Jede Menge Probleme hier:
- Delay hat in einer Anwendung mit Fenstern nix verloren
- Während des Uploads werden keinerlei Events verarbeitet
- Das ist alles nur kein lauffähiges Beispiel, was genau soll man hier sehen?

Hier mal ein lauffähiges Beispiel, ohne Delay und mit ordentlichem Eventhandling.
Damit bekomme ich einen netten Speed hin (60MByte/s)

Code: Alles auswählen

InitNetwork()

Enumeration
	#String_FTP_Server
	#String_FTP_User
	#String_FTP_Password
	#String_FTP_UploadFile
	#Button_FTP_BrowseUploadFile
	#String_FTP_PathOnServer
	#Editor_Log
	#Button_StartUpload
EndEnumeration

Global SIZE_OF_FTP_FILE.q
Global START_OF_UPLOAD.i

Procedure.s ByteRechner(dSize.d, Decimals.i = 2)
	Protected Namen.s = "kMGTPEZY", *C.CHARACTER, Result.s = "0"

	If dSize > 0.0
		If dSize < 1024
			Result = StrD(dSize, Decimals) + " " + "Byte"
		Else
			dSize / 1024
			*C = @Namen
			While dSize > 1024 And *C\c <> 0
				dSize / 1024
				*C + SizeOf(CHARACTER)
			Wend
			Result = StrD(dSize, Decimals) + " " + Chr(*C\c) + "Byte"
		EndIf
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure GadgetEvent_BrowseUploadFile()
	Protected a$
	
	a$ = OpenFileRequester("Select Upload File", "bla.rar", "All files (*.*)|*.*", 0)
	If a$
		SetGadgetText(#String_FTP_UploadFile, a$)
	EndIf
EndProcedure

Procedure GadgetEvent_StartUpload()
	Protected Path.s, i, Result
	
	If GetGadgetText(#String_FTP_PathOnServer) And GetGadgetText(#String_FTP_Server) And GetGadgetText(#String_FTP_UploadFile)
		
		If OpenFTP(0, GetGadgetText(#String_FTP_Server), GetGadgetText(#String_FTP_User), GetGadgetText(#String_FTP_Password)) = 0
			AddGadgetItem(#Editor_Log, -1, "Unable to connect to Server!")
		Else
			Path   = GetGadgetText(#String_FTP_PathOnServer)
			Result = #True
			If Left(Path, 1) <> "/"
				Path = "/" + Path
			EndIf
			For i = 1 To CountString(Path, "/")
				If SetFTPDirectory(0, StringField(Path, i + 1, "/")) = 0
					AddGadgetItem(#Editor_Log, -1, "Error! Can't get into " + StringField(Path, i + 1, "/") + "!")
					Break
				Else
					AddGadgetItem(#Editor_Log, -1, "Set Directory to " + StringField(Path, i + 1, "/"))
				EndIf
			Next i
			SIZE_OF_FTP_FILE = FileSize(GetGadgetText(#String_FTP_UploadFile))
			If SendFTPFile(0, GetGadgetText(#String_FTP_UploadFile), GetFilePart(GetGadgetText(#String_FTP_UploadFile)), #True) = 0
				Result = #False
				AddGadgetItem(#Editor_Log, -1, "Error! Can't upload file: " + GetGadgetText(#String_FTP_UploadFile) + "!")
			EndIf
			
			If Result = #False
				CloseFTP(0)
				SIZE_OF_FTP_FILE = #Null
			Else
				DisableGadget(#Button_StartUpload, 1)
				StatusBarProgress(0, 0, 0)
				START_OF_UPLOAD = ElapsedMilliseconds()
			EndIf
		EndIf
	EndIf
	
EndProcedure

Procedure MyTimerEvent()
	Protected q.q, speed.d, d.d
	
	If IsFTP(0)
		q = FTPProgress(0)
		Select q
			Case #PB_FTP_Started
				;reset our time var
				START_OF_UPLOAD = ElapsedMilliseconds()
			Case #PB_FTP_Finished
				;finished, close ftp and add speed info
				speed = SIZE_OF_FTP_FILE / ((ElapsedMilliseconds() - START_OF_UPLOAD) / 1000)
				AddGadgetItem(#Editor_Log, -1, "Speed: " + ByteRechner(Speed) + "/s")
				StatusBarProgress(0, 0, 100)
				CloseFTP(0)
				DisableGadget(#Button_StartUpload, 0)
			Case #PB_FTP_Error
				AddGadgetItem(#Editor_Log, -1, "An error occured while uploading!")
				StatusBarProgress(0, 0, 100)
				CloseFTP(0)
				DisableGadget(#Button_StartUpload, 0)
			Default
				d = 100 * (q / SIZE_OF_FTP_FILE)
				StatusBarProgress(0, 0, d)
		EndSelect
	EndIf
	
EndProcedure

Procedure main()
	
	OpenWindow(0, 0, 0, 330, 460, "FTP-Upload-Test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
	
	TextGadget(#PB_Any, 5, 5, 100, 20, "FTP-Server:")
	StringGadget(#String_FTP_Server, 110, 5, 160, 22, "")
	TextGadget(#PB_Any, 5, 30, 100, 20, "Username:")
	StringGadget(#String_FTP_User, 110, 30, 160, 22, "")
	TextGadget(#PB_Any, 5, 55, 100, 20, "Password:")
	StringGadget(#String_FTP_Password, 110, 55, 160, 22, "")
	TextGadget(#PB_Any, 5, 80, 100, 20, "Upload-File:")
	StringGadget(#String_FTP_UploadFile, 110, 80, 160, 22, "")
	ButtonGadget(#Button_FTP_BrowseUploadFile, 275, 80, 40, 22, "...")
	TextGadget(#PB_Any, 5, 105, 100, 20, "Path on Server:")
	StringGadget(#String_FTP_PathOnServer, 110, 105, 160, 22, "")
	
	ButtonGadget(#Button_StartUpload, 110, 140, 80, 26, "Start Upload")
	
	EditorGadget(#Editor_Log, 5, 180, 320, 250, #PB_Editor_ReadOnly)
	
	CreateStatusBar(0, WindowID(0))
	AddStatusBarField(#PB_Ignore)
	AddWindowTimer(0, 0, 10)
	
	BindGadgetEvent(#Button_FTP_BrowseUploadFile, @GadgetEvent_BrowseUploadFile())
	BindGadgetEvent(#Button_StartUpload, @GadgetEvent_StartUpload())
	BindEvent(#PB_Event_Timer, @MyTimerEvent())
	
	While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
	
	If IsFTP(0)
		CloseFTP(0)
	EndIf
EndProcedure

main()

Re: FTP-Übertragung langsam

Verfasst: 17.09.2015 00:41
von Bisonte
Zu Hex0r noch hinzufügen möchte ich, dass es auch am Empfänger oder der Verbindung liegen kann! Man bekommt selten die maximale Up/Download Geschwindigkeit... und dann sieht das ganze noch nach Tel*k*m und Vectoring aus ;) ... Die Schummeln sich mit den Geschwindigkeitsangaben eh durch....

Re: FTP-Übertragung langsam

Verfasst: 17.09.2015 10:26
von texti
Hallo und Danke für die Antworten!
@ HeX0R: das sieht sehr gut aus und ich werde das auf jeden Fall mal so einbauen und probieren. DANKE dafür!
Der Debugger ist aus und die Verbindung steht auch durchgehend ganz gut.

Habe das jetzt so gelöst: Die Backup-Datei wird in 4GB große Dateien gepackt (WinRAR) und die werden gleichzeitig hoch geladen. Das funktioniert erstaunlicher Weise mit vollem Upload. Warum das mit nur einer Upload-Datei unter PureBasic nicht geht, würde mich aber trotzdem mal interessieren. Delay ist immer noch drin (@HeX0R: warum sollte man das nicht machen?), abbrechen läuft verzögert, aber ohne Probleme und die Anzeige aktualisiert sich auch regelmäßig. Danke nochmal für Eure Hilfe und bin für alle Vorschläge offen!

Code: Alles auswählen

tag$="16"

Dim dateiname$(50)

Procedure.s FormatByteSize(n.q)
  Protected s.s=Str(n)
  Protected len=Len(s)
  Protected ret.s
  For i=0 To len-1
    If i And Not i%3 :: ret="."+ret :: EndIf
    ret= Mid(s,len-i,1) +ret
  Next
  ProcedureReturn ret
EndProcedure

OpenWindow(0,0,0,600,270,"FTP-Backup Upload V1.01",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
  TextGadget(1, 30, 30, 540, 40, "Start", #PB_Text_Center)
  SetGadgetFont(1, FontID1)
  TextGadget(2, 30, 80, 540, 40, "Teile", #PB_Text_Center)
  SetGadgetFont(2, FontID1)
  TextGadget(4, 30, 130, 540, 40, "Datendurchsatz", #PB_Text_Center)
  SetGadgetFont(4, FontID1)
  ProgressBarGadget(5, 30, 180, 540, 10, 0, 100)
  TextGadget(6, 30, 210, 540, 40, "%", #PB_Text_Center)
  SetGadgetFont(6, FontID1)
  


SetGadgetText(1,"Übertragung gestartet: " + FormatDate("%dd.%mm.%yyyy", Date()) + " - " + FormatDate("%hh:%ii:%ss", Date()))
anzahl=0
gesamtlaenge.q=0
If ExamineDirectory(0, "x:\backup\", tag$+"date*.*")  
  While NextDirectoryEntry(0)
    If DirectoryEntryType(0) = #PB_DirectoryEntry_File      ;ist datei
      anzahl=anzahl+1
      dateiname$(anzahl)=DirectoryEntryName(0)
      gesamtlaenge.q = gesamtlaenge.q + DirectoryEntrySize(0)
    EndIf
  Wend
  FinishDirectory(0)
EndIf

Ergebnis=InitNetwork() 
For zaehler=1 To anzahl
  OpenFTP(zaehler, "ftp-url", "benutzer", "passwort")
  SetFTPDirectory(zaehler, "backup")
  Ergebnis = DeleteFTPFile(zaehler, dateiname$(zaehler))
  Ergebnis = SendFTPFile(zaehler, "x:\backup\"+dateiname$(zaehler), dateiname$(zaehler),1)
Next

Repeat
  Delay(1000)
  Ereignis = WindowEvent()
  If Ereignis = #PB_Event_CloseWindow
    MessageRequester("Ende","Programm normal beendet")
    End
  EndIf
  byteold.q=byteaktuell.q
  byteaktuell.q=0
  geschlossen=0
  For zaehler=1 To anzahl
    byteaktuell.q=byteaktuell.q+FTPProgress(zaehler)
    If FTPProgress(zaehler)=-3 Or FTPProgress(zaehler)=-2
      geschlossen=geschlossen+1
    EndIf
  Next
  byteintervall.q=byteaktuell.q-byteold.q
  If byteintervall.q<10
    bytenull=bytenull+1
   Else
    bytenull=0
  EndIf
  SetGadgetText(2,Str(anzahl)+" Teil(e) insgesamt - aktiv "+Str(anzahl-geschlossen)+" Teil(e)")
  SetGadgetText(4,"TE-FTP - sende Zeichen: "+FormatByteSize(byteaktuell/1024/1024)+" MB - "+FormatByteSize(byteintervall/1024)+" kByte/s")
  prozent=Int(byteaktuell.q*100/gesamtlaenge.q)
  SetGadgetState(5, prozent)
  SetGadgetText(6,Str(prozent)+" %")
Until (geschlossen=anzahl) Or (bytenull>60) Or (FormatDate("%hh:%ii", Date())="22:00")
For zaehler=1 To anzahl
  CloseFTP(zaehler)
Next
Gruß
texti

Re: FTP-Übertragung langsam

Verfasst: 17.09.2015 11:28
von ts-soft
Tja, warum ist ein Delay in einer Fensteranwendung unnötig?
Weil wir nur auf Ereignisse reagieren!

Dein "Eventloop" läuft von oben nach unten durch, es wird also alles angezeigt,
aber nur wenn das Delay gerade um ist. Das kann nicht effektiv sein!

Nur auf Ereignisse reagieren (WaitWindowsEvent() und nicht WindowEvent(). Ereignisse
können auch erstellt werden, wie z.B. durch einen Timer (siehe Dein 1000er Delay, aber nur
das dort rein, was nirgendswo anders passt bzw. kein anderes Ereignis erzeugt).

Sehe Dir das Beispiel von Hexor nochmals genau an und überlege, wann er worauf reagiert.
Man kann das Beispiel von Hexor auf ohne BindGadgetEvent() oder BindEvent() schreiben.

Ich werde Dir jetzt kein Beispiel geben, es gibt ja auch bereits eins, sondern dies dient nur
der Anregung und dem Verständnis für Fensterbehandlung!

Dieses Verständnis ist fundamentale Voraussetzung für Fensterprogrammierung!

Gruß
Thomas

Re: FTP-Übertragung langsam

Verfasst: 17.09.2015 11:36
von texti
Danke Thomas, aber da stehe ich auf dem Schlauch. Meinst du das hier:

Code: Alles auswählen

 While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Wo wird dann die Anzeige aktualisiert?

Gruß
texti (Gorden)

Re: FTP-Übertragung langsam

Verfasst: 17.09.2015 11:40
von texti
... nebenbei gibt das aber leider immer noch keine Antwort auf die Frage, warum PureBasic nur etwa 1/4 der Upload-Bandbreite (bei einem Upload) nutzt ...
Gruß
Gorden

Re: FTP-Übertragung langsam

Verfasst: 17.09.2015 12:10
von ts-soft
texti hat geschrieben:Danke Thomas, aber da stehe ich auf dem Schlauch. Meinst du das hier:

Code: Alles auswählen

 While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Wo wird dann die Anzeige aktualisiert?
Hexor hat alles in "Callbacks" ausgelagert, kannst aber auch normale Routinen nutzen, z.B.:

Code: Alles auswählen

AddWindowTimer(0, 1, 10)
; BindEvent(#PB_Event_Timer, @MyTimerEvent())
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Timer
      Select EventTimer()
        Case 1 ; timer mit der nr. 1
          If IsFTP(0)
            q = FTPProgress(0)
            Select q
              Case #PB_FTP_Started
                ;reset our time var
                START_OF_UPLOAD = ElapsedMilliseconds()
              Case #PB_FTP_Finished
                ;finished, close ftp and add speed info
                speed = SIZE_OF_FTP_FILE / ((ElapsedMilliseconds() - START_OF_UPLOAD) / 1000)
                AddGadgetItem(#Editor_Log, -1, "Speed: " + ByteRechner(Speed) + "/s")
                StatusBarProgress(0, 0, 100)
                CloseFTP(0)
                DisableGadget(#Button_StartUpload, 0)
              Case #PB_FTP_Error
                AddGadgetItem(#Editor_Log, -1, "An error occured while uploading!")
                StatusBarProgress(0, 0, 100)
                CloseFTP(0)
                DisableGadget(#Button_StartUpload, 0)
              Default
                d = 100 * (q / SIZE_OF_FTP_FILE)
                StatusBarProgress(0, 0, d)
            EndSelect
          EndIf
      EndSelect
    Case #PB_Event_CloseWindow
      Break
    ; ...
  EndSelect
ForEver
so in etwa.
Das mit der Upload-Bandbreite sollte sich dann auch erledigt haben.