Netzwerk: Eigenes "Protokoll" erstellen - wie?
-
Hallo.
Ich habe mal einige Fragen zur Netzwerkprogrammierung.1.) Wie groß dürfen die Daten eines "Bytes" sein? Ich weiß die Frage hört sich ziemlich doof an, aber da bin ich mir recht unsicher. Der Prototyp meiner SendBuf-Funktion sieht so aus: (von hier)
void SendBuf(const char *buf,size_t len,int f = 0);Heißt das nun, dass ich nur Integer senden kann, die größer als 0 und kleiner als 255 sind? (Es geht um TCP falls das wichtig ist)
2.) Wenn meine Annahme stimmt - wie erstelle ich daraus ein vernünftiges Protokoll?
Meine erste Idee war ein paar Konstanten zu setzen (auf dem Client und auf dem Server gleich). Beispiel:enum Flags_t { FlagStartFlag = 1 << 0, FlagRequestAuth = 1 << 1, FlagRequestInfo = 1 << 2, FlagSendAuth = 1 << 3, FlagSendInfo = 1 << 4 };Dann sendet halt je nach dem der Client und/oder der Server die Flag und wartet auf eine Antwort die eine vorgegebene Struktur hat. Beispiel:
const char testBytes[] = { FlagStartFlag, FlagRequestAuth }; SendBuf(testBytes, sizeof(testBytes)); //... void OnRawData(const char *pBuffer, size_t iLength) { if (iLength >= 2) { if (pBuffer[0] == FlagStartFlag) { switch (pBuffer[1]) { case FlagRequestAuth: //Daten senden break; //... } } }3.) Ist meine Idee so richtig? Oder falsch? Oder nur nicht ganz optimal? Wie sieht da eigentlich aus mit Unverwechselbarkeit? Was ist, wenn zufällig eine Chatnachricht mit 01 anfängt? Dann würde FlagStartFlag und FlagRequestAuth ja auch "matchen". Wie kann ich so etwas vermeiden?
Gruß
-
Heißt das nun, dass ich nur Integer senden kann, die größer als 0 und kleiner als 255 sind? (Es geht um TCP falls das wichtig ist)
Du kannst z.b.
char bytestream[100];
int i = 5000;snprintf(bytestream, 100, "%d", i);
send(bytestream);verwenden.
-
"const char *buf" ist nur ein Platzhalter für den Beginn eines Feldes im Speicher, welches nichts mit dem Typ char zu tun hat. Die Länge des Feldes gibst du in deinem "len" Parameter in Byte an. Ein Integer hat beispielsweise auf der x86 Architektur (umgangssprachlich 32-bit Architektur) 4 Byte länge.
Einen Integer könntest du also beispielsweise überint i = 42; SendBuf( (char*)&i, sizeof(int) );senden. (was der Parameter f soll weis ich nicht)
Man könnte auch "const void *buf" schreiben, allerdings nimmt man vermute ich mal char damit deutlich ist dass "len" in Byte gemessen wird (sizeof(char) ist ja = 1).Was ist, wenn zufällig eine Chatnachricht mit 01 anfängt
Als Beispiel könntest du immer das erste Byte deiner Nachricht dem Zweck der Nachricht zuordnen. Zum einfacheren Debuggen nimmst du am besten ASCII Zeichen, du könntest zum Beispiel 'N' einer normalen Nachricht zuordnen, oder mit 'F' signalisieren dass du Flags auswerten willst. Also eine normale Nachricht "Hallo, wie gehts?" würde dann intern zu "AHallo, wie gehts?" werden. Der auswertende (Server?) Part liest dann das erste Byte der Nachricht ein, und weiß wie er den Rest der Nachricht zu behandeln hat.
-
Hi.
Danke!
Dazu habe ich mal eine Frage. Und zwar benutze ich eine Pack-Funktion damit das ganze portabel bleibt. Diese benötigt jedoch einenunsigned char*Buffer, dieSendBuf-Funktion nimmt aber nur einenchar*Buffer an. Heißt das, ich kann mit demlen-Parameter das ganze "steuern"?Beispiel:
unsigned char myData[128] = { '\0' }; //packen //size_t size = pack(...); SendBuf((const char*)myData, sizeof(unsigned char) * size);Gruß
-
Warum als Puffer nicht ein std::string oder std::vector<char>?
#include <sstream> //... std::ostringstream dataStream(std::ios::binary); //binary ist wichtig! dataStream.write(daten, sizeof(daten)); //was auch immer "daten" ist dataStream.write(daten2, sizeof(daten2)); //was auch immer "daten2" ist MeineNetzwerkKlasse.SendBuffer(dataStream.str()); // Die Länge des Puffers steckt // im std::string, der durch // str() erzeugt wird //... //Fertig, ich habe keine Sorgen wegen Speicher feigeben etc.. :-)
-
theliquidwave schrieb:
Hi.
Danke!
Dazu habe ich mal eine Frage. Und zwar benutze ich eine Pack-Funktion damit das ganze portabel bleibt. Diese benötigt jedoch einenunsigned char*Buffer, dieSendBuf-Funktion nimmt aber nur einenchar*Buffer an. Heißt das, ich kann mit demlen-Parameter das ganze "steuern"?Beispiel:
unsigned char myData[128] = { '\0' }; //packen //size_t size = pack(...); SendBuf((const char*)myData, sizeof(unsigned char) * size);Gruß
Was du deiner Sende-Funktion reingibst ist an sich egal, du kannst meinetwegen auch "unsigned char*" in "char*" casten das sollte nichts ändern. Wichtig ist nur wie du auf der Empfangsseite deine empfangenen Daten interpretierst, eben entweder als "unsigned char" oder als normaler "char"
-
Stimmt.
Man, Netzwerkprogrammierung ist doch ein wenig umfangreicher als ich dachte.
Bis jetzt funktioniert alles wie gewollt.Danke an alle!
Gruß