Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Callback im UDT
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
CommLan



Anmeldungsdatum: 23.10.2015
Beiträge: 40
Wohnort: hinterm Mond

BeitragVerfasst am: 17.02.2019, 15:34    Titel: Callback im UDT Antworten mit Zitat

Und wieder ein Hallo an die Community.

Dieses mal hab ich ein sehr unschönes Problem mitgebracht, wozu ich auch einen Beispielcode gebastelt habe.

Ich würde TSNE_V3.bi von ThePuppetMaster gerne in einen objektorienterten Ansatz pressen, so wie ich den gerade brauche. Das würde mir vieles erleichtern, wenn das irgendwie ginge, weils Codewust ohne Ende spart. Der Haken an der ganzen Geschichte sind die Callback - Routinen. Die versauen mir das dezent. neutral

Code:

'Die (symbolische) Sub (Eigentlich Funktion), die von TSNE her kommt
'und per INCLUDE reinkommt
DECLARE SUB TSNE_Create_Server(NewConnection AS ANY PTR)

'Klasse
TYPE ServerKlasse
   'Diese Variable darf nicht static sein. In meinem richtigen
   'Quellcode ist hier unter anderem ein variables UDT-Array
   'mit REDIM !
   DIM AS INTEGER IrgendeineVariable

   PRIVATE:
   'Meine Callback - Routine für TSNE
   DECLARE SUB TSNE_NewConnection()
   
   PUBLIC:
   'Meine Methode, die das ganze verpacken soll
   DECLARE FUNCTION CreateNewServer() AS INTEGER
END TYPE

'Routinen
FUNCTION ServerKlasse.CreateNewServer() AS INTEGER
   'ServerKlasse.CreateNewServer() lässt sich vollständig an
   'Bedürfnisse anpassen.

   'Hier wird der eigentliche TSNE - Server erstellt
   TSNE_Create_Server(@TSNE_NewConnection)

   RETURN(0)

END FUNCTION

SUB ServerKlasse.TSNE_NewConnection()
   'In dieser Sub lassen sich die Übergabewerte nur sehr
   'unpraktikabel ändern. Auch das würde ich vermeiden
   'wollen

   'Die Methode muss auf das Attribut zugreifen können !
   'Damit ist die Methode nicht als Static realisierbar.
   IrgendeineVariable = 10

   'Wer es zum laufen bekommt, kriegt diese Meldung.
   PRINT "Es funktioniert: ";STR(IrgendeineVariable);"."
END SUB

'MAIN
DIM AS ServerKlasse Server
Server.CreateNewServer()



'Subs
SUB TSNE_Create_Server(NewConnection AS ANY PTR)

   'Gehen wir mal davon aus, nach einem riesen
   'Codewust kommt eine Verbindung rein, NewConnection
   'wird aufgerufen
   'Achtung: Diese Funktion kommt eigentlich aus einer
   'externen lib und ist nicht wirklich veränderbar.

   DIM AS SUB() callback
   callback = NewConnection
   callback()

END SUB



Nun geht es um folgendes Problem:
Compiliert man das ganze Spielchen, kommt die Meldung:
error 208: Illegal non-static member access, SERVERKLASSE.TSNE_NEWCONNECTION in 'TSNE_Create_Server(@TSNE_NewConnection)'

Um das zu lösen, könnte man einfach ein STATIC bei TSNE_NewConnection() dazu basteln. Problem ist aber, dass TSNE_NewConnection dann nicht mehr auf die Variable zugreifen kann und dort wieder eine Fehlermeldung vom Compiler geschmissen wird. Pattsituation halt oder ich bin zu dumm - je nachdem...

Gibt es da irgendeine Lösung die mir mal wieder entgangen ist ?
(Außer es bleiben zu lassen und mich mit dem zufrieden zu geben, was ich kriegen kann durchgeknallt )

EDIT am 18.02.19 um 12:30 Uhr


Zuletzt bearbeitet von CommLan am 18.02.2019, 12:31, insgesamt 3-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 17.02.2019, 18:29    Titel: Antworten mit Zitat

Muss denn TSNE_Create_Server überhaupt @TSNE_NewConnection übergeben werden? Die Funktion kann doch sowieso auf TSNE_NewConnection direkt zugreifen. Ggf. etwas in dieser Art:

Code:
FUNCTION ServerKlasse.CreateNewServer() AS INTEGER
   TSNE_Create_Server
   RETURN(0)
END FUNCTION
SUB ServerKlasse.TSNE_Create_Server(NewConnection AS ANY PTR = 0)
   IF NewConnection = 0 THEN
     TSNE_NewConnection()
   ELSE
     DIM AS SUB() callback
     callback = NewConnection
     callback()
     ' wenn überhaupt über diesen Umweg
   END IF
END SUB

Ob es funktioniert oder auch nur sinnvoll ist, kann ich leider nicht beurteilen. happy
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
CommLan



Anmeldungsdatum: 23.10.2015
Beiträge: 40
Wohnort: hinterm Mond

BeitragVerfasst am: 17.02.2019, 18:51    Titel: Antworten mit Zitat

Kompetente Hilfe, sie naht vor Freude klatschen

Also die Sache ist die:
TSNE_Create_Server benötigt die Sub als Callback. Die Sub wird nämlich von TSNE dann aufgerufen, wenn überhaupt eine Verbindung erst reinschneit und nicht sobald der Server gestartet wird.
Der Server läuft nämlich in einem extra Thread, der gegebenenfalls die Callback - Routine erst aufruft.

Das Problem tritt übrigens an späterer Stelle (nämlich im Normalfall in TSNE_NewConnection) mit gleich 3 Callbacks nochmal auf bei TSNE_Create_Accept(). Hab ich aber der Übersicht halber hier mal rausgelassen - symbolisches Beispiel halt.

Mit dem jetzigen Vorschlag müsste ich zudem im Code von The Puppet Master mächtig herumschmieren, was ich nur ungern machen würde.

Ich hätte vielleicht dazu sagen sollen, dass alles, was TSNE_ vorne dran stehen hat, nicht veränderbar ist - aufgrund eben der Bibliothek.

Ich hab jetzt schon überlegt, einen Constructor anzulegen, der die Funktionen einfach als Pointer speichert und dann dem Callback übergibt. Die TSNE - Routinen fressen das tatsächlich (logischerweise), wenn man den Pointer als STATIC AS ANY PTR definiert.
Der Denkfehler daran, ich hab den Fehler damit nur in den Constructor verlegt, weil ich da ja jetzt wieder nen Pointer von einem angeblich "Nicht-Static-Member" erstellt kriegen muss.
Aber immerhin kann man schon mal was drum herum schreiben..

Edit: Okay, DIM AS ANY PTR ist mit momentaner "Ich compilier es nicht durch" - Lage auch funktionsfähig.
Edit2: Die Callback - Geschichte hab ich da nur reingebaut, weil die auch das eigentliche Problem ist. Wie gesagt, TSNE_ ist soweit nicht veränderbar ohne größeren Aufwand.
Edit3: Was es noch zu sagen gilt: Bei TSNE_NewConnection ist der Inhalt der Funktion veränderbar, aber nicht die Deklaration.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4594
Wohnort: ~/

BeitragVerfasst am: 17.02.2019, 22:15    Titel: Antworten mit Zitat

Zitat:
Kompetente Hilfe, sie naht vor Freude klatschen

Freu dich mal nicht zu früh - so kompetent bin ich in diesem Bereich wirklich nicht. grinsen

Was ich nicht so recht verstehe: Wenn du die Funktionen TSNE_ nicht ändern willst, ist das durchaus verständlich. Hier handelt es sich aber doch um die Funktionen deiner Serverklasse. Oder willst du innerhalb deiner Funktionen gar nicht auf die Serverklassen-Funktionen zugreifen, sondern auf die externen, von TSNE bereitgestellten? In
Code:
FUNCTION ServerKlasse.CreateNewServer() AS INTEGER
   TSNE_Create_Server(@TSNE_NewConnection)
   RETURN(0)
END FUNCTION

werden die Member-Mitglieder aufgerufen, nicht die gleichnamigen Funktionen außerhalb der Klasse.
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
CommLan



Anmeldungsdatum: 23.10.2015
Beiträge: 40
Wohnort: hinterm Mond

BeitragVerfasst am: 18.02.2019, 11:06    Titel: Antworten mit Zitat

Also, was ich erreichen will, ist mir den TSNE - Wust in eine eigene Klasse auszulagern, um mehr Überblick zu haben. So habe ich dann z.B. nur den Befehl Server starten, bekomm Daten in ein Array und gut ist und nicht hundert Aufrufe hier, tausend mal Funktion erstellen da, sondern alles auf einem Fleck und einfach händelbar, weil direkt als massenware erstellbar.

Die Sache ist, dass ich das eigene Member aufrufe stimmt. Aber die Sache ist, dass TSNE_NewConnection halt auch in der Klasse deklariert ist damit ein Member ist. Nur TSNE_Create_Server (Und später TSNE_Create_Accept), welche direkt von TSNE kommt, ist von außerhalb - dafür aber global verfügbar.

Ich verstehe irgendwie diese ganze Problematik nicht ganz. Was ist an der Callback - Routine nicht static ? Weil ich die Funktionen überschreiben könnte ? Das wäre doch dann aber mein eigenes Problem und geht den Compiler dann doch garnichts an, oder sehe ich das falsch ? Irgendwie leuchtet mir das alles logisch gesehen nicht sehr ein..

@nemored - Ich hab noch nen Fehler in meinem Beispiel gefunden. Das mit dem Global konntest du nicht wissen - weils nicht global was... Hab das Beispiel oben mittlerweile direkt (Ich hoffe fehlerfrei) angepasst.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 18.02.2019, 12:46    Titel: Antworten mit Zitat

Ja, dieses Pointerzeugs kann einen in den Wahnsinn treiben! durchgeknallt

Mit ein paar kleinen Änderungen funktioniert's aber:

Code:
'Klasse
Type ServerKlasse
   Static As Integer IrgendeineVariable '<<<<<<<<<<<<<<<<
   Dim As Integer dummy 'jeder type muss mindestens eine nicht-statische variable enthalten <<<<<<<<<<<<<<<<<<<

   Private:
   'Die (symbolische) Sub (Eigentlich Funktion), die von TSNE her kommt
   Declare Sub TSNE_Create_Server(NewConnection As Any Ptr)
   'Meine Callback - Routine für TSNE
   Declare Static Sub TSNE_NewConnection() '<<<<<<<<<<<<<<<<<<
   
   Public:
   'Meine Funktion, die das ganze verpacken soll
   Declare Function CreateNewServer() As Integer
End Type

Dim As Integer ServerKlasse.IrgendeineVariable '<<<<<<<<<<<<<<<<<<<<<<

'Routinen
Function ServerKlasse.CreateNewServer() As Integer

   'Hier wird der eigentliche TSNE - Server erstellt
   TSNE_Create_Server(@TSNE_NewConnection)

   Return(0)

End Function
Sub ServerKlasse.TSNE_Create_Server(NewConnection As Any Ptr)

   'Gehen wir mal davon aus, nach einem riesen
   'Codewust kommt eine Verbindung rein, NewConnection
   'wird aufgerufen
   Dim As Sub() callback
   callback = NewConnection
   callback()

End Sub
Sub ServerKlasse.TSNE_NewConnection()
   'Wer es zum laufen bekommt, kriegt diese Meldung.
   IrgendeineVariable = 10
   Print "Es funktioniert: ";Str(IrgendeineVariable);"."
End Sub

'MAIN
Dim As ServerKlasse Server
Server.CreateNewServer()
Sleep


"STATIC" heißt soviel wie "Global zum Type", d.h., der Wert einer statischen Variable gilt für alle Instanzen eines Types. Darum können statische Prozeduren nur auf statische Member und nicht-statische Prozeduren nur auf nicht-statische Member zugreifen. Natürlich gibt es Workarounds, aber das ist eine andere Geschichte.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!


Zuletzt bearbeitet von grindstone am 18.02.2019, 13:39, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
CommLan



Anmeldungsdatum: 23.10.2015
Beiträge: 40
Wohnort: hinterm Mond

BeitragVerfasst am: 18.02.2019, 13:31    Titel: Antworten mit Zitat

Hallo grindstone,
ich musste leider mein Beispiel abändern, vielleicht hast du's im Nachhinein bemerkt. Zum einen war der Fehler, dass die Funktion TSNE_Create_Server an der falschen Stelle stand - das andere war, dass die Variable unbedingt so bleiben muss, da es in Wirklichkeit REDIM ist - was mit STATIC schlecht geht.

Zudem hab ich das Problem, dass ich mehrere Instanzen von Serverklasse starte - die unabhängig laufen sollen voneinander. Synchronisationen soll es über extra Methoden geben (Wobei die STATIC - Geschichte mich auf eine andere, neue Funktion gebracht hat, welche ich einbauen werde).

Von daher muss ich leider sagen, dass das für mich nicht praktikabel ist. Tut mir leid, dass das jetzt so lief, weil du ja Zeit verloren hast dadurch..
Falls dir die Lust daran noch nicht vergangen ist - das neue Beispiel ist jetzt besser kommentiert und der Quellcode von Fehlern befreit.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 18.02.2019, 14:04    Titel: Antworten mit Zitat

Wieso "Lust vergangen"? Jetzt wird es doch erst interessant. grinsen

Zitat:
...dass die Variable unbedingt so bleiben muss, da es in Wirklichkeit REDIM ist - was mit STATIC schlecht geht.
Im Gegenteil, das geht sogar sehr gut. Damit könnte sogar der Type ein Array von sich selbst enthalten.
Code:
...
'Klasse
TYPE ServerKlasse
   'Diese Variable darf nicht static sein. In meinem richtigen
   'Quellcode ist hier unter anderem ein variables UDT-Array
   'mit REDIM !
   STATIC AS INTEGER IrgendeineVariable() '<<<<<<<<<<<<

   PRIVATE:
   'Meine Callback - Routine für TSNE
   DECLARE SUB TSNE_NewConnection()
   
   PUBLIC:
   'Meine Methode, die das ganze verpacken soll
   DECLARE FUNCTION CreateNewServer() AS INTEGER
END TYPE

REDIM AS INTEGER ServerKlasse.IrgendeineVariable(0) '<<<<<<<<<<
...


Ich werde mir deinen neuen Quellcode heute Abend einmal genauer ansehen.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!


Zuletzt bearbeitet von grindstone am 18.02.2019, 21:20, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
CommLan



Anmeldungsdatum: 23.10.2015
Beiträge: 40
Wohnort: hinterm Mond

BeitragVerfasst am: 18.02.2019, 21:13    Titel: Antworten mit Zitat

So, ich hab ein bisschen weiter gekokelt über meinem Problem, jetzt gibts wieder ein neues. Frage ist, dadurch, dass ich es nie in action erlebt habe, ob es überhaupt geht oder es sich gleich mit einem segmentation fault in die unendlichen Weiten des Rams verabschiedet...

Code:
'Die (symbolische) Sub (Eigentlich Funktion), die von TSNE her kommt
'und per INCLUDE reinkommt
DECLARE SUB TSNE_Create_Server(NewConnection AS ANY PTR)

'Klasse
TYPE ServerKlasse
   'Diese Variable darf nicht static sein. In meinem richtigen
   'Quellcode ist hier unter anderem ein variables UDT-Array
   'mit REDIM !
   DIM AS INTEGER IrgendeineVariable

   PRIVATE:
   
   PUBLIC:
   'Pointer für die Funktion TSNE_NewConnection()
   DIM AS ANY PTR TSNE_NewConnectionPTR
   
   'Meine Callback - Routine für TSNE
   DECLARE SUB TSNE_NewConnection()
   
   
   'Meine Methode, die das ganze verpacken soll
   DECLARE FUNCTION CreateNewServer() AS INTEGER
END TYPE

SUB Create_ServerKlasse(Server AS ServerKlasse)

   'Hier hakelts jetzt, weil ich nicht weiß, wie ich mir den Methoden -
   'Pointer holen könnte... Weil das hier ist laut Compiler wieder
   'ein Syntax Error. Das Teil treibt mich noch in den Wahnsinn...
   Server.TSNE_NewConnectionPTR = @Server.TSNE_NewConnection
END SUB

'Routinen
FUNCTION ServerKlasse.CreateNewServer() AS INTEGER
   'ServerKlasse.CreateNewServer() lässt sich vollständig an
   'Bedürfnisse anpassen.

   'Hier wird der eigentliche TSNE - Server erstellt
   TSNE_Create_Server(@TSNE_NewConnectionPTR)

   RETURN(0)

END FUNCTION

SUB ServerKlasse.TSNE_NewConnection()
   'In dieser Sub lassen sich die Übergabewerte nur sehr
   'unpraktikabel ändern. Auch das würde ich vermeiden
   'wollen

   'Die Methode muss auf das Attribut zugreifen können !
   'Damit ist die Methode nicht als Static realisierbar.
   IrgendeineVariable = 10

   'Wer es zum laufen bekommt, kriegt diese Meldung.
   PRINT "Es funktioniert: ";STR(IrgendeineVariable);"."
END SUB

'MAIN
DIM AS ServerKlasse Server
'Der neue Aufruf, der erstmal die Pointer auf definierte Werte bringen soll.
Create_ServerKlasse(Server)
Server.CreateNewServer()



'Subs
SUB TSNE_Create_Server(NewConnection AS ANY PTR)

   'Gehen wir mal davon aus, nach einem riesen
   'Codewust kommt eine Verbindung rein, NewConnection
   'wird aufgerufen
   'Achtung: Diese Funktion kommt eigentlich aus einer
   'externen lib und ist nicht wirklich veränderbar.

   DIM AS SUB() callback
   callback = NewConnection
   callback()

END SUB


Jetzt besteht nur das Problem, dass ich irgendwie den Pointer zu Server.TSNE_NewConnection() von außerhalb der Klasse irgendwie kriegen muss. Dann wäre das Problem erstmal (Mit Augenkrebs) theoretisch umgangen. Schön ists nicht, aber es würde funktionieren...

@grindstone
Also irgendwie verstehe ich das Klassenfremde REDIM nicht ganz. Aber was problematisch ist, ist, dass alle Instanzen nach wie vor auf ein und dasselbe Array zugreifen. Und wenn man jetzt bedenkt, dass dieses Array z.B. die Verbindungen des aktuellen Servers enthalten soll, ich aber 3 Server starte, wird das etwas unpraktisch - wenn ich das jetzt so richtig verstehe.
Lösungsansatz wäre natürlich, dass ich jetzt in dem UDT vermerke, von welchem Server welches Datenpaket in dem UDT stammt, aber das bremst auch wieder die Server, weil sich dann 3 Server ums Mutex streiten werden... Und das ist das nächste Manko - die Server müssen schnell sein können. Die bekommen im jetzigen Anwendungsfall, wo das vorkommt, eine ganze Menge Anfragen auf einmal.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 19.02.2019, 00:54    Titel: Antworten mit Zitat

Zitat:
Also irgendwie verstehe ich das Klassenfremde REDIM nicht ganz.
Vielleicht kann man das besser an einem Beispiel erklären. Schau dir in diesem Quellcode einmal den Type "tPlane" an (etwa bei 1/5 des Quellcodes). In der Typendeklaration ist ein Array
Code:
Static As tPlane plane() 'planes array
deklariert, und nach der Typendeklaration noch einmal
Code:
ReDim As tPlane tPlane.plane(0)
Damit wird ein Array von Objekten "Flugzeug" erstellt, auf das sowohl von innerhalb des Types (bzw. dessen Prozeduren) als auch von außerhalb vom restlichen Programm zugegriffen werden kann. Die meisten Member von "tPlane" sind nicht-statisch, d.h. sie gelten individuell für die jeweilige Instanz des Types (Flughöhe, Geschwindigkeit etc.). Die Tag - Offsets (= Abstand vom Mittelpunkt des Flugzeug - Icons, im Tag werden Flugziel, Höhe und Geschwindigkeit angezeigt) dagegen sind statisch und somit für alle Flugzeuge gleich.

Ein weiterer Vorteil des statischen Arrays ist es, daß auch auch innerhalb von statischen Prozeduren auf nicht-statische Member des Types zugegriffen werden kann, wenn dessen Index bekannt ist. Beispielsweise könnte ich bei dem o.g. Beispielcode in der statischen Function "tPlane.create" auf den nicht-statischen Wert "plane(2).altitude" zugreifen.

Zurück zu TSNE. Ich habe vor einiger Zeit mal ein Server/Client - Paar zur Fileübertragung zwischen zwei Rechnern programmiert. Das habe ich mir gerade angesehen und festgestellt, daß ich mich in die Thematik erst wieder einarbeiten muß. grinsen

Schaun mer mal!

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
CommLan



Anmeldungsdatum: 23.10.2015
Beiträge: 40
Wohnort: hinterm Mond

BeitragVerfasst am: 19.02.2019, 16:17    Titel: Antworten mit Zitat

So, ich gebs jetzt auf. Es hat keinen Sinn. Das Programm wird immer größer und unübersichtlicher und mit jedem Schritt, den man umgangen hat, fällt dem Compiler was neues ein.
Jetzt war ich schon an dem Punkt, alles STATIC zu machen, ein statisches UDT-Array mit den eigentlichen Variablen der Serverklasse anzulegen, und den Kram über den Instanzpointer auseinander zu halten. Über den hätte ich mir den Index für das statische UDT-Array (welches mit jeder neuen Instanz PRESERVE um einen Record erweitert wird) holen können und hätte damit die passenden Variablen zur Instanz gehabt..
Aber der Compiler lacht sich dabei ins Fäustchen und führt einfach immer wieder den Constructor aus, wenn ich mit @ServerKlasse einer Pointer - Variable versuche, einen Instanzpointer zu geben.

Ich verstehe nicht, wie es sein kann, dass über meine Objekt während der Laufzeit im Objekt nichts bekannt ist. Weil logisch gesehen - Wenn der Befehl im Objekt ausgeführt wird, existiert das Objekt und dann müssen da auch Pointer sein. Stattdessen wird aber der Constructor aufgerufen, weil da eben keiner ist. Das passiert übrigens auch mit VARPTR() ...

Dann werd ich mal wundervolle 2000 Zeilen in meine Klasse integrieren und anpassen, weils ja scheinbar nicht anders möglich ist...
Wen der Ansatz (Der dank @ServerKlasse nicht funktioniert und eine Endlosschleife mit Segmentation Fault auslöst) interessiert:

Code:
'Die (symbolische) Sub (Eigentlich Funktion), die von TSNE her kommt
'und per INCLUDE reinkommt
DECLARE SUB TSNE_Create_Server(NewConnection AS ANY PTR)

'UDT für Informationen über die Serverinstanz
TYPE TYP_ServerPointer
   DIM AS ANY PTR RuntimePointer
   DIM AS INTEGER InstanceNumber
END TYPE

'Klasse
TYPE ServerKlasse
   PRIVATE:
   DIM AS INTEGER DUMMY
   
   'Instanzinformationen
   STATIC AS TYP_ServerPointer ServerPointer()
   STATIC AS INTEGER RunningInstances()
   
   'Meine Callback - Routine für TSNE
   DECLARE STATIC SUB TSNE_NewConnection()
   
   PUBLIC:
   'Constructor
   DECLARE CONSTRUCTOR()
   
   'Meine Methode, die das ganze verpacken soll
   DECLARE FUNCTION CreateNewServer() AS INTEGER
END TYPE

'Variablen neu initialisieren
REDIM AS TYP_ServerPointer ServerKlasse.ServerPointer(0)
REDIM AS INTEGER ServerKlasse.RunningInstances(0)

'Methoden
CONSTRUCTOR ServerKlasse()
   Print "Erweitere Array"

   'Neuen Serverpointer eintragen
   RunningInstances(0) += 1
   REDIM PRESERVE AS TYP_ServerPointer ServerPointer(0 TO RunningInstances(0))
   
   Print "Setze Informationen"
   
   'Instanzinformationen setzen
   ServerPointer(RunningInstances(0)).RuntimePointer = @ServerKlasse
   ServerPointer(RunningInstances(0)).InstanceNumber = RunningInstances(0)
   
   PRINT "Erfolgreich"
END CONSTRUCTOR
FUNCTION ServerKlasse.CreateNewServer() AS INTEGER
   'ServerKlasse.CreateNewServer() lässt sich vollständig an
   'Bedürfnisse anpassen.

   'Hier wird der eigentliche TSNE - Server erstellt
   TSNE_Create_Server(@TSNE_NewConnection)

   RETURN(0)

END FUNCTION
SUB ServerKlasse.TSNE_NewConnection()

   DIM AS INTEGER InstanceNumber = 0
   
   'Instanznummer anhand des Instanzpointers suchen
   PRINT "Suche Instanznummer"
   FOR I AS INTEGER = 0 TO UBOUND(ServerPointer)
      IF ServerPointer(I).RuntimePointer = @ServerKlasse THEN
         InstanceNumber = ServerPointer(I).InstanceNumber
      END IF
   NEXT

   'Gefundene Instanznummer ausgeben
   PRINT "I am ";STR(InstanceNumber)
END SUB

'MAIN
DIM AS ServerKlasse Server1
DIM AS ServerKlasse Server2
Server1.CreateNewServer()
Server2.CreateNewServer()

'Subs
SUB TSNE_Create_Server(NewConnection AS ANY PTR)

   'Gehen wir mal davon aus, nach einem riesen
   'Codewust kommt eine Verbindung rein, NewConnection
   'wird aufgerufen
   'Achtung: Diese Funktion kommt eigentlich aus einer
   'externen lib und ist nicht wirklich veränderbar.

   DIM AS SUB() callback
   callback = NewConnection
   callback()

END SUB


Vielleicht hat ja irgendjemand eine Idee, wie ich an den Pointer der aktuell laufenden Instanz komme. Weil dann wäre, wenn man eventuelle Denkfehler noch korrigiert, das ganze akzeptabel lauffähig...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 20.02.2019, 12:41    Titel: Antworten mit Zitat

"Denkfehler" (im Plural) ist das richtige Stichwort. lächeln

Zum einen ist "ServerKlasse" keine Instanz, sondern nur der Bauplan für eine Instanz, also ein Gedankenkonstrukt, das logischerweise auch keinen Pointer hat. Der Grund dafür, daß während der Laufzeit im Objekt nichts über das Objekt bekannt ist, ist also der, daß überhaupt kein Objekt existiert.

Warum -zweitens- der Compiler versucht, bei "@ServerKlasse" eine Instanz zu erstellen, statt eine Fehlermeldung auszugeben, entzieht sich meiner Kenntnis, aber wenn dieser Aufruf im Constructor und somit rekursiv erfolgt, muß das zwangsläufig zu einem Speicherüberlauf führen.

Drittens: Type - interne Prozeduren, die als Callback - Routinen verwendet werden sollen, müssen Static sein, um sie von außen -in diesem Fall für die TSNE - Bibliothek- verfügbar zu machen. Daß die Pointer auf nicht - statische Prozeduren außerhalb des Types nicht verfügbar sind, ist Absicht, denn schliesslich ist es der Sinn der Kapselung, das Innere des Types vom Rest des Programms abzuschirmen.

Kommen wir nun zum konstruktiven Teil.

Es gibt eine sehr viel elegantere Methode, den Index der aktuellen Instanz zu ermitteln, als von außen mitzuzählen (ACHTUNG: Dies funktioniert nicht im Constructor, da sich die Instanz während der Konstruktion an einer anderen Stelle im Speicher befindet und erst danach an das Array angehängt wird).
Code:
'Die (symbolische) Sub (Eigentlich Funktion), die von TSNE her kommt
'und per INCLUDE reinkommt
Declare Sub TSNE_Create_Server(NewConnection As Any Ptr)


'Klasse
Type ServerKlasse
   Private:
   Dim As Integer DUMMY

   'Meine Callback - Routine für TSNE
   Declare Static Sub TSNE_NewConnection()

   Public:
   Static As ServerKlasse server()
   'Meine Methode, die das ganze verpacken soll
   Declare Function CreateNewServer() As Integer

End Type

'Statische Variablen initialisieren
ReDim As ServerKlasse ServerKlasse.server(0)


Function ServerKlasse.CreateNewServer() As Integer
   'ServerKlasse.CreateNewServer() lässt sich vollständig an
   'Bedürfnisse anpassen.

   Dim As Integer InstanceNumber = 0

   'Instanznummer berechnen
   Print "Suche Instanznummer"
   InstanceNumber = (Cast(UInteger,@This) - Cast(UInteger,@ServerKlasse.server(0))) / SizeOf(ServerKlasse)
   '                                |                      |____Pointer auf den Beginn des Arrays
   '                                |___________________________Pointer auf die aktuelle Instanz
   'Gefundene Instanznummer ausgeben
   Print "I am ";Str(InstanceNumber)


   'Hier wird der eigentliche TSNE - Server erstellt
   TSNE_Create_Server(@TSNE_NewConnection)

   Return(0)

End Function
Sub ServerKlasse.TSNE_NewConnection()

End Sub

'MAIN
ReDim Preserve ServerKlasse.Server(2)

ServerKlasse.Server(1).CreateNewServer()
ServerKlasse.Server(2).CreateNewServer()
Sleep

'Subs
Sub TSNE_Create_Server(NewConnection As Any Ptr)

   'Gehen wir mal davon aus, nach einem riesen
   'Codewust kommt eine Verbindung rein, NewConnection
   'wird aufgerufen
   'Achtung: Diese Funktion kommt eigentlich aus einer
   'externen lib und ist nicht wirklich veränderbar.

   Dim As Sub() callback
   callback = NewConnection
   callback()

End Sub


Falls es dich interessiert: Hier ist der Thread mit dem erwähnten Server / Client - Paar:
https://www.freebasic.net/forum/viewtopic.php?f=3&t=27023&hilit=TSNE&start=120#p253590

Außerdem habe ich mal probeweise den Server aus dem Tutorial von ThePuppetMaster (erfolgreich) in einen Type gepackt. Ist noch stark verbesserungsfähig, aber im Prinzip läuft es.
http://users.freebasic-portal.de/grindstone/Codes/TSNE/test_server2type.bas

Was mich zu der Frage bringt, was du eigentlich vorhast? Ein Server kann gleichzeitig mehrere Clients bedienen, da brauchst du nur einen Server. Allerdings arbeitet jeder Server nur auf einem Port, du mußt also für jeden Port einen Server starten.

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 27.02.2019, 02:09    Titel: Antworten mit Zitat

@CommLan ... wenn ich fragen darf: Was planst du denn zu basteln, .. um das eine Klasse hilfreicher wäre?


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MOD
Fleißiger Referenzredakteur


Anmeldungsdatum: 10.09.2007
Beiträge: 1003

BeitragVerfasst am: 27.02.2019, 10:41    Titel: Antworten mit Zitat

Etwas ähnliches habe ich vor Jahren auch schon gemacht - vielleicht hilft es ja:
Server
Cleint
(Beide Codes unterscheiden sich im Grunde nur unten durch die Initialisierung, die Basisklasse darüber ist gleich.)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1208
Wohnort: Ruhrpott

BeitragVerfasst am: 28.02.2019, 05:26    Titel: Antworten mit Zitat

Und dann lässt du mich hier tagelang rumprogrammieren? grinsen

Aber da wir gerade beim Thema sind: TSNE für https wäre schön! zwinkern

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 28.02.2019, 14:15    Titel: Antworten mit Zitat

[OT]@grindstone ... war mal angedacht und auch in Entwicklung, is aber leider nicht so easy, wie ich das gerne hätte[/ot]


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
CommLan



Anmeldungsdatum: 23.10.2015
Beiträge: 40
Wohnort: hinterm Mond

BeitragVerfasst am: 08.03.2019, 00:23    Titel: Antworten mit Zitat

Soo, jetzt mal von mir eine Antwort, damit ihr alle mal etwas bescheid wisst, was so los ist und auch ein Lebenszeichen im Thread ist.
(Nachtrag: Ich sehe gerade, ich sollte Roman - Autor werden. Sieht ohne Vorschau echt nach viel weniger aus.)

Stand der Dinge ist, das Projekt lebt und gedeiht. Ich geh dabei zwar eher ein, weils stellenweise einfach Brainfuck wird, aber ich krieg das noch irgendwie gebacken. Momentan hab ich auch noch ein interessantes Speicherleck, dass ich nicht ganz zuordnen kann, welches vom System gemeldet wird. Da hab ich irgendwo nicht ganz so brav aufgeräumt, wie ich sollte. Oder ich hab nen Zugriff, der irgendwo hingeht, nur nicht dahin, wo er soll.. Lustig ist auch, mal ist von ungültigen Pointern die Rede, dann ist die Main wieder größer als sie sein soll laut Speicherverwaltung - ganz komisch. Muss ich noch herausfinden. Komisch ist nur, dass meine Verwaltung einwandfrei scheint. Ich bete einfach mal, dass der Fehler trotzdem bei mir liegt. Weil sonst hab ich ein mächtiges Problem... Aber es wäre ja nicht das erste mal, dass ich mich irre...
Bis ich die Lib aber so weit habe, dass es präsentierbar wäre, dauert es noch ein bisschen. Bin mir stellenweise uneinig, ob ich das alles wirklich so haben will, wie ich es jetzt gerade habe - oder ob ich es noch weiter herunterbreche.
Momentan ist es z.B. so, dass ich eine Refresh - Routine habe, die in die Hauptschleife muss. Bin noch am überlegen, ob ich das irgendwie doch noch in einen Thread gepresst kriege oder ich ganz drauf verzichten kann. Beim Thread ist nur mal wieder das Problem mit meinen heißgeliebten Callbacks und dem STATIC, was da uneingeladen mit reinplatzt...

@grindstone:
Also erstmal krasse Lösung, den Index zu kriegen. Was muss man nehmen, um darauf zu kommen ? Will ich auch können durchgeknallt

Was das mit @ServerKlasse angeht - okay - macht ja auch Sinn, dass ich den Pointer zur Klasse bekomme - steht ja da schließlich. Aber ich hab ein wenig um die Ecke gedacht und hab die sinnvollere Lösung als sinnvoll erachtet: Warum bekomme ich einen Pointer zur Klasse ? Was will man damit ? Mir selber eine Klasse bauen ? Wozu hab ich dann noch FB... Die Sache ist, klar, ich referenziere auf den "Bauplan", aber zur Laufzeit stimmt das doch eigentlich garnicht mehr. Weil die Sache daran ist ja, dass das ja alles so stehen bleibt, nur Leben eingehaucht bekommt und dann ins Leben kopiert wird. Und dieses "Leben" würde sich ja auch als Pointer auf das Objekt äußern, statt auf die weiterhin virtuell vegetierende Klasse. Somit würde letztlich @ServerKlasse zu einem Pointer aufs Objekt übersetzt werden müssen... - laut meiner Logik. Damit müsste man auch nicht über THIS gehen. Der Befehl würde dadurch optional sein - so wie ich es auch mal kennen gelernt habe: THIS ist laut meinem Wissensstand eine Option, um den Quelltext besser lesbar und in uneindeutigen Fällen eindeutig zu machen.
Was ich dabei noch einsehen würde, wäre, wenn im Constructor der Pointer auf die Klasse zeigt. Da wird ja noch am Objekt gewerkelt. Aber dass zur Laufzeit der Pointer nicht auf das Objekt sondern auf die Klasse zeigt, finde ich schon sehr unpraktisch.
Daher dieser Denkfehler mit @ServerKlasse.

Was die Frage des -was will ich überhaupt mit sowas- angeht, die Sache ist, ich habe einen Serverkonstrukt, bei dem jeder Server nach Schema x läuft. Problem daran, mir ist es einfach zu viel und zu unübersichtlich, TSNE an der Stelle einfach 3 mal abzupinseln und jedes mal anzupassen. Da erstelle ich lieber ein Objekt und das Ding schaukelt mir das mit ganz einfachen Befehlen fast von selbst. Ich gebe dann effektiv nur noch mit, mit welchen Parametern der Server läuft, ich rufe vom Server Daten ab, Sende an den Client Daten über den Server und mache, wenn ich keine Lust mehr habe, den Server wieder platt. Mehr will ich fast garnicht.
Da ich das jetzt aber als Lib fasse, kommt natürlich noch ein bisschen praktisch/statistische Deko/Kosmetik rundherum und auch die unzähligen Parameter sollen ja Otto - Normal - Zerbraucher - sicher werden.

Was die ganzen Beispiele angeht, ich versuche das alles noch ein bisschen zu verwursten. Danke dafür auf alle Fälle, es hat mich gut weitergebracht. Zwar hatte ich trotzdem den einen oder anderen Tag der Krise, aber ich bin gerade mit 900 Zeilen, speicherleckendem funktionierendem Code gut dabei durchgeknallt

@ThePuppetMaster
Wie du sicherlich schon mehr oder weniger gelesen haben wirst, ist es eine Adaption, um mir Schreibarbeit zu sparen. Da ich TSNE in allen Projekten mit Netzwerk bei mir verwurste, weil ich einfach keine Lust mehr habe, mich mit C herumzuärgern, ist es jetzt für mich auch das beste, eine Adaption über TSNE und nicht mit C zu schreiben. Ich will dann doch noch nicht wegen C ins Krankenhaus/in die Irrenanstalt kommen.
Die Klassen - Geschichte mache ich eigentlich nur, damit ich noch mehr einspare als ohnehin schon. Ich muss z.B. nicht mehr aufpassen, ob ich den Server dicht gemacht habe - ich hab ja nen Destructor, der das für mich macht - sofern ich es nicht schon zur Laufzeit selbst erledigt habe. Oder die Clients sortieren und geordnet zur Ausführung bringen bzw. sinnvoll auf die Requests reagieren - muss ich alles schon nicht mehr machen jetzt.

Um mal Zahlen zu nennen: Um 6 Server aufzumachen, die mir das zurück schicken, was ich denen sende, brauche ich nach aktuellem Stand 41 Zeilen. Wenn ich es noch etwas weiter verschachtel, gehts noch kleiner. Dazu kommt sogar ein kleines Monitoring, welches mir den Istzustand anzeigt für alle 6 Server. Zwar flackerts bei hohen Geschwindigkeit wie sonst was, weil der Terminal - Bildpuffer asynchron zum Print ist - aber das ist ja noch das kleinste Übel. Nur wenn der Monitor dann auch weg ist, wird das Programm schon verschwindend klein.

Was ich mich bei TSNE frage: Wie lehne ich als Server eigentlich eine Verbindung gezielt ab ? Momentan mach ichs so, dass ich den Client mit TSNE_Create_Accept annehme, bei TSNE_Create_Accept aber keine Funktionen hinterlege, um Risiken zu mindern. Anschließend schmeiß ich den Client mit TSNE_Disconnect direkt danach und ohne Verzögerung wieder vom Server. Ist das so im "Sinne des Erfinders" oder geht das noch anders ? Da ich in dem Codewust nicht richtig durchsehe, da die Bezeichner mir eher kryptisch anmuten, kann ich es blöderweise selbst nicht so wirklich erkennen, wie es gedacht ist. Und bisher habe ich eine Doku, wo das steht, zu meinem leidwesen übersehen.

@Mod
An sich geht das schon in die richtige Richtung. Was mir daran nur nicht ganz so gefällt ist, dass es eher weniger eine Idiotensichere Lösung ist. Ich komme einfach an zu viele Sachen direkt heran. Bei mir ist es so, dass alles, was der Programmierer nicht kaputt machen darf, grundsätzlich nach einem PRIVATE kommt. Damit will ich auch erzielen, dass meine LIB, sag ich mal, intuitiver ist. Weil der Programmierer kommt ja mit nix mehr in Kontakt, was ihn nicht zu interessieren hat. Aber um die Callbacks bzw. die ganze STATIC - Geschichte zu umgehen ist es eine gute Variante, wenns jetzt nicht so auf das Lib - gewese drauf ankommt.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 08.03.2019, 02:16    Titel: Antworten mit Zitat

Zuerst einmal .. n tut gibts hier: https://www.freebasic-portal.de/tutorials/netzwerkprogrammierung-tsne-v3-60.html

zum "verweigern" .. nun .. das mache ich auch so .. eigentlich gibt es ein paket, das als verweigerung gesendet werden kann, allerdings ist das in der aktuellen form nicht in tsne integriert, da es keine passende api-funktion hierfür gibt. Es liese sich zwar sicher eine funktion basteln, welche das übernimmt, ist allerdings faktisch genau das gleiche .. accept -> disconnect -> fertig.

Bezüglich der "krypto" .. jain .. die funktionen sind (sofern die die bezeichnungen von tsne meinst) sind "codiert" .. Die beschreibung hierfür findest du auch in obrigem tut.

PS: bezüglich des "flackerns" .. versuch es mal mit "screenlock / ...unlock"


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
CommLan



Anmeldungsdatum: 23.10.2015
Beiträge: 40
Wohnort: hinterm Mond

BeitragVerfasst am: 08.03.2019, 11:56    Titel: Antworten mit Zitat

Hallo ThePuppetMaster,
die Sache ist, das Tutorial kenne ich. Verwende ich auch. Aber zu dem Thema und einigen anderen Themen ist da nichts zu finden.

Interessant fände ich Tutorials zu BW und UDP.
Zudem, was auch interessant wäre, sind allgemeine Verhaltensweisen von TSNE. Was ich z.B. noch nicht so sicher rausfinden konnte bisher - ist bei TSNE_Create_ServerWithBindIPA die 127.0.0.1 der Loopback oder gewollt alle IPs ? Weil ich hatte mal gelesen, dass 127.0.0.1 bei deiner Lib heißt, dass der Server überall erreichbar ist. Und das Verhalten ist auf meinem Rechner auch zu beobachten. Find ich allerdings etwas unschön, wenn man Streams hat, die nur auf dem Rechner laufen sollen und nirgendwo anders.
Gibts da eine Möglichkeit oder ist das hardcore so drin ? Muss ich da dann mit BW nachhelfen ?

Naja, und was noch mal die Kryptosache angeht - ich meine nicht die Funktionsnamen. Dass da ne Codierung drin ist, um die Übersichtlichkeit aufrecht zu erhalten, weiß ich ja und verstehe ich.
Die Sache, was ich meine, ist der Quellcode in den Funktionen. Da hab ich irgendwie nicht so richtig den Durchblick. Ich muss aber dazu sagen, dass ich nen Ordnungsfimmel in Sachen Code habe und bei mir Variablen schon nen lesbaren, eindeutigen Namen haben sollten. Weil wenn da übertrieben BM als Baum steht, find ich das so schön. Ich mag mich damit auch nicht so gerne befassen, weils eher einem Rätselraten gleich kommt für mich neutral
Aber hat halt jeder so sein Vorlieben. Der nächste schreibt Spaghetti, ein anderer Roman, so wie ich. So ist das halt.

PS.: Zum flackern, ich hätte dazu sagen müssen - ich benutze kein Screenres / Screen, sondern das blanke Linux - Terminal. Da funzt das leider nicht.

Nachtrag: Was mir auch auffiel, ist die Tatsache, dass der Server erstmal bis ins Timout komplett hängt, wenn man eine Verbindung öffnet, aber keine Daten schickt (Vom Client aus (Weil ich den vorm Daten senden einfach abschieße)). Kann man da irgendwas machen, dass das nicht mehr passiert und der Server einfach Instant weiter macht ? Weil es ist schon unpraktisch, wenn der Server einen Dienst hostet und von jemandem gezielt mit sowas abgeschossen werden kann. Zumal ich auch das verhalten beobachten konnte, dass wenn mehrere abgebrochene Verbindungen dann noch im Zwischenspeicher sind, dass der Server die auch jeweils mit einer Minute hängen alle nacheinander quittiert.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1837
Wohnort: [JN58JR]

BeitragVerfasst am: 08.03.2019, 14:41    Titel: Antworten mit Zitat

CommLan hat Folgendes geschrieben:
Interessant fände ich Tutorials zu BW und UDP.

Naja... ein Tut zu BW und UDP empfand ich bis jetzt als nicht nützlich, da beides eigentlich so simpel ist, das man da kaum etwas zu erklären kann, was nicht schon in den beispielen drin steht.

UDP ist verbindungslos. Daher ist das erzeugen des UDP-Sockets automatisch immer aktiv, wenn es nicht schon auf dem selben Port ein anderes Socket gibt. Es gibt 2 Typen, den Sender und Empfänger. Beide können direkt erzeugt werden, und nach der erzeugugn auch direkt zum senden udn empfangen verwendet werden. Daher ... nicht wirklich viel zu erklären bezüglich deren zustände.

Bezüglich BW ist es ähnlich. Ist ne Liste, der man mit _add eine ip hinzufügen kann.

CommLan hat Folgendes geschrieben:
Zudem, was auch interessant wäre, sind allgemeine Verhaltensweisen von TSNE. Was ich z.B. noch nicht so sicher rausfinden konnte bisher - ist bei TSNE_Create_ServerWithBindIPA die 127.0.0.1 der Loopback oder gewollt alle IPs ? Weil ich hatte mal gelesen, dass 127.0.0.1 bei deiner Lib heißt, dass der Server überall erreichbar ist. Und das Verhalten ist auf meinem Rechner auch zu beobachten. Find ich allerdings etwas unschön, wenn man Streams hat, die nur auf dem Rechner laufen sollen und nirgendwo anders.
Gibts da eine Möglichkeit oder ist das hardcore so drin ? Muss ich da dann mit BW nachhelfen ?

Nein, die loopback-adr ist so nicht fest hinterelgt. Es liegt am verhalten des Systems. Und, ja, ich geb dir recht. Die loopback sollte lokal agieren. (So wie das 2^0 problem lächeln )

Das "Binden" hat in diesem fall allerdings auch eher den Zweck, das Socket an eine bestimmte Netzwerkkarte zu binden. Wenn du folglich merere Karten drin hast, haben Sie eine Lokale Adr. Diese Lokal-Adr ist faktisch die adr, welche du mit Bind der Karte zuordnen kannst.

Beispiel-1:
Karte-A: 192.168.0.1

TSNE bindet mit 127.0.0.1 die erste lokale karte an .. also 192.168.0.1 und, da es nur eine karte gibt, ist dies damit auch die globale Verbindung.

Beispiel-2:
Karte-A: 192.168.0.1 / 255.255.255.0
Karte-B: 192.168.1.1 / 255.255.255.0

TSNE bindet hier mit 127.0.0.1 ebenfalls die erste lokale karte an. Gibst du jetzt jedoch die lokale adr. ...0.1 oder ...1.1, dann hört das socket entsprechend auf der spezifizierten Karte.

Es ist also nicht so, wie du annimmst, das mit Bind eine Adressgruppe gemeint ist, oder "nur lokal", sondern entsprechend das lokale system. (Aber, ich geb dir recht, das verhaltn ist etwas doof mit 127...)

CommLan hat Folgendes geschrieben:
Naja, und was noch mal die Kryptosache angeht - ich meine nicht die Funktionsnamen. Dass da ne Codierung drin ist, um die Übersichtlichkeit aufrecht zu erhalten, weiß ich ja und verstehe ich.
Die Sache, was ich meine, ist der Quellcode in den Funktionen. Da hab ich irgendwie nicht so richtig den Durchblick.

Naja... ich kann dir gerne meine Struktur erklären ...
Alles was mit "T" / "X" beginnt oder mit "T" endet sind Temporäre Variablen, welche nur "kurzfristig" gebraucht werden. "N" (ende / anfang) sind "Neue Werte", z.B. Neu generierte Speicherbereiche. "L" ist der "Letzte" Pointer einer LinkedList. Normalerweise wäre "F" der erste, ist aber leider hier ein "D". "X", "Y", "Z" sind Laufvariablen ... "BV" ist noch aus alter zeit und stand für "BackValue", was ich heute als RV für "ReturnValue" bezeichne. V_, R_ und RV_ ist ja schon aus dem tut bekannt. Der Rest ist regulär selbsterklärend durch dessen Bezeichnung.

CommLan hat Folgendes geschrieben:
PS.: Zum flackern, ich hätte dazu sagen müssen - ich benutze kein Screenres / Screen, sondern das blanke Linux - Terminal. Da funzt das leider nicht.

Fürs Terminal konnte man das glaub auch irgend wie machen ... aber, alternativ, einfach den cursor auf "off" stellen, zur Pos jumpen, und den entsprechenden Wert aktualisieren. Dann flackerts auch nicht, wenn du z.B. den gesammten inhalt überschreibst.

CommLan hat Folgendes geschrieben:
Nachtrag: Was mir auch auffiel, ist die Tatsache, dass der Server erstmal bis ins Timout komplett hängt, wenn man eine Verbindung öffnet, aber keine Daten schickt (Vom Client aus (Weil ich den vorm Daten senden einfach abschieße)). Kann man da irgendwas machen, dass das nicht mehr passiert und der Server einfach Instant weiter macht ? Weil es ist schon unpraktisch, wenn der Server einen Dienst hostet und von jemandem gezielt mit sowas abgeschossen werden kann. Zumal ich auch das verhalten beobachten konnte, dass wenn mehrere abgebrochene Verbindungen dann noch im Zwischenspeicher sind, dass der Server die auch jeweils mit einer Minute hängen alle nacheinander quittiert.

Hä? ... was? .. wie? ... versteh ich nicht. Kannst du mir ein Beispiel-Code geben.?!


MfG
TPM
_________________
[ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz