Seite 1 von 2
ConnectionID() bei Ungültiger Connection
Verfasst: 20.10.2010 12:39
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
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 20.10.2010 16:59
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.
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
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 20.10.2010 17:03
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
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 20.10.2010 17:11
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
Edit 2: WTF. Das ändert sich, je nachdem in welcher Zeile es steht.
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 20.10.2010 17:40
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 ...
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 20.10.2010 18:42
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
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 20.10.2010 21:24
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.
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 20.10.2010 21:32
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
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 21.10.2010 01:21
von PMV
Man kanns natürlich auch kompliziert machen.
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
Re: ConnectionID() bei Ungültiger Connection
Verfasst: 21.10.2010 16:30
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.