Protokoll schreiben



  • uint32_t dataId;
    	uint32_t timed;
    	std::string payload;
    	memcpy(&dataId, position, sizeof(dataId));
    	position +=sizeof(dataId);
    	memcpy(&timed, position, sizeof(timed));
    	position +=sizeof(timed);
    	memcpy(&payload, position, sizeof(payload));
    

    Habe es so gemacht mit Zeiger und Co. Wie gesagt funktionieren die Ersten beiden Werte wunderbar, beim Dritten bekomme ich mit cout folgendes

    1730(erster Wert) 1024(zweiter Wert) hallo ===========²²²² und ganz viele komische Zeichen im Anschluss. zu guter Letzt kommt ein Debug- Fehler



  • Hallo,

    ich bekomme irgendwie es nicht hin nach der Versendung über TCP, dass packet wieder auszulesen. Bin irgendwie fürs programmieren nicht geeignet bzw der Umstieg von Java auf C++ war doch nicht so.



  • Die Komplettlösung für die Allgemeinheit:

    #include <string> 
    #include <cstring> 
    #include <cassert> 
    #include <cstdint> 
    
    typedef std::string Buffer; 
    
    struct BinaryWriter 
    { 
      Buffer &buffer; 
    
      explicit BinaryWriter(Buffer &buffer) 
        : buffer(buffer) 
      { 
      } 
    
      void write(const char *data, size_t size) 
      { 
        buffer.append(data, data + size); 
      } 
    
      void overwrite(size_t position, const char *data, size_t size) 
      { 
        assert(position + size <= buffer.size()); 
        std::memcpy(&buffer[position], data, size); 
      } 
    
      template <class POD> 
      void write(POD value) 
      { 
        write(reinterpret_cast<const char *>(&value), sizeof(value)); 
      } 
    
      template <class POD> 
      void overwrite(size_t position, POD value) 
      { 
        overwrite(position, reinterpret_cast<const char *>(&value), sizeof(value)); 
      } 
    
      void writeString32(const std::string &str) 
      { 
        write(static_cast<std::uint32_t>(str.size())); 
        write(str.data(), str.size()); 
      } 
    };
    
    struct PacketWriter : BinaryWriter 
    { 
      size_t sizePosition; 
      size_t payloadPosition; 
    
      PacketWriter(Buffer &buffer, std::uint32_t id, std::uint32_t time) 
        : BinaryWriter(buffer) 
      { 
        write(id); 
        write(time); 
    
        //die Position der Länge für spätere Korrektur speichern 
        sizePosition = buffer.size(); 
        write(std::uint32_t(0)); 
    
        //um die Länge des Inhaltes auszurechnen 
        payloadPosition = buffer.size(); 
      } 
    
      void finish() 
      { 
        size_t currentPos = buffer.size(); 
        std::uint32_t length = static_cast<std::uint32_t>(currentPos - payloadPosition); 
    
        overwrite(sizePosition, length); 
      } 
    };
    
    struct BinaryReader
    {
      const char *begin, *pos, *end;
    
      BinaryReader()
        : begin(0)
        , pos(0)
        , end(0)
      {
      }
    
      BinaryReader(const char *begin, const char *end)
        : begin(begin)
        , pos(begin)
        , end(end)
      {
      }
    
      size_t remaining() const
      {
        return (end - pos);
      }
    
      bool read(char *dest, size_t size)
      {
        if (size > remaining())
        {
          return false;
        }
    
        std::memcpy(dest, pos, size);
        pos += size;
        return true;
      }
    
      template <class POD>
      bool read(POD &value)
      {
        return read(reinterpret_cast<char *>(&value), sizeof(value));
      }
    
      bool readString32(std::string &dest)
      {
        std::uint32_t length;
        if (read(length))
        {
          dest.resize(length);
          if (length)
          {
            return read(&dest[0], length);
          }
    
          return true;
        }
    
        return false;
      }
    };
    
    struct PacketReader : BinaryReader
    {
      std::uint32_t id, time;
      BinaryReader body;
    
      PacketReader(const char *begin, const char *end)
        : BinaryReader(begin, end)
      {
      }
    
      bool parseHeader()
      {
        std::uint32_t length;
    
        if (
          read(id) &&
          read(time) &&
          read(length) &&
          (remaining() >= length))
        {
          body.begin = body.pos = this->pos;
          body.end = body.begin + length;
    
          //Inhalt überspringen
          this->pos += length;
          return true;
        }
    
        return false;
      }
    };
    
    #include <iostream>
    using namespace std;
    
    int main() 
    { 
      Buffer packet; 
    
      {
        PacketWriter writer(packet, 123, 456); 
    
        std::string message = "hallo"; 
        writer.writeString32(message); 
        writer.write<std::uint16_t>(42); //ja, hier können beliebige weitere Werte folgen
    
        writer.finish();
    
        //packet kann nun versendet werden.. 
      }
    
      //empfangen..
      {
        PacketReader reader(&packet[0], &packet[0] + packet.size());
        if (!reader.parseHeader())
        {
          //nach dem nächsten receive nochmal versuchen..
          cout << "Incomplete packet" << endl;
          return 1;
        }
    
        std::string message;
        reader.body.readString32(message); //Ergebnis ggf. prüfen
    
        cout << message << endl;
    
        std::uint16_t value;
        reader.body.read(value);
    
        cout << value << endl;
    
        //das gelesene Paket aus dem Puffer entfernen.
        //clear() ist ungeeignet, denn es können weitere Pakete im Puffer liegen.
        const size_t parsed = (reader.pos - reader.begin);
        packet.erase(
          packet.begin(),
          packet.begin() + parsed);
      }
    }
    

Anmelden zum Antworten