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:

Socket Server ohne Threads
Gehe zu Seite Zurück  1, 2, 3
 
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
nemored



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

BeitragVerfasst am: 21.12.2012, 22:56    Titel: Antworten mit Zitat

DEALLOCATE gibt einen mit ALLOCATE reservierten Speicherbereich wieder frei.
_________________
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
stevie1401



Anmeldungsdatum: 04.07.2006
Beiträge: 133

BeitragVerfasst am: 22.12.2012, 00:26    Titel: Antworten mit Zitat

Jo, habe ich inzwischen nachgelesen, wenn auch nicht ganz verstanden, aber egal.
Es steht allerdings auch da, dass es nicht unbedingt Thread-save ist.

Der Fehler mit der doppelten Anmeldung liegt zu 100% am Server, habe ich inzwischen getestet.
Hm...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
nemored



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

BeitragVerfasst am: 22.12.2012, 00:46    Titel: Antworten mit Zitat

Du belegst Speicher, und wenn du ihn nicht mehr brauchst, gibst du ihn wieder frei. Würdest du das nicht machen und immer wieder neuen Speicher belegen, würde dir auf Dauer der Speicherplatz ausgehen und das Programm abstürzen.
_________________
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
stevie1401



Anmeldungsdatum: 04.07.2006
Beiträge: 133

BeitragVerfasst am: 23.12.2012, 01:56    Titel: Antworten mit Zitat

@Puppetmaster
Dein vorgeschlagener Code
Code:

Type MSG_Type
    V_Next as MSG_Type Ptr
    V_TSNEID as UInteger
'sollte V_Data nicht ein String sein? Aber auch als String   
'funktioniert es nicht.
    V_Data as UInteger
End Type

Dim Shared G_MSGF as MSG_Type Ptr
Dim Shared G_MSGL as MSG_Type Ptr

Sub TSNE_NewData(Byval V_TSNEID As Uinteger, Byref V_Data As String, Byval V_CallBackPtr As Client_Type Ptr)
MutexLock(G_ClientMux)
If G_MSGL <> 0 Then
    G_MSGL->V_Next = CAllocate(SizeOf(MSG_Type))
    G_MSGL = G_MSGL->V_Next
Else
    G_MSGL = CAllocate(SizeOf(MSG_Type))
    G_MSGF = G_MSGL
End if
With *G_MSGL
    .V_TSNEID = V_TSNEID
    .V_Data = V_Data
End With
MutexUnLock(G_ClientMux)
End Sub


Dim TPtr as MSG_Type Ptr
Do Until InKey() = Chr(27) 'oder wie auch immer die schleife aussieht
    '...
    MutexLock(G_ClientMux)
    If G_MSGF <> 0 Then
        TPtr = G_MSGF
        With *TPtr
            Verarbeite_Nachricht(.V_TSNEID, .V_Data)
        End With
        G_MSGF = TPtr->V_Next
        DeAlloctae(TPtr)
    End If
    MutexUnLock(G_ClientMux)
    '...
    sleep 1, 1
Loop


funktioniert überhaupt nicht.
Leider blicke ich das mit den Pointern auch überhaupt nicht und ich finde es sehr unübersichtlich.
Mein Code:
Code:

Sub TSNE_NewData(Byval V_TSNEID As Uinteger, Byref V_Data As String, Byval V_CallBackPtr As Client_Type Ptr)
MutexLock(G_ClientMux)
 MessageFromClient=V_Data  'Dim Shared as String
 ClientID=V_TSNEID          'Dim Shared as uInteger
MutexUnLock(G_ClientMux)
End Sub




Do Until InKey() = Chr(27) 'oder wie auch immer die schleife aussieht
    '...
    MutexLock(G_ClientMux)
    If MessageFromClient<>""  Then
        Verarbeite_Nachricht(ClientID, MessageFromClient)
        MessageFromClient=""
    End If
    MutexUnLock(G_ClientMux)
    '...
    sleep 1, 1
Loop

funktioniert, aber ich bin mir nicht sicher, ob das nicht zu Chrases führen kann.
Muss in der Hauptschleife überhaupt ein MutexLock/Unlock sein?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ThePuppetMaster



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

BeitragVerfasst am: 24.12.2012, 16:32    Titel: Antworten mit Zitat

1. Ja, muss String sein, ud nicht UInteger. Da hast du recht.

2. So wie du das geschrieben hast, kannst du das schon machen, is auch threadsafe, allerdings nicht nachrichtensicher.


Also, zur kurzen erklärung meines codes und deines codes.

Mein Source:
Ich lege eine Liste an. eine sogenante LinkedList. Das ist eine Liste, die man erweitern und verkleinern kan (ähnlich einem array), jedoch mit einigen geschwindigkeitsvorteilen. Mehr infos dazu goibts in den tutorials in freebasic-portal.de.

an diese liste hänge ich einen neuen eitrag an, sobald eine nachricht eintrudelt. dieser eintrag beinhaltet die nachricht selbst und die id, von der sie kam.

damit das ganze threadsafe ist utze ich ein mutex, das ich vor dem ändern der liste sperre, und nach dem ändern wieder entsperre.

in der hauptschleife wird geprüft, ob die liste einträge beinhaltet. wen dem so ist, wird der erste eintrag oin der liste heraus genommen und zwischegespeichert.
anschliessend dieser erste eintrag gelöscht, womit die nachfolgenden nach vorne rücken.

dieser zwischengespeicherte eintrag wird daraufhin der auswert-fuktion von dir übergeben.

dadurch verliehrst du keine einzige nachricht, da jede eingehende in diese liste aufgeommen wird.


zu deinem source:
du machst "ansich" etwas ähnliches. du speicherst die nachricht jedoch nicht in eine liste, nachricht für nachricht, sondern in eine einzige, einzelne variable. sprich, wenn der fall eintreten sollte, das 2 nachrichten hinteienander eingehen, bevor der hauptthread diese verarbeiten konnte, dan wird die erste von der zweiten (und der dritten, und vierten, usw.) überschrieben, bevor der hauptthread diese verarbeiten konnte.

deswegen nutzt mein source auch eine liste, an der die nachrichten angehängt werden, und nicht überschreibt.

bei dir ist es also möglich, das du nachrichten verliehrst. bei meinem source ist das nicht der fall.

wen du also doppelte ameldungen bekommst, kann da entweder daran liegen, das dieser eintrag doppelt in der liste vorhanden ist, du ihn eventuell 2x verarbeitest, oder der client ihn 2x sendet.
oder auch, das der server ihn 2x in die liste einträgt, da er vieleicht an alle und an sich selbst übermittelt wird.

warum, ist schwer zu verfolgen, wenn man nicht server udn client sourcecode zur verfügung hat.


Bezüglich Pointer:
Also ... wenn du Dim ABC as UInteger anwendest, dann erzeugt dir dein Programm einen speicherbereich der 4 byte gross ist.

indem du ABC verwendest .. z.B. abc = 1, sagst du dem programm, das er in diese variable (in den spoeicherbereich welcher abc repräsentiert) den wert 1 schreiben soll

du kennst jetzt allerdings nur einen willkürlichen namen dieser variable. wo genau im speicher dieser speicherplatz liegt, ist dir nicht bekannt.
das kann mit z.B. mit CPtr(abc) herausfinden.

diese fuktion gibt dir die adresse (den speicherplatz) zu dieser variable zurück.

diese adresse ist eindeutig, und definiert hier expliziet den speicherplatz für diese eine variable. jede variable hat prinzipiell eine eigene adresse.

damit das programm weis, wo es die daten im speicher ablegen muss, braucht eben jede variable eine adresse (speicheradresse)

mit dieser adresse kann man also auf den speicher zugreifen.

du kannst jetzt z.B. einen sogenanten zeiger (pointer) erzeugen.
dim abc_pointer as uinteger ptr
dies ist eine variable (geauso wie abc), die jedoch keine normalen zahloenwerte oder textzeichen speichert, sondern speicheradressen.
abc_pointer = cptr(abc)
jetzt hast du also die adresse von abc in eine pointer-variable (abc_pointer) gespeichert.

wenn du jetzt auf diesen speicher zugreifen willst, kannst du das mithilfe von * tun.
Print *abc_Pointer
hier wird dir das Print jetzt "1" ausgeben. Das Programm weis, das du keine variable sondern einen pointer hast, liest die speicheradresse aus, greift auf diese adresse zu und gibt dir den wert, welcher an dieser adresse liegt zurück.

der unterschied ist also, das du mit normalen variablen den wert der eigenen variable auslesen / manipulieren kanst, und mit pointer-variablen kannst du fremde (nicht die eigene) auslesen. Hierzu teilt man dieser natürlich erst die adresse der fremden speicheradresse mit.

das ist eigentlich auch schon das ganze prozedere dahinter.

was man damit jetzt alles anstellen kann, sollte erstmal ebensächlich sein. aber, als beispiel kann man so z.B. speicherbereiche über das gesammte programm hinweg übermitteln, ohne die daten zu kopieren. man reicht einfach den "pointer" weiter. dieser ist 4 byte gross. im gegensatz zu z.B. einem 1000Byte grossen Text-String, welcher bei jedem weiterreichen immer wieder kopiert werden muss.

Und solche Pointer verwende ich in der liste (Linked List). Es ist quasi eine liste aus speicheradressen, welche die daten speichert.
Steckt zwar noch n ticken mehr dahinter, aber das ist erstmal egal.


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



Anmeldungsdatum: 04.07.2006
Beiträge: 133

BeitragVerfasst am: 24.12.2012, 16:38    Titel: Antworten mit Zitat

Vielen Dank für deine ausführliche Erklärung.
Dein Code (String geändert), funktioniert dennoch nicht, wie oben schon erwähnt.
Man genau 1 Meldung senden, danach nimmt der Server keine weiteren Nachrichten auf.
Du kannst ja noch mal nachgucken, was da evtl nicht stimmen könnte.

Euch allen eine schöne Weihnacht lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail 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 Zurück  1, 2, 3
Seite 3 von 3

 
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