none
NetWorkOrder - ByteArray - ByteArray integer RRS feed

  • Frage

  • Hallo,
    ich empfange über TCPClient ein Telegramm, die ersten 4 Bytes sind die Länge mit NetWorkOrder.
    Wenn ich das ganze konvertiere passt es nicht.
    Sieht jemand einen Fehler, die Ursache.
    Obwohl ich nur 4 Bytes im String analysiere sind es 6 im Byte[] Array.
    Konvertiere ich mit ASCII, sind es 4, wie erwartet, die Länge passt aber auch nicht.
     
    numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
    responseCompleteMessage.AppendFormat("{0}", Encoding.UTF8.GetString(myReadBuffer, 0, numberOfBytesRead));
       
    string forLength = responseCompleteMessage.ToString().Substring(0,4);
    byte[] test = Encoding.UTF8.GetBytes(forLength); 
    int i = BitConverter.ToInt32(test, 0);
    int lengthInHostOrder = IPAddress.HostToNetworkOrder(i);
    
    
    Byte[] bytesReceive = new Byte[4];
    length = 2233;
    unchecked
    {
     bytesReceive[0] = (byte)(length >> 24);
     bytesReceive[1] = (byte)(length >> 16);
     bytesReceive[2] = (byte)(length >> 8);
     bytesReceive[3] = (byte)(length);
    }  
     
    Ausweg aber umständlicher - ich nehme ein ByteArray.
    Byte[] bytesReceived = new Byte[8096]; 
    numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
    responseCompleteMessage.AppendFormat("{0}", Encoding.UTF8.GetString(myReadBuffer, 0, numberOfBytesRead));
    System.Array.Copy(myReadBuffer, 0, bytesReceived, numberOfBytesReadActual, numberOfBytesRead);
    numberOfBytesReadActual += numberOfBytesRead; 
    
    
    Byte[] bytesReceiveForLength = new Byte[4];
    System.Array.Copy(bytesReceived, 0, bytesReceiveForLength, 0, 4);
    int i2 = BitConverter.ToInt32(bytesReceiveForLength, 0);
    int lengthInHostOrder2 = IPAddress.HostToNetworkOrder(i2);
    string text2 = responseCompleteMessage.ToString().Substring(4, responseCompleteMessage.ToString().Length - 4);  

     
    Kurzum, kennt jemand einen Weg über den String zu gehen? Vielleicht gibt es einen gängigen Weg.
    Vielleicht ist die Übertragung der Länge auch gängig. Mir wurde das so vorgegeben.
    • IPAddress.HostToNetworkOrder
      IPAddress.NetworkOrderToHost
    Das Ergebnis ist immer dasselbe.

    Danke im Voraus.

    Viele Grüße Ulrich 
    Freitag, 8. April 2016 15:45

Antworten

  • Hallo Ulrich,

    ich verstehe die Anforderung im Augenblick nicht komplett. Was genau soll über das Netz gehen? 

    Wenn ich die Thematik richtig verstanden habe, dann soll zuerst die Länge in den ersten 4 Bytes übermittelt werden. Also würde ich diese 4 Bytes erst einmal nicht in einen String umwandeln. Wenn ich das richtig verstanden habe, dann solltest Du etwas wie folgt haben:
    Schleife, die Daten liest. Diese werden in eine ByteArray gelesen und zwar an die aktuelle Position. (Schleife ist wichtig, denn evtl. ist noch nicht die ganze Nachricht da!)
    Dann prüfst du: Hast du 4 Bytes? Wenn ja:
    - Du nimmst die ersten 4 bytes und wandelst die in deinen Integer um. Dazu kannst Du einfach die 4 Werte nehmen und shiften oder mit entsprechenden Werten multiplizieren. So wie du es mit dem BitConcerter teilweise ja auch schon gemacht hast.
    - Dann prüfst Du, ob Du schon die ganze Nachricht hast. Also die Schreibposition muss größer/gleich Errechnete Länge + 4 sein.
    - Wenn die Nachricht komplett im puffer ist: Dann wandelst Du diese um und nimmst setzt deinen Puffer neu (Also weitere Bytes umkopieren an den Anfang und Position ist dann die Position - länge Nachricht - 4.) Also zum Umwandeln rufst Du dann GetString mit dem richtigen Offset (4) und der korrekten Länge auf.

    Bezüglich der Umwandlung musst Du ggf. aufpassen. Es gibt unterschiedliche Arten, wie ein 4 Byte Integer in 4 einzelne Bytes aufgeteilt werden kann. Little und Big Endian wären da die Stichwörter, die wichtig sind. 

    Mit den besten Grüßen,

    Konrad

    • Als Antwort markiert Ulrich Stippe Dienstag, 12. April 2016 17:00
    Samstag, 9. April 2016 19:07

Alle Antworten

  • Hallo Ulrich,

    ich verstehe die Anforderung im Augenblick nicht komplett. Was genau soll über das Netz gehen? 

    Wenn ich die Thematik richtig verstanden habe, dann soll zuerst die Länge in den ersten 4 Bytes übermittelt werden. Also würde ich diese 4 Bytes erst einmal nicht in einen String umwandeln. Wenn ich das richtig verstanden habe, dann solltest Du etwas wie folgt haben:
    Schleife, die Daten liest. Diese werden in eine ByteArray gelesen und zwar an die aktuelle Position. (Schleife ist wichtig, denn evtl. ist noch nicht die ganze Nachricht da!)
    Dann prüfst du: Hast du 4 Bytes? Wenn ja:
    - Du nimmst die ersten 4 bytes und wandelst die in deinen Integer um. Dazu kannst Du einfach die 4 Werte nehmen und shiften oder mit entsprechenden Werten multiplizieren. So wie du es mit dem BitConcerter teilweise ja auch schon gemacht hast.
    - Dann prüfst Du, ob Du schon die ganze Nachricht hast. Also die Schreibposition muss größer/gleich Errechnete Länge + 4 sein.
    - Wenn die Nachricht komplett im puffer ist: Dann wandelst Du diese um und nimmst setzt deinen Puffer neu (Also weitere Bytes umkopieren an den Anfang und Position ist dann die Position - länge Nachricht - 4.) Also zum Umwandeln rufst Du dann GetString mit dem richtigen Offset (4) und der korrekten Länge auf.

    Bezüglich der Umwandlung musst Du ggf. aufpassen. Es gibt unterschiedliche Arten, wie ein 4 Byte Integer in 4 einzelne Bytes aufgeteilt werden kann. Little und Big Endian wären da die Stichwörter, die wichtig sind. 

    Mit den besten Grüßen,

    Konrad

    • Als Antwort markiert Ulrich Stippe Dienstag, 12. April 2016 17:00
    Samstag, 9. April 2016 19:07
  • Hallo Konrad,

    ich habe eine Kundenspezifikation, da steht was von Networkorder.

    Byte[] bytesReceive = new Byte[4];
    length = 2233;
    unchecked
    {
     bytesReceive[0] = (byte)(length >> 24);
     bytesReceive[1] = (byte)(length >> 16);
     bytesReceive[2] = (byte)(length >> 8);
     bytesReceive[3] = (byte)(length);
    }  

    Prinzipiell tut es so. Ich sehe nur keinen Unterschied.

    IPAddress.HostToNetworkOrder
    IPAddress.NetworkOrderToHost

    Problem erkannt. Danke.

    Grüße Ulrich

    Sonntag, 10. April 2016 14:15