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); } }