Seite 4 von 4

Re: noch ein daten senden problem

Verfasst: 23.01.2017 22:11
von STARGÅTE
schleicher hat geschrieben:Wie kann man das noch machen, das man auch alle Informationen sicher empfängt ?
Na zuallererst solltest du dein GetString umschreiben.
Und zwar in der Form, dass du die Events "richtig" verarbeitet und auch mehrere Events zulässt (weil es auch durchaus mehrere geben kann).

Des weiteren musst du deine ReceiveNetworkData()-Schleife anpassen.
Zum einen brauchst du durchaus mehrere ReceiveNetworkData() um alles zu empfangen. Dabei muss dann aber dein *Buffer ständig vergrößert werden und die empfangenen Daten an der richtigen Stelle abgelegt werden.

Nun kommt aber das eigentliche Problem:
Du (bzw. ich) weiß nicht, wann du deine Empfangsschleife abbrechen musst, dafür brauchst du halt entweder ein "Signal-Zeichen" was das Ende ankündigt oder eine vorher definierte Länge an empfangenen Daten.
Vielleicht findest du ja dazu ein paar Informationen, dann kann ich vielleicht noch mal ein Code für dich schreiben (aber nicht heute)

Re: noch ein daten senden problem

Verfasst: 24.01.2017 12:28
von schleicher
STARGÅTE hat geschrieben: Nun kommt aber das eigentliche Problem:
Du (bzw. ich) weiß nicht, wann du deine Empfangsschleife abbrechen musst, dafür brauchst du halt entweder ein "Signal-Zeichen" was das Ende ankündigt oder eine vorher definierte Länge an empfangenen Daten.
Ja genau das ist das Problem. Eine vorher definierte Länge ist nicht so gut, weil die Länge immer variert. Manchmal nur 10 byte , manchmal aber auch sehr viel mehr. Wenn das einloggen stattgefunden hat (Username und Passwort), dann habe ich eine Möglichkeit, denn dann sendet der Server am Ende jeder Antwort den Namen des Servers (in meinem Fall root@et9x00:~#). Die Zeichenfolge "~#" könnte man dann als Ende jeder Antwort sehen, weil das bei jedem Linux(Enigma)-Server immer gleich ist, nur der Name "et9x000" ist je nach Hersteller anders. Nur eben beim einloggen wird diese Zeichenfolge erst gesendet, wenn das einloggen fertig ist.

Ea wäre warscheinlich das Beste, wenn ich fürs einloggen eine eigene ReceiveNetworkData()-Schleife schreibe.

Re: noch ein daten senden problem

Verfasst: 24.01.2017 14:44
von schleicher
Ich würde mich aber sehr freuen, wenn du mir auch ein Beispiel schreiben könntest, denn ich vermute, das ich das wieder falsch mache.

Re: noch ein daten senden problem

Verfasst: 24.01.2017 20:28
von mk-soft
Ich habe mal das hier einmal grob überlesen.

Wie bereits Stargate schon gesagt hat muss man selber darum kümmern das alle Daten angekommen sind. Also den Empfangsbuffer auswerten und die entsprechend umkopieren.

Dazu kann man bei Strings mit Start- und Endezeichen arbeiten.

Eine andere Methode ist es ist Header zu arbeiten. Damit lassen sich auch unterschiedlichen Datentypen übertragen.
Zum Beispiel bei Modbus over TCP sind im Header die erste drei Worte (16bit) festgelegt.

1. TransactionID; Fortlaufende Nummer
2. ProtocolID; Standard immer Null
3. DataLen; Anzahl der folgende Bytes

Als erstes im Ablauf mit ReceiveNetworkData nur die erstes 6 byte lesen.
Dann solange lesen bis die Anzahl von DataLen angekommen sind.
Danach die Daten auswerten.

Um sehr große Datenmengen zu übertragen habe ich mal ein Modul geschrieben...
Dieses ist zur Anwendung relativ leicht zu verwenden.

Aber zum erlernen von Netzwerkkommunikation schon sehr komplex

Link zum Modul:
http://www.purebasic.fr/german/viewtopi ... =8&t=29743

Re: noch ein daten senden problem

Verfasst: 24.01.2017 21:26
von schleicher
Danke mk-soft. Dein Modul für große Daten habe ich mir bereits abgespeichert und nutze es für FTP-Verbindung.
Für die Telentverbindung habe ich heute eine Lösung gefunden mit Hilfe von Stargates Tips. Danke nocheinmal dafür. Habe Receivestring() so umgeschrieben, das er nun alle Daten empfängt.

Ist bestimmt nicht so perfekt aber funktioniert, Wenn jemand eine bessere Lösung weiss freue ich mich natürlich
Bei großen zu erwartenden Datenmengen erhöhe ich die paketsize, dann kommt das Ergebnis schneller.

Code: Alles auswählen

Procedure.s ReceiveString(ConnectionID, TimeOut, paketsize)
  
  Protected *Buffer, t, Size, Text.s, x, Text1.s
  
  
  Text=""
  Repeat
    *Buffer = AllocateMemory(paketsize+1)
  Until *Buffer
  t = ElapsedMilliseconds()
  
  
  If *Buffer
    
    While NetworkClientEvent(ConnectionID) <> 2 And ElapsedMilliseconds()-t < Timeout
      Delay(10)
     Wend
  
    Repeat
      Size=ReceiveNetworkData(ConnectionID, *Buffer, paketsize)
      Debug Size
      If Size=paketsize
        text1=PeekS(*Buffer, -1, #PB_UTF8)
        Text=Text+Text1
        FillMemory(*Buffer, paketsize+1)
      ElseIf Size<paketsize And Size>0
        Text1=PeekS(*Buffer, -1, #PB_UTF8)
        Text=Text+Text1
        Break
      EndIf
    ForEver
    
    FreeMemory(*Buffer)
    
   ProcedureReturn Text   
    
  EndIf
  
EndProcedure