Seite 1 von 2

OpenNetworkConnection ohne programmstop

Verfasst: 04.09.2007 22:38
von R4z0r1989
gibt es irgendeine möglichkeit OpenNetworkConnection auszuführen ohne dass der programmcode stopt wenn der Server nicht existiert?

und eine möglichkeit zu überprüfen ob die verbindung zum server noch existiert wenn eine verbindung schon statrgefunden hat?

dies ist wichtig da ich 2 clienten in einen Programm hab und falls einer ausfällt muss ich noch daten zu den Clienten schicken können und der andre Client muss gleichzeit versuchen eine verbindung aufzubaun,
da diese beiden sachen wichtig sind brauch ich diese beinen oben genannten sachen!

Vielen Dank schon im vorraus!

Re: OpenNetworkConnection ohne programmstop

Verfasst: 04.09.2007 23:06
von R4z0r1989
Sirhc.ITI hat geschrieben:Pack OpenNetworkConnection in einen Thread und prüfe danach mit IsThread() wan der Thread fertig ist. Den Rückgabewert kannst du ja über eine globale Variable oder besser noch mit einem pointer machen.
da liegt mein problem ich hab von Threads keine ahnung....
wäre echt nett wenn du mir da vl unter die arme greifen könntest!
und das mit dem ping werd ich machen aber da seh ich nur ein problem:
was wenn der server noch da ist aber ich nen neuen aufmach dann stürtzt doch das prog ab oder?

Verfasst: 05.09.2007 09:40
von gnasen
da liegt mein problem ich hab von Threads keine ahnung....
Das ganze ist sehr ausführlich und gut erklärt in der Hilfe zu finden (F1). Such einfach nach "Thread", bzw "CreateThread" und lass dich dann mit den Links durchs Thema führen.

Platt kann man sagen, dass ein Thread parallel zu deinem Programm läuft. Solltest du zB eine Endlosschleife proggen (zB eine abfrage der Network Events) erstellst du einfach einen neuen Thread, der parallel laufend dein Programm nicht beeinflusst.

Procedure BeispielEndlosschleife()
...
Endprocedure

CreateThread(@BeispielEndlosschleife(), 0)

Verfasst: 05.09.2007 21:24
von a14xerus
gnasen hat geschrieben:Procedure BeispielEndlosschleife()
...
Endprocedure

CreateThread(@BeispielEndlosschleife(), 0)
ACHTUNG:

Code: Alles auswählen

Global Ende.l
Procedure BeispielEndlosschleife(dummy.l) ; <- es MUSS EIN parameter vorhanden sein
repeat
  if ENDE
    procedurereturn
  endif
forever
Endprocedure

CreateThread(@BeispielEndlosschleife(), 0)
;blablabla code
; Bei Programmende:
Ende = 1 ; Variable Ende afu #True setzen damit sich der Thread sicher beendet
; Dann ggf mit ishread() noch kurz warten dun dann isset auch noch schön sicher beendet alles
Dann noch unter Projektoptionen: Threadsafe anklicken und fertig ;)

Verfasst: 05.09.2007 22:48
von gnasen
Procedure BeispielEndlosschleife(dummy.l) ; <- es MUSS EIN parameter vorhanden sein
Ich bin mir ziemlich sicher, dass das auch ohne ging. Aber ich lass mich auch gerne etwas besseren belehren ;)

Verfasst: 05.09.2007 23:55
von NicTheQuick
Man muss einen Thread auch nicht unbedingt sicher beenden. Außer es
müssen Sachen freigegeben werden oder dergleichen. In dem Fall kann man
dann mit 'WaitThread()' auf das Ende des Threads warten.

Verfasst: 05.09.2007 23:59
von PMV
NicTheQuick hat geschrieben:Man muss einen Thread auch nicht unbedingt sicher beenden.
Was meinst du damit? ... du drückst dich da sehr unglücklich aus.

Ein Thread sollte immer "sauber" (sicher) beendet werden. Ob man
darauf warten will/ muss ist eine andere Sache.

Ach ja, der angesprochende Parameter muss immer vom Typ Long sein.

MFG PMV

Verfasst: 06.09.2007 02:03
von mk-soft
PMV hat geschrieben:
NicTheQuick hat geschrieben: Ach ja, der angesprochende Parameter muss immer vom Typ Long sein.
MFG PMV
Kann auch ein Pointer auf eine Struktur sein. Somit kann man einen Thread auch einen Poll von Daten übergeben.

Nachtrag:
Jeden Client in ein eigenen Thread laufen lassen. Threadsafe erforderlich.
Mit Globaler Variable "ende" auf 1 werden die Threads beendet.

Hatte mit den Beispiel getestet ob man über mehrere Threads arbeiten kann:

Code: Alles auswählen

Global ende.l

InitNetwork()

Procedure MyThread(*this.s)

  Protected ConnectionID, todo.l, len, t
  Protected *buffer
  
  ; Warten auf Verbindung zum Server oder auf Abbruch
  While ende = 0
    ConnectionID = OpenNetworkConnection("localhost", 7000)
    If ConnectionID <> 0
      Break
    EndIf
    Delay(500)
  Wend
  
  If ende
    If ConnectionID <> 0
      CloseNetworkConnection(ConnectionID)
    EndIf
    ProcedureReturn 1
  EndIf
  
  ; Speicher anfordern
  *buffer = AllocateMemory($4000)
  
  Repeat
    
    Select NetworkClientEvent(ConnectionID)
    
    Case #PB_NetworkEvent_Data
      len = ReceiveNetworkData(ConnectionID, *buffer, $4000)
      ; Daten auswerten
      Debug PeekS(*buffer, len)
      
    Case #PB_NetworkEvent_File
    
    Default
      Select todo
      Case 0:
        Debug "New " + *this
        SendNetworkString(ConnectionID, "NEW Test=100"+#CR$)
        todo = 1
      Case 2:
        Debug "Get " + *this
        SendNetworkString(ConnectionID, "GET "+*this+#CR$)
        todo = 3
      Case 4:
        Debug "Pause" + *this
        Delay(1000)
        todo = 2  
      EndSelect
      Delay(100)
      t + 100
      If t > 1000
        todo + 1
        t = 0
      EndIf
    EndSelect
    
  Until ende
  
  ; Verbindung schliessen
  CloseNetworkConnection(ConnectionID)
  ; Speicher freigeben
  FreeMemory(*buffer)
  
EndProcedure


;- Konstanten
Enumeration ; Window ID
  #Window
EndEnumeration

Enumeration ; Menu ID
  #Menu
EndEnumeration

Enumeration ; MenuItem ID
  #Menu_Exit
EndEnumeration

Enumeration ; Statusbar ID
  #Statusbar
EndEnumeration

Enumeration ; Gadget ID
  
EndEnumeration

; ***************************************************************************************

;- Globale Variablen
Global exit = 0


;- Fenster
style = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 400, 300, "Fenster", style)
  ; Menu
  If CreateMenu(#Menu, WindowID(#Window))
    MenuTitle("&Datei")
      MenuItem(#Menu_Exit, "Be&enden")
  EndIf
  ; Statusbar
  CreateStatusBar(#Statusbar, WindowID(#Window))
  ; Gadgets
  If CreateGadgetList(WindowID(#Window))
  
  EndIf

  ; Start Thread
  hThread = CreateThread(@MyThread(),@"Test")
  Delay(400)
  hThread2 = CreateThread(@MyThread(),@"Value")
    
  ;-- Hauptschleife
  Repeat
    event   = WaitWindowEvent()
    window  = EventWindow()
    menu    = EventMenu()
    type    = EventType()
    Select event
      Case #PB_Event_Menu                       ; ein Menü wurde ausgewählt
        Select menu
          Case #Menu_Exit
            Exit = 1
            ende = 1
        EndSelect
      Case #PB_Event_Gadget                     ; ein Gadget wurde gedrückt
      Case #PB_Event_CloseWindow                ; das Schließgadget vom Fenster wurde gedrückt
        Exit = 1
      Case #PB_Event_Repaint                    ; der Fensterinhalt wurde zerstört und muss neu gezeichnet werden (nützlich für 2D Grafik-Operationen) 
      Case #PB_Event_SizeWindow                 ; das Fenster wurde in der Größe verändert
      Case #PB_Event_MoveWindow                 ; das Fenster wurde verschoben
      Case #PB_Event_ActivateWindow             ; das Fenster wurde aktiviert (hat den Fokus erhalten)
      Case #PB_Event_SysTray                    ; das SysTray wurde aktiviert
    
    EndSelect
    
  Until Exit
EndIf

WaitThread(hThread)
WaitThread(hThread2)

Verfasst: 06.09.2007 03:25
von PMV
mk-soft hat geschrieben:
PMV hat geschrieben: Ach ja, der angesprochende Parameter muss immer vom Typ Long sein.
MFG PMV
Kann auch ein Pointer auf eine Struktur sein. Somit kann man einen Thread auch einen Poll von Daten übergeben.
Wie viel Bytes hat den ein 32-Bit-Zeiger? :D
... aber bin mal gespannt, wie Fred das später in der 64-Bit version macht.
<)

MFG PMV

Verfasst: 06.09.2007 17:12
von a14xerus
Sind LONGs unter 64bit Systemen nicht auch 64 Bit lang (also ein normaler Parameter bei übergaben dann immer ein 64 bit para?) bin mir net sicher...