Seite 1 von 2

FTP

Verfasst: 12.05.2008 09:22
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.

Verfasst: 12.05.2008 16:42
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

Verfasst: 12.05.2008 18:42
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 

Verfasst: 12.05.2008 21:15
von edel
Das solltest du so aber auf keinen Fall einbauen.

Verfasst: 13.05.2008 18:14
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.

Verfasst: 13.05.2008 18:24
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

Verfasst: 13.05.2008 23:42
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

Verfasst: 13.05.2008 23:47
von ts-soft
Der Timer funktioniert aber in einem Callback viel zuverlässiger!

Verfasst: 14.05.2008 01:32
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

Verfasst: 14.05.2008 01:36
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!