FTP

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
H.Brill
Beiträge: 497
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

FTP

Beitrag von H.Brill »

Hallo,
bin gerade dabei, die neuen FTP-Funktionen in mein
Prog einzubauen. Scheint irgendwie beim Asyncronen
Modus zu craschen :
Oder kann das an meinem T-Online-Account liegen ?

Code: Alles auswählen

SendFTPFile(0, datei, datei, 1)
möchte das Ganze gerne mit einer Progressbar
und FTPProgress() machen. Hat jemand schon
damit gearbeitet bzw. kann mir einen kleinen
Codeschnipsel geben ?

Die Hilfe ist nicht gerade sehr aussagekräftig.
PB 6.10
Benutzeravatar
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

hi H.Brill,

der code funktioniert mit meinem t-online acount:

Code: Alles auswählen

InitNetwork()
OpenConsole()
If OpenFTP(0, "server", "user", "pass")
  Debug SendFTPFile(0, "c:\ntldr", "test.bin", 1)
  Repeat
    Debug FTPProgress(0)
    Delay(300)
  Until FTPProgress(0) = #PB_FTP_Finished Or FTPProgress(0) = #PB_FTP_Error
Else
  Debug "Failed"
EndIf
mfG
tobe
PureBasic 4.40 (Windows - x86)
Benutzeravatar
H.Brill
Beiträge: 497
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Beitrag von H.Brill »

Danke, hat wohl an der Until - Condition
gehangen.
So gehts bei mir mit Progressbar :

Code: Alles auswählen

   If ReadFile(0, datei) 
      length = Lof(0) 
      CloseFile(0)
   EndIf
   SendFTPFile(0, datei, datei, 1)
   SetGadgetAttribute(100, #PB_ProgressBar_Maximum, length) 
   Repeat 
    SetGadgetState(100, FTPProgress(0))
    Delay(300) 
  Until FTPProgress(0) = #PB_FTP_Finished Or FTPProgress(0) = #PB_FTP_Error 
PB 6.10
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Das solltest du so aber auf keinen Fall einbauen.
Benutzeravatar
H.Brill
Beiträge: 497
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Beitrag von H.Brill »

Was ist denn falsch daran oder was kann ich besser machen?
Ist doch das gleiche, wie bei tobe, nur daß ich in der Schleife die Progressbar füttere.
PB 6.10
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

Beitrag von ts-soft »

> was kann ich besser machen?

Code: Alles auswählen

Delay(300) 
Sowas gehört in keine GUI!
Nimm z.B. ein TimerCallback für den Fortschritt

http://www.purebasic.fr/german/viewtopi ... 561#109561
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
Benutzeravatar
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

ich hab dir jetzt mal nen richtigen codeschnipsel gebastelt ;)
einmal läuft es mit Thread oder mit ApiTimer (ohne callback)
edit: jetzt auch noch mit Callback
die zugangsdaten und die ip muss man noch anpassen

Code: Alles auswählen

EnableExplicit
Define Event, size, file$, Quit, ThreadID, Titel$, FTPProgress, TimerId, ProcTimerId

Procedure FTPProgressBarThread(size)
  Protected FTPProgress
  Shared Quit, ThreadID
  Repeat
    FTPProgress = FTPProgress(0)
    SetGadgetState(3, Int(1000 / size * FTPProgress))
    Delay(10)
  Until FTPProgress = #PB_FTP_Finished Or FTPProgress = #PB_FTP_Error Or Quit
  ThreadID = 0
  If Not Quit
    CloseFTP(0)
    DisableGadget(0, 0)
    DisableGadget(1, 0)
    DisableGadget(2, 0)
  EndIf
EndProcedure

Procedure TimerProc(hwnd, uMsg, idEvent, dwTime)
  Protected FTPProgress
  Shared size, ProcTimerId
  Select idEvent
    Case ProcTimerId
      FTPProgress = FTPProgress(0)
      SetGadgetState(3, Int(1000 / size * FTPProgress))
      If FTPProgress = #PB_FTP_Finished Or FTPProgress = #PB_FTP_Error
        If Not KillTimer_(WindowID(0), idEvent)
          Debug "KillTimer_ Fehler"
        EndIf
        CloseFTP(0)
        DisableGadget(0, 0)
        DisableGadget(1, 0)
        DisableGadget(2, 0)
      EndIf
    Default
      Debug "TimerProc unbekannte id " + Str(idEvent)
  EndSelect
EndProcedure
    
Titel$ = "FTP Progressbar..."
If InitNetwork()
  If OpenWindow(0, 0, 0, 250, 90, Titel$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If CreateGadgetList(WindowID(0))
      ButtonGadget(0, 10, 10, 70, 25, "Thread")
      ButtonGadget(1, 85, 10, 70, 25, "Timer")
      ButtonGadget(2, 160, 10, 80, 25, "TimerCallback")
      ProgressBarGadget(3, 10, 50, 230, 20, 0, 1000, #PB_ProgressBar_Smooth)
      Repeat
        Event = WaitWindowEvent()
        Select Event
          Case #PB_Event_Gadget
            Select EventGadget()
              Case 0, 1, 2
                file$ = OpenFileRequester(Titel$ + " Datei wählen", "", "", 0)
                size = FileSize(file$)
                If file$
                  If OpenFTP(0, "server", "upload", "upload")
                    ;SetFTPDirectory(0, ZielPfad$)
                    If SendFTPFile(0, file$, GetFilePart(file$), 1)
                      DisableGadget(0, 1)
                      DisableGadget(1, 1)
                      DisableGadget(2, 1)
                      Select EventGadget()
                        Case 0
                          ;Thread
                          ThreadID = CreateThread(@FTPProgressBarThread(), size)
                          If Not ThreadID
                            Debug "CreateThread Fehler"
                          EndIf
                        Case 1
                          ;Timer
                          TimerId = 1
                          If Not SetTimer_(WindowID(0), TimerId, 10, 0)
                            Debug "SetTimer_ Fehler"
                          EndIf
                        Case 2
                          ;Timer Callback
                          ProcTimerId = 2
                          If Not SetTimer_(WindowID(0), ProcTimerId, 10, @TimerProc())
                            Debug "SetTimer_Callback Fehler"
                          EndIf
                      EndSelect
                    Else
                      Debug "SendFTPFile Fehler"
                    EndIf
                  Else
                    Debug "OpenFTP Fehler"
                  EndIf
                Else
                  Debug "File Fehler"
                EndIf
            EndSelect
          Case #PB_Event_CloseWindow
            Quit = 1
          Case #WM_TIMER
            If EventwParam() = TimerId
              FTPProgress = FTPProgress(0)
              SetGadgetState(3, Int(1000 / size * FTPProgress))
              If FTPProgress = #PB_FTP_Finished Or FTPProgress = #PB_FTP_Error
                If Not KillTimer_(WindowID(0), TimerId)
                  Debug "KillTimer_ Fehler"
                EndIf
                CloseFTP(0)
                DisableGadget(0, 0)
                DisableGadget(1, 0)
                DisableGadget(2, 0)
              EndIf
            EndIf
        EndSelect
      Until Quit
    Else
      Debug "CreateGadgetList Fehler"
    EndIf
  Else
    Debug "OpenWindow Fehler" 
  EndIf
  If ThreadID
    Debug "Thread läuft noch"
    If Not WaitThread(ThreadID, 1000)
      KillThread(ThreadID)
      Debug "Thread killed"
    Else
      Debug "Thread beendet"
    EndIf
  EndIf
Else
  Debug "InitNetwork Fehler"
EndIf
End
mfG
tobe
Zuletzt geändert von tobe am 14.05.2008 01:31, insgesamt 2-mal geändert.
PureBasic 4.40 (Windows - x86)
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

Beitrag von ts-soft »

Der Timer funktioniert aber in einem Callback viel zuverlässiger!
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
Benutzeravatar
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

mit callback wird es aber auch komplizierter für anfänger :)
sogesehen müsste ich eigentlich den thread teil auch aus dem code rauswerfen sonst ist das ja auch schon zu unüberlichtlich.
wieso ist es mit callback zuverlässiger ?

musste es jetzt gleich mal ausprobieren und hab den oberen code noch etwas erweitert und hier noch die nur callback version:

Code: Alles auswählen

EnableExplicit
Define Event, size, file$, Quit, Titel$
Titel$ = "FTP Progressbar..."

Procedure TimerProc(hwnd, uMsg, idEvent, dwTime)
  Protected FTPProgress
  Shared size
  Select idEvent
    Case 1
      FTPProgress = FTPProgress(0)
      SetGadgetState(1, Int(1000 / size * FTPProgress))
      If FTPProgress = #PB_FTP_Finished Or FTPProgress = #PB_FTP_Error
        If Not KillTimer_(WindowID(0), idEvent)
          Debug "KillTimer_ Fehler"
        EndIf
        CloseFTP(0)
        DisableGadget(0, 0)
      EndIf
    Default
      Debug "TimerProc unbekannte id " + Str(idEvent)
  EndSelect
EndProcedure

If InitNetwork()
  If OpenWindow(0, 0, 0, 250, 90, Titel$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If CreateGadgetList(WindowID(0))
      ButtonGadget(0, 10, 10, 230, 25, "Start")
      ProgressBarGadget(1, 10, 50, 230, 20, 0, 1000, #PB_ProgressBar_Smooth)
      Repeat
        Event = WaitWindowEvent()
        Select Event
          Case #PB_Event_Gadget
            Select EventGadget()
              Case 0
                file$ = OpenFileRequester(Titel$ + " Datei wählen", "", "", 0)
                size = FileSize(file$)
                If file$
                  If OpenFTP(0, "server", "upload", "upload")
                    ;SetFTPDirectory(0, ZielPfad$)
                    If SendFTPFile(0, file$, GetFilePart(file$), 1)
                      DisableGadget(0, 1)
                      If Not SetTimer_(WindowID(0), 1, 10, @TimerProc())
                        Debug "SetTimer_ Fehler"
                      EndIf
                    Else
                      Debug "SendFTPFile Fehler"
                    EndIf
                  Else
                    Debug "OpenFTP Fehler"
                  EndIf
                Else
                  Debug "File Fehler"
                EndIf
            EndSelect
          Case #PB_Event_CloseWindow
            Quit = 1
        EndSelect
      Until Quit
    Else
      Debug "CreateGadgetList Fehler"
    EndIf
  Else
    Debug "OpenWindow Fehler"
  EndIf
Else
  Debug "InitNetwork Fehler"
EndIf
End
aus meiner sicht funktionieren alle 3 methoden gleich gut
PureBasic 4.40 (Windows - x86)
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

Beitrag von ts-soft »

> wieso ist es mit callback zuverlässiger ?
Weil Windows direkt die Funktion ansprechen kann und nicht durch das
PB-Eventhandling hangeln muss :mrgreen:

Mit dem Callback ist es in diesem Fall IMHO genauso zuverlässig wie mit
Thread, aber einfacher und sicherer!
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