2 Fragen bezüglich EventClient()

Anfängerfragen zum Programmieren mit PureBasic.
Anxifer
Beiträge: 5
Registriert: 16.06.2009 22:59

2 Fragen bezüglich EventClient()

Beitrag von Anxifer »

Hi@all,
ich hab mal zwei Fragen, die mich etwas ins Grübeln bringen und ich hoffe, dass mir jemand weiterhelfen kann.
Dazu hol ich am besten erstmal etwas aus.

Der Befehl: EventClient() ermittelt ja den Clienten, der Daten versendet hat.
Speichere ich diesen Befehl in eine Variable z.B. ClientID (wie im Beispiel "NetworkServer.pb" in der PB-Hilfe) und lass mir den Wert der Variable anzeigen (z.B. mittels Debug) erscheint eine Zahl.

Nun Meine 1. Frage:
Wenn sich mehrere Clienten zu meinem Server verbinden, ist der Wert der Variable ClientID (also die Zahl) bei den Verschiedenen Clienten in jedem Fall immer unterschiedlich oder kann es auch passieren, dass mehrere Clienten die selbe ClientID haben?

Was mich dann gleich zu meiner 2. Frage führt:
Woraus setzt sich der mittels EventClient() ermittelte Wert zusammen?

Über Hilfe würde ich mich sehr freuen.
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

Für die erste Frage: Jeder Client hat automatisch eine eindeutige, einzigartige ID. Es gibt keine identischen.
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Anxifer
Beiträge: 5
Registriert: 16.06.2009 22:59

Beitrag von Anxifer »

Ok, dankeschön.

Jetzt würde ich nur noch gern wissen, woraus sich der mittels EventClient() ermittelte Wert zusammen setzt.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

das ist vermutlich wieder mal eine ID, also irgendeine Art Handle, das den Client identifiziert.
normalerweise ist sowas ein Pointer zu einer Objektstruktur.

... also nichts, was man auseinandernehmen kann, um Informationen zu erhalten,
sondern etwas, was auf eine Struktur verweist, die die Informationen enthält.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Anxifer
Beiträge: 5
Registriert: 16.06.2009 22:59

Beitrag von Anxifer »

Beim rumbasteln hat sich mir noch eine andere Frage aufgetan.
Ich hab hier mal den Server und den Clienten aus der PB-Hilfe in etwas abgewandelter Form:

Server:

Code: Alles auswählen

Port = 6832
*Buffer = AllocateMemory(1000)

If InitNetwork() = 0
  MessageRequester("Error", "Netzwerk konnte nicht initialisiert werden!", 0)
  End
EndIf

OpenWindow(0,0,0,300,320,"Server",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
TextGadget(0,10,12,110,20,"Verbundene Clienten:")
ListViewGadget(1,10,30,280,280)


If CreateNetworkServer(0, Port)
  MessageRequester("Server", "Server wurde erstellt", 0)

  Repeat
    event=WaitWindowEvent()

    If event=#PB_Event_CloseWindow
      End
    EndIf

    SEvent = NetworkServerEvent()
  
    If SEvent
    
      ClientID = EventClient()
  
      Select SEvent
      
        Case 2
          ReceiveNetworkData(ClientID,*Buffer,1000)
          AddGadgetItem(1,#PB_Any,PeekS(*Buffer))
  
        Case 4
          MessageRequester("Server", "Der Client "+Str(ClientID)+" hat die verbindung geschlossen", 0)
          
      EndSelect
    EndIf

  Delay(50)

ForEver

Else
  MessageRequester("Error", "Server konnte nicht erstellt werden.", 0)
EndIf

End
Client 1:

Code: Alles auswählen

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

Port = 6832

ConnectionID = OpenNetworkConnection("127.0.0.1", Port)

If ConnectionID
  MessageRequester("Client", "Client ist zum Server verbunden. Drücken sie die ESC-Taste um die Verbindung zu unterbrechen und den Clienten zu schließen.", 0)
  SendNetworkString(ConnectionID, "Max Mustermann")
    
  Repeat

    Delay(50)

  Until GetAsyncKeyState_(27)

  CloseNetworkConnection(ConnectionID)

Else
  MessageRequester("Client", "Server konnte nicht gefunden werden", 0)
EndIf
  
End 
Client 2:

Code: Alles auswählen

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

Port = 6832

ConnectionID = OpenNetworkConnection("127.0.0.1", Port)

If ConnectionID
  MessageRequester("Client", "Client ist zum Server verbunden. Drücken sie die ESC-Taste um die Verbindung zu unterbrechen und den Clienten zu schließen.", 0)
  SendNetworkString(ConnectionID, "Karl Kugelschreiber")
    
  Repeat

    Delay(50)

  Until GetAsyncKeyState_(27)

  CloseNetworkConnection(ConnectionID)

Else
  MessageRequester("Client", "Server konnte nicht gefunden werden", 0)
EndIf
  
End 
Wie ihr sicherlich merken werdet unterscheidet sich bei Client 1 und 2 nur der String, der in Zeile 12 versendet wird.

Nun folgendes:
Wenn jetzt ein Client die Verbindung zum Server trennt, müsste ich im Code den befehl RemoveGadgetItem() einfügen damit der Client auch auf der Liste nicht mehr zu sehen ist. Ich weiß allerdings nicht wie ich ermitteln kann, welcher der beiden Clienten die Verbindung zum Server getrennt hat.

Könnte mir das jemand erläutern?
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Beitrag von TomS »

Hä?
Steht doch schon da

Code: Alles auswählen

Case 4
          MessageRequester("Server", "Der Client "+Str(ClientID)+" hat die verbindung geschlossen", 0) 
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Die Hilfe ist nicht ganz aktuell.
Ich empfehle dir, die Konstanten #PB_NetworkEvent_Connect, #PB_NetworkEvent_Data und #PB_NetworkEvent_Disconnect zu benutzen. So sieht man auf den ersten Blick schon, welches Event abgefragt wird. Das ist leserlicher.
Die Beispiele aus der Hilfe sind älter als diese Konstanten, diese wurden erst später eingeführt.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Beitrag von helpy »

Hallo Anxifer,

Einige Anmerkungen:


1. In Verbindung mit anderen Events (wie z.B. NetworkServerEvent()) unbedingt einen Timout in WaitWindowEvent() verwenden, ansonsten werden evt. anstehende Network-Events erst abgearbeitet, wenn ein Window-Event auftritt!


2. Das Delay(50) ist nicht nötig, wenn WaitWindowEvent() verwendet wird! Wird stattdessen WindowEvent() verwendet, dann ist es sinnvoll Delay() einzusetzen! Das mit den Event-Schleifen löst jeder anders.

Hier ein Vorschlag:

Code: Alles auswählen

  Repeat
    event = WindowEvent()
    
    ; ...
    
    SEvent = NetworkServerEvent()
 
    If SEvent
    
      ; ...
      
    EndIf

    If Not ( event Or SEvent )
      Delay(100)
    EndIf

  Until Quit = #True
Damit wird das Delay(50) nur asgeführt, wenn keine Window- oder Network-Events anliegen. ... und damit werden anstehende Events schneller ausgeführt, anstatt zwischendrin immer ein Delay abzuwarten.


3. Den Client bereits bei Verbindung (connect) in die Liste eintragen und nicht erst beim Daten-Empfang:

Code: Alles auswählen

      Select SEvent
     
        Case #PB_NetworkEvent_Connect
          ; Client in Liste eintragen!

        Case #PB_NetworkEvent_Data
          ; Daten empfangen und verarbeiten
 
        Case #PB_NetworkEvent_File
          ; Datei empfangen und verarbeiten

        Case #PB_NetworkEvent_Disconn
          ; Client aus Liste austragen!
         
      EndSelect

4. Um später wieder herauszufinden welches GadgetItem zu welcher ClientID gehört, musst Du dies selbst verwalten. Da gibt es viele Möglichkeiten! Hier nur mal eine Lösung:
  • Einen neuen Client (#PB_NetworkEvent_Connect) mit AddGadgetItem() ans ENDE der Liste eintragen. Mit LastItem="CountGadgetItems()-1" und SetGadgetItemData(#Gadget, LastItem, ClientID) speicherst Du die ClientID im GadgetItem.
  • Willst Du einkommende Nachrichten als Text im GadgetItem anzeigen kannst Du Dir mit einer Schleife von 0 bis "CountGadgetItems()-1" und dem Vergleich mit GetGadgetItemData() heraussuchen, an welcher Position das GadgetItem für diesen Client liegt. ... und dann dort den Text eintragen.
  • Meldet sich ein Client ab, kannst Du mit der oben genannten Schleife das entsprechende GadgetItem heraussuchen und löschen.

Damit solltest Du genügend Infos haben, um Dein Ziel zu erreichen.

cu, guido
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Anxifer
Beiträge: 5
Registriert: 16.06.2009 22:59

Beitrag von Anxifer »

@helpy,

Also deine Erklärung hört sich ja ganz gut an, nur irgendwie versteh ich nicht ganz, wie du das mit CountGadgetItems() und SetGadgetItemData(#Gadget, LastItem, ClientID) meinst. Könntest du mir das vieleicht an einem Beispiel erklären?
Benutzeravatar
jojo1541
Beiträge: 431
Registriert: 15.09.2007 17:12
Wohnort: Irgendwo im Nirgendwo

Beitrag von jojo1541 »

er meint, dass du eine schleife machst, in der du alle Items deiner Liste auf die Clientid des clients, der die Daten gesendet hat, abgleichst.

Sähe dann so aus:

Code: Alles auswählen

For x = 0 To CountGadgetItems(#DeinLsitGadget) - 1 ; wir durchsuchen alle Items in der Liste
  If GetGadgetData(#DeinListGadget) = clientid  ; Clientid ist der EventClient(), der die Daten gesendet hat
    SetGadgetItemText(#DeinAusgabeGadget,x,"Deine empfangenen Daten") ; in dein Ausgabegadget die Daten schreiben
  EndIf
Next
Ich verkaufe Rechtschreibfehler und jede menge GROßBUCHSTABEN. Alles unbegrenzt zu haben.
Antworten