NetworkStream empfängt zu schnelle Daten nicht

  • VB.NET
  • .NET (FX) 4.0

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von mrwebber.

    NetworkStream empfängt zu schnelle Daten nicht

    Hallo zusammen,

    nochmal ein Netzwerkproblem, das ich seit zwei Stunden nicht in den Griff bekomme.

    Ich sende wiefolgt (s ist der NetworkStream):
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim bf As New BinaryFormatter()
    2. Dim ms As New MemoryStream
    3. bf.Serialize(ms, oData)
    4. Dim bu() As Byte = ms.ToArray
    5. Dim sr As New StreamWriter(s)
    6. Dim iLen As Integer = UBound(bu) + 1
    7. sr.WriteLine(iLen)
    8. sr.Flush()
    9. s.Write(bu, 0, iLen)
    10. s.Flush()

    Und empfange so (s ist der NetworkStream):
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Do
    2. Dim bf As New BinaryFormatter()
    3. Dim sr As New StreamReader(s)
    4. Dim iLen As Integer = 0
    5. iLen = CInt(sr.ReadLine)
    6. Dim bu(iLen - 1) As Byte
    7. s.Read(bu, 0, iLen)
    8. Dim ms As New MemoryStream(bu)
    9. oData = CType(bf.Deserialize(ms), List(Of Object))
    10. datenAuswerten(oData)
    11. Loop

    Das funktioniert prima. Wenn ich allerdings mehrere Nachrichten schnell hintereinander sende,
    kommt die zweite nicht an.

    Liegt das daran, dass ich während dem Verarbeiten der Daten mit dem StreamReader noch nicht .readLine()-lese, obwohl die zweite Bufferlänge schon gesendet wird?
    Buffert der Netzwerkstream? D.H. kann ich da auch später noch lesen, obwohl mir schon was zugesendet wurde?

    Ich stehe echt auf dem Schlauch ...
    mache ich ein sleep von 100ms zwischen die Sendevorgänge, klappt alles wunderbar.

    Variablen über das Internet senden? [VB.NET] Universal Ticket.dll :thumbup:
    Lasse deine Programme selbstständig lernen! [VB.NET] Brain.dll
    :thumbsup:
    man kann nicht mit 2 Readern aus demselben Stream lesen.
    Son Reader befüllt intern einen Puffer, sodass der Stream schon viel weiter ausgelesen ist als der Reader Daten ausgibt.
    Wenn dann der andere Reader weiterlesen soll, dann hat man eine Daten-Lücke.
    nimm einen BinaryReader, und benutze den, um sowohl die Länge auszulesen als auch die Daten.
    Und schreib die Sachen mit einem BinaryWriter hinein.

    Wenn du eine vernünftige Methode postest, dann kann ich das auch mal bisserl pimpen - so wies ist, ist's noch ziemlich wurstelig.
    Aha! Damit kommen wir der Sache schon deutlich näher!

    Also Anforderung an meinen Code ist, dass eine List(Object) mit dem BinaryFormatter zu Bytes konvertiert wird.
    Dieses Array brauche ich später evtl. noch.
    Danach soll dieses Array an Bytes über den NetworkStream gesendet werden.

    Auf der anderen Seite soll das Array wieder aufgebaut werden und danach mit einem BinaryFormatter wieder zu einer richigen Objekt (-> List (Of Object)) zurückgewandelt werden.

    Wie kann ich mit dem BinaryWriter die Länge auslesen?
    So lange .read() aufrufen und an das Array anhängen, bis ein Ende-Zeichen kommt?
    Wie fände ich dann raus, ob es ich nicht schon um die nächsten Daten vom folgenden Objekt handelt?
    Muss ich selbst ein Ende-Zeichen mitsenden, und gibt es eines, das der BinaryFormatter nicht zufällig erzeugt?

    EDIT: Sorry for die Code-Qualität, ich taste mich gerade sehr langsam noch an das Thema Streams ran und habe auch das Gefühl, hier noch einige Anfängerschwierigkeiten zu haben.

    Variablen über das Internet senden? [VB.NET] Universal Ticket.dll :thumbup:
    Lasse deine Programme selbstständig lernen! [VB.NET] Brain.dll
    :thumbsup:
    Senden, provisorisch:

    VB.NET-Quellcode

    1. Private Sub send(ByRef s As NetworkStream, ByRef oData As List(Of Object))
    2. Dim bf As New BinaryFormatter()
    3. Dim ms As New MemoryStream
    4. bf.Serialize(ms, oData)
    5. Dim buf() As Byte = ms.ToArray
    6. Dim bw As New BinaryWriter(s)
    7. bw.Write(buf)
    8. bw.Flush()
    9. End Sub


    Empfangen, provisorisch:

    VB.NET-Quellcode

    1. Private Sub receive(ByRef s As NetworkStream)
    2. Dim bf As New BinaryFormatter()
    3. Do
    4. Dim oData As List(Of Object)
    5. Dim br As New BinaryReader(s)
    6. Dim buf As New List(Of Byte)
    7. While br.PeekChar <> EOF()
    8. buf.Add(br.Read)
    9. End While
    10. Dim ms As New MemoryStream(buf)
    11. oData = CType(bf.Deserialize(ms), List(Of Object))
    12. verarbeite(oData)
    13. Loop While bShutdown = False
    14. End Sub


    Variablen über das Internet senden? [VB.NET] Universal Ticket.dll :thumbup:
    Lasse deine Programme selbstständig lernen! [VB.NET] Brain.dll
    :thumbsup:
    Ist nicht an.
    Welchen Datentyp gibt br.Read zurück?
    Welchen Datentyp erwartet buf.Add?

    Passt das zusammen? - nein. Also ist offsichtlich Strict Off.

    Welchen Datentyp hat das Objekt?

    jdfs. probierma meine Bearbeitung

    VB.NET-Quellcode

    1. Private Sub send(s As NetworkStream, oData As List(Of Object))
    2. Dim bf As New BinaryFormatter()
    3. Dim ms As New MemoryStream
    4. bf.Serialize(ms, oData)
    5. Dim bw As New BinaryWriter(s)
    6. bw.Write(CInt(ms.Length))
    7. bw.Write(ms.ToArray)
    8. 'bw.Flush() 'erstmal ohne probieren
    9. End Sub
    10. Private Sub receive(s As NetworkStream)
    11. Dim bf As New BinaryFormatter()
    12. Dim br As New BinaryReader(s)
    13. Do
    14. Dim oData As List(Of Object)
    15. Dim length = br.ReadInt32
    16. Dim ms As New MemoryStream(br.ReadBytes(length))
    17. oData = DirectCast(bf.Deserialize(ms), List(Of Object))
    18. verarbeite(oData)
    19. Loop While bShutdown = False
    20. End Sub

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Richtig toller Support! Super Sache!

    Klappt problemlos ohne Flush.
    Jetzt kann ich erstmal in ruhe weiter tüfteln! :)

    EDIT: @OptionStrict: Beide Recht gehabt :D Ich hatte se zwar an, aber die Methode kopiert gehabt, um die alte noch zu erhalten. Da die Signatur schon angemeckert wurde, hat der Compiler den Code in der Methode gar nicht mehr kontrolliert :D

    Variablen über das Internet senden? [VB.NET] Universal Ticket.dll :thumbup:
    Lasse deine Programme selbstständig lernen! [VB.NET] Brain.dll
    :thumbsup: