FTP-Übertragung langsam

Für allgemeine Fragen zur Programmierung mit PureBasic.
texti
Beiträge: 42
Registriert: 13.03.2009 13:24

FTP-Übertragung langsam

Beitrag 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
Nichts wissen macht nichts. Man muß nur wissen, wo es steht, oder wen man fragen kann . . .
Andesdaf
Moderator
Beiträge: 2660
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: FTP-Übertragung langsam

Beitrag von Andesdaf »

möglicherweise hilft es, den Debugger auszuschalten.
Win11 x64 | PB 6.00 (x64)
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: FTP-Übertragung langsam

Beitrag 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
Hygge
Benutzeravatar
HeX0R
Beiträge: 2959
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win10 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2
Kontaktdaten:

Re: FTP-Übertragung langsam

Beitrag 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()
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: FTP-Übertragung langsam

Beitrag 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....
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
texti
Beiträge: 42
Registriert: 13.03.2009 13:24

Re: FTP-Übertragung langsam

Beitrag 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
Nichts wissen macht nichts. Man muß nur wissen, wo es steht, oder wen man fragen kann . . .
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: FTP-Übertragung langsam

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
texti
Beiträge: 42
Registriert: 13.03.2009 13:24

Re: FTP-Übertragung langsam

Beitrag 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)
Nichts wissen macht nichts. Man muß nur wissen, wo es steht, oder wen man fragen kann . . .
texti
Beiträge: 42
Registriert: 13.03.2009 13:24

Re: FTP-Übertragung langsam

Beitrag 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
Nichts wissen macht nichts. Man muß nur wissen, wo es steht, oder wen man fragen kann . . .
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: FTP-Übertragung langsam

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten