ConnectionID() bei Ungültiger Connection

Hier werden, insbesondere in den Beta-Phasen, Bugmeldungen gepostet. Das offizielle BugForum ist allerdings hier.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

ConnectionID() bei Ungültiger Connection

Beitrag von cxAlex »

Code: Alles auswählen

InitNetwork()
Con = OpenNetworkConnection("www.google.de", 80)
Debug ConnectionID(Con)
CloseNetworkConnection(Con)
Debug ConnectionID(Con)
Syntax

Ergebnis = ConnectionID(Verbindung)
Beschreibung

Gibt den eindeutigen System-Identifier (Bezeichner) der 'Verbindung' zurück.

Dieses Ergebnis ist manchmal auch als 'Handle' bekannt. Schauen Sie in das Extra-Kapitel Handles und Nummern für weitere Informationen.
Das 2. Connection-ID gibt irgend einen Schwachsinn zurück, nur keine Gültiges Handle. Schon klar, da die Verbindung ja beendet worden ist, aber es wäre besser #Null oder sonst einen definierten Wert zurückzugeben, sonst ist es unmöglich zu prüfen ob das Handle gültig ist. Und ja, es kann durchaus dazu kommen das ConnectionID() auf eine selbst geschlossene Connection zugreift (Threads). Da helfen auch keine Flags ... . Da die Verbindungen wie alles in PB mit dem ObjectManager verwaltet werden sollte das kein Problem sein.

Gruß, Alex
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: ConnectionID() bei Ungültiger Connection

Beitrag von PMV »

Wenn du weist, das eine ID nicht mehr gültig sein kann, dann solltest
du diese selber "löschen", wenn du nicht anders ermitteln kannst das
diese ID bereits ungültig ist. :wink:

Code: Alles auswählen

InitNetwork()
Con = OpenNetworkConnection("www.google.de", 80)
If Con : Debug ConnectionID(Con) : EndIf
CloseNetworkConnection(Con)
Con = #Null
If Con : Debug ConnectionID(Con) : EndIf
MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Re: ConnectionID() bei Ungültiger Connection

Beitrag von cxAlex »

Das Problem ist das Mehrere Threads die ID haben und ich ihnen nicht sofort signalisieren kann das die ID ungültig ist.

Gruß, Alex
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: ConnectionID() bei Ungültiger Connection

Beitrag von TomS »

Das zweite ConnectionID() gibt immer den gleichen Wert aus. Und zwar: 95630136

Edit: Ok anscheinend doch nicht. Jedesmal wenn ich auf F5 drücke kommt das gleiche raus. Allerdings kommt jetzt was anderes raus, als vor 2 Minuten :freak:
Edit 2: WTF. Das ändert sich, je nachdem in welcher Zeile es steht.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Re: ConnectionID() bei Ungültiger Connection

Beitrag von cxAlex »

172417905328172
23356753575979
4582
74934999056426
...

Ich bekomm immer anderen Blödsinn angezeigt, aber eben nichts mit dem ich erkennen könnte ob das Handle ungültig ist ...
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Re: ConnectionID() bei Ungültiger Connection

Beitrag von cxAlex »

Ich hab mir jetzt einen Work-Around gebastelt, nun gibt ConnectionID() 0 zurück wenn das Handle geschlossen wurde, und das genze ist Thread-safe:

Code: Alles auswählen

; EnableExplicit

Structure __ConnectionIDCollector_Data
  Map Connections.i()
  Mutex.i
EndStructure

Global __ConnectionIDCollector.__ConnectionIDCollector_Data

Procedure __ConnectionIDCollector_Init()
  Shared __ConnectionIDCollector
  __ConnectionIDCollector\Mutex = CreateMutex()
EndProcedure : __ConnectionIDCollector_Init()

Procedure __EventClient()
  Protected EventClient
  Shared __ConnectionIDCollector
  
  With __ConnectionIDCollector
    EventClient = EventClient()
    LockMutex(\Mutex)
    \Connections(Str(EventClient)) = #True
    UnlockMutex(\Mutex)
  EndWith
  
  ProcedureReturn EventClient
EndProcedure

Procedure __NetworkServerEvent()
  Protected Event
  Shared __ConnectionIDCollector
  
  With __ConnectionIDCollector
    Event = NetworkServerEvent()
    If Event = #PB_NetworkEvent_Disconnect
      LockMutex(\Mutex)
      \Connections(Str(EventClient())) = #False
      UnlockMutex(\Mutex)
    EndIf
  EndWith
  
  ProcedureReturn Event
EndProcedure

Procedure __OpenNetworkConnection(Host$, Port, Type = #PB_Network_TCP)
  Protected Connection
  Shared __ConnectionIDCollector
  
  With __ConnectionIDCollector
    Connection = OpenNetworkConnection(Host$, Port, Type)
    LockMutex(\Mutex)
    \Connections(Str(Connection)) = #True
    UnlockMutex(\Mutex)
  EndWith
  
  ProcedureReturn Connection
EndProcedure

Procedure __CloseNetworkConnection(Connection)
  Protected isOk
  Shared __ConnectionIDCollector
  
  With __ConnectionIDCollector
    LockMutex(\Mutex)
    isOk = \Connections(Str(Connection))
    \Connections(Str(Connection)) = #False
    UnlockMutex(\Mutex)
    If isOk
      isOk = CloseNetworkConnection(Connection)  
    EndIf
  EndWith
  
  ProcedureReturn isOk
EndProcedure

Procedure __ConnectionID(Connection)
  Protected isOk
  Shared __ConnectionIDCollector
  
  With __ConnectionIDCollector
    LockMutex(\Mutex)
    isOk = \Connections(Str(Connection))
    UnlockMutex(\Mutex)
    If isOk
      isOk = ConnectionID(Connection)  
    EndIf
  EndWith
  
  ProcedureReturn isOk
EndProcedure

Procedure __SendNetworkData(Connection, *Mem, MemSize)
  Protected isOk
  Shared __ConnectionIDCollector
  
  With __ConnectionIDCollector
    LockMutex(\Mutex)
    isOk = \Connections(Str(Connection))
    UnlockMutex(\Mutex)
    If isOk
      isOk = SendNetworkData(Connection, *Mem, MemSize)
    EndIf
  EndWith
  
  ProcedureReturn isOk
EndProcedure

Procedure __ReceiveNetworkData(Connection, *Mem, MemSize)
  Protected isOk
  Shared __ConnectionIDCollector
  
  With __ConnectionIDCollector
    LockMutex(\Mutex)
    isOk = \Connections(Str(Connection))
    UnlockMutex(\Mutex)
    If isOk
      isOk = ReceiveNetworkData(Connection, *Mem, MemSize)
    EndIf
  EndWith
  
  ProcedureReturn isOk
EndProcedure

; PB - Befehle überschreiben

Macro EventClient()
  __EventClient()  
EndMacro

Macro NetworkServerEvent()
  __NetworkServerEvent()  
EndMacro

Macro OpenNetworkConnection(ServerName, Port, Type = #PB_Network_TCP)
  __OpenNetworkConnection(ServerName, Port, Type)  
EndMacro

Macro CloseNetworkConnection(Connection)
  __CloseNetworkConnection(Connection)  
EndMacro

Macro ConnectionID(Connection)
  __ConnectionID(Connection)  
EndMacro

Macro SendNetworkData(Connection, Mem, MemSize)
  __SendNetworkData(Connection, Mem, MemSize)  
EndMacro

Macro ReceiveNetworkData(Connection, Mem, MemSize)
  __ReceiveNetworkData(Connection, Mem, MemSize)
EndMacro
Gruß, Alex
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: ConnectionID() bei Ungültiger Connection

Beitrag von edel »

CloseNetworkConnection duerfte den Speicher, der bei OpenNetworkConnection alloziert wurde, wieder freigeben. Somit waere ein 2. ConnectionID(Con) fatal, und duerfte frueher
oder spaeter zu einem IMA fuehren. Con = #null duerfte es auch tun.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Re: ConnectionID() bei Ungültiger Connection

Beitrag von cxAlex »

Nicht in Threads!! Natürlich ist das Overkill bei einem einfachen, linearen Programm ... Aber bei Threads schaut die Sache anders aus.

Gruß, Alex
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: ConnectionID() bei Ungültiger Connection

Beitrag von PMV »

Man kanns natürlich auch kompliziert machen. :wink:
Wobei du erst den Mutex wieder frei geben darfst, nach dem du die ConnectionID auch tatsächlich verwendet hast. Du gibst den Mutex ja immer schon frei, bevor du ihn verwendest. Du schützt damit ja nur das überprüfen, nicht aber die tastächliche Nutzung.

Ein Aufruf von CloseNetworkConnection(#Null) führt bei mir tatsächlich zu einem IMA an Adresse 0. :)

Ich hät einfach die ConnectionID in eine Variable (Struktur, Speicher) geschrieben, der in alle Threads genutzt wird. Somit greifen alle Threads auf den selben Wert zu. Wird die ConnectionID nun geschlossen, wird der Wert auf #Null gesetzt. Der Wert wird vor dem Aufruf von CloseNetworkConnection() auf #Null gesetzt. Damit das ganze Threadsafe bleibt, brauchts dann noch Mutexschutz.

Code: Alles auswählen

Structure ThreadConnection
  ID.i
  Mutex.i
EndStructure

Procedure MyThread(*Connection.ThreadConnection)
  Repeat
    If *Connection\ID And TryLockMutex(*Connection\Mutex)
      ; Daten senden, empfangen, usw.
      UnlockMutex(*Connection\Mutex)
    EndIf
    ;...
  Until Not *Connection\ID

EndProcedure

Global Connection.ThreadConnection
Connection\ID = OpenNetworkConnection(...)
Connection\Mutex = CreateMutex()
Thread.i = CreateThread(@MyThread(), @Connection)
;...

; Verbindung beenden
tmpID = Connection\ID
LockMutex(Connection\Mutex)
Connection\ID = #Null
CloseNetworkConnection(tmpID)
UnlockMutex(Connection\Mutex)
; ---

WaitThread(Thread)
MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: ConnectionID() bei Ungültiger Connection

Beitrag von AND51 »

Das wäre doch mal wieder ein tolles Beispiel für ein natives isConnectionID(), oder? Warum wird sowas nicht mal implementiert? Ein weiterer für mich und viele hauptsächlicher Vorteil wäre, dass endlich auch Clients feststellen können, ob eine Verbindung beendet wurde. Serverseitig geht das ja schon, da gibt's ja immer ein entsprechendes Event. Clientseitig — bisher keine Chance.

Schlagt mich bitte nicht, wenn es das mittlerweile schon gibt. Hab zwar schon/noch 4.50 Beta 1 installiert und natürlich auch alle Changelogs gelesen, aber intensiv seit 4.30 nichts mehr gemacht.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Antworten