Netzwerkdaten am laufenden Band ...

Anfängerfragen zum Programmieren mit PureBasic.
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Netzwerkdaten am laufenden Band ...

Beitrag von der-sigi »

Hallo Leute

ich habe noch einen Schmerzen, wo ich dazu kein Beispiel gefunden habe. Ich bekomme über einen Port Text rein und will den weiter verarbeiten. Wie mach ich das, daß ich den kompletten Text nachher in einer Stringvariablen habe?

Mein Versuch sieht so aus. Allerdings bleibt da immer der alte Text im Buffer und wird nur vorne durch neuen Text ersetzt - bei einem weiteren Aufruf dieser Funktion - wird ausgelöst durch ein "NetworkServerEvent() = 2". Auch das "ReAllocateMemory" nützt nichts.

Code: Alles auswählen

  Procedure HoleNetzwerkDaten()
    ; --- Text Puffer freimachen
    BufferText = ""
    ; --- und den ersten Text holen
    Ergebnis = ReceiveNetworkData(NetworkID, *Buffer, BufferLaenge) 
    ; --- im Text Puffer ablegen
    BufferText = PeekS(*Buffer, BufferLaenge - 1)
    ; --- ist noch mehr an Daten da ?
    While Ergebnis = BufferLaenge
      ; --- dann abholen
      Ergebnis = ReceiveNetworkData(NetworkID, *Buffer, BufferLaenge)
      ; --- und in den Text Puffer schreiben
      BufferText = BufferText+PeekS(*Buffer, BufferLaenge - 1)
    Wend
    ; --- dann alles putzen
    BufferText = ReplaceString(BufferText,Chr(13),"")
    BufferText = ReplaceString(BufferText,Chr(10),"")
    ; --- Buffer loeschen
    ReAllocateMemory(*Buffer, BufferLaenge) 
    ; --- Resultat rausgeben
    ProcedureReturn BufferText
  EndProcedure
Habe ich da irgendwas mißverstanden?

Viele Grüße
Sigi
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

Buffer tut man mit freeMemory löschen...

> BufferText
sollte am Anfang der Prozeudre mit einem
> Protected BufferText.s
deklariert werden
Bild
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-sigi »

Hallo MVXA

Danke für die Info. Ich wollte aber nicht den Buffer löschen, sondern nur den Inhalt! So muß ich ja bei jedem Prozedur-Aufruf den Buffer wieder anlegen und danach löschen. Da ich den nur mit der Prozedur brauche, hätte ich den global nur einmal angelegt, alles andere kostet nur Zeit und Performance und ist (meiner Meinung nach) kein guter Stil. Aber es geht wohl nicht anders. Wenn ich innerhalb der Prozedur den Buffer anlege und wieder lösche paßt das mit dem Resultat.

Danke nochmals
und viele Grüße
Sigi
Benutzeravatar
Frogger
Beiträge: 425
Registriert: 14.03.2006 19:27
Kontaktdaten:

Beitrag von Frogger »

Du könntest auch den ganzen Speicher mit Nullen füllen. (natürlich binäre Nullen)
Der Inhalt wäre somit auch gelöscht aber ob das schneller ist als den Speicher löschen und neu reservieren weis ich nicht. Muss man halt ausprobieren.
[PB4.20]
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

> sondern nur den Inhalt!
Das ist dann sowieso die falsche Methode, hier die API dafür:
RtlFillMemory_()

villt sollte Fred diese noch in PB4 einfügen...

ReAllocateMemory() vergrößert (oder behält die Größe in deinem Fall)
den Speicherbereich und gibt einen neuen zurück. Dabei sind die Daten
in dem Speicherbereich nicht gelöscht!
Bild
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Du gehst da etwas falsch rann.
Man muß und sollte nicht den Speicher löschen, sondern einfach nur die benötigten Daten auslesen.

Code: Alles auswählen

BufferLaenge.l = 1024
*Buffer = AllocateMemory(BufferLaenge)
; in PB4 mu man die Variablen noch als global declarieren

Procedure HoleNetzwerkDaten() 
   ; --- Text Puffer freimachen 
   BufferText = "" 
   ; --- und den ersten Text holen 
   Ergebnis = ReceiveNetworkData(NetworkID, *Buffer, BufferLaenge) 
   ; --- im Text Puffer ablegen 
   If Ergebnis > 0
      BufferText = PeekS(*Buffer, Ergebnis) 
   Else
      BufferText = ""
   EndIf
   
   ; --- ist noch mehr an Daten da ? 
   While Ergebnis > -1
      ; --- dann abholen 
      Ergebnis = ReceiveNetworkData(NetworkID, *Buffer, BufferLaenge) 
      ; --- und in den Text Puffer schreiben 
      If Ergebnis > 0
         BufferText = BufferText+PeekS(*Buffer, Ergebnis) 
      EndIf
   Wend 
   ; --- dann alles putzen 
   BufferText = ReplaceString(BufferText,Chr(13),"") 
   BufferText = ReplaceString(BufferText,Chr(10),"") 
   ; --- Buffer loeschen 
   ;ReAllocateMemory(*Buffer, BufferLaenge)  ; das lscht nicht den Speicher, sondern ndert nur die Gre
   ; --- Resultat rausgeben 
   ProcedureReturn BufferText 
EndProcedure 
Der Code ist ungetestet, sollte aber grundlegend funktionieren.

Gruß
Thorsten
1. Win10
PB6.1
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-sigi »

Hallo Toshy

aaaah, du hast meinen Fehler entdeckt. Da stand ich wohl auf dem Schlauch. Statt der "Bufferlaenge" muß ich natürlich das "Ergebnis" aus "ReceiveNetworkData()" mit dem "PeekS()" verwenden. Und dann braucht man natürlich auch nicht zu löschen. Und schon funktioniert mein "HoleNetzwerkDaten()". ;)

Mein Fehler. Entschuldige mich und BEDANKE mich für die viele Hilfe.

Sigi
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Hallo.

Schön das dir geholfen ist, eine Entschuldigung aber ist nicht notwendig. Zum gegenseitigen helfen und manchmal auch dampf ablassen sind wir doch da ;-)
Und jeder hier steht mal auf dem Schlauch, ich parke sogar manchmal mit einem Laster auf dem Schlauch.

Was mit noch aufgefallen ist:

Code: Alles auswählen

Else 
      BufferText = "" 
oder

Code: Alles auswählen

 ; --- Text Puffer freimachen 
   BufferText = "" 
kannst du weglassen bzw Beides. Wird sonst ja doppel "freigemacht". Falls die BufferText nicht als global declaiert hast, brauchst du das aber gar nicht zu machen, da Variablen in Proceduren normal nur lokal sind und bei jedem Procedureaufruf neu (und leer) erstellt werden.

Gruß
Toshy
1. Win10
PB6.1
der-sigi
Beiträge: 39
Registriert: 07.04.2006 12:22

Beitrag von der-sigi »

Danke Toshy für die weiteren Infos.
Klar, das doppelt freimachen muß ja nicht sein. ;)

Du sagst: "... Variablen in Proceduren normal nur lokal sind und bei jedem Procedureaufruf neu (und leer) erstellt werden". Wozu ist dann "Protected"? Ich dachte, nur dann sind die Variablen lokal. Oder muß ich das so verstehen:

"Protected Variable" ist IMMER lokal in der Prozedur. Und nur "Variable" ist eben lokal, weil nicht global definiert. Sobald aber eine andere Prozedur die gleiche Variable nutzt, gibt es Probleme bzw. ist das wie global. Also ist nur "Variable" NIEMALS lokal sondern IMMER global. Es wäre also nur eine Pseudo lokale Nutzung. Nur "Variable" als lokal zu nutzen wäre also sehr schlechter Programmierstil.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

der-sigi hat geschrieben:Danke Toshy für die weiteren Infos.
Klar, das doppelt freimachen muß ja nicht sein. ;)

Du sagst: "... Variablen in Proceduren normal nur lokal sind und bei jedem Procedureaufruf neu (und leer) erstellt werden". Wozu ist dann "Protected"? Ich dachte, nur dann sind die Variablen lokal. Oder muß ich das so verstehen:

"Protected Variable" ist IMMER lokal in der Prozedur. Und nur "Variable" ist eben lokal, weil nicht global definiert. Sobald aber eine andere Prozedur die gleiche Variable nutzt, gibt es Probleme bzw. ist das wie global. Also ist nur "Variable" NIEMALS lokal sondern IMMER global. Es wäre also nur eine Pseudo lokale Nutzung. Nur "Variable" als lokal zu nutzen wäre also sehr schlechter Programmierstil.
Variablen, die an eine Procedure übergeben werden, sind erst ab PB 4 immer Local!
Protected sorgt dafür, das die Variable in der Procedure keine globale
Variable selben Namens überschreibt, da diese sonst Vorrang hätte!
Wer also globale Variablen verwendet, sollte lokale Variablen immer als
Protected deklarieren, dann kann eigentlich nichts mehr verkehrt laufen :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten