<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Netzwerkproblem - Klassen gegen Buffer]]></title><description><![CDATA[<p>Hi,</p>
<p>ich möchte ein Multiplayer-Spiel schreiben. Es müssen verschiedene Arten von Daten ausgetauscht werden: Spieler-Positionen, Abfeuern von Raketen, etc. (könnte man enummerieren).</p>
<p>Nun habe ich verschiedene Möglichkeiten:</p>
<p>1.) Ich schreibe eine Klasse, die einen großen char-Buffer enthält. Wenn ich Daten verschicken will sagt das erste Byte des Buffers, wie die restlichen Bytes zu interpretieren sind. Das Herüberkopieren könnte man mit casts oder memcpy() realisieren. Das ganz ist aber durch das Kopieren ein bischen langsamer, außerdem nicht ganz Typsicher und sieht zudem blöd aus. Und das ganze memcpy()-Geschreibe wird auch ziemlich nervtötend...</p>
<p>2.) Ich habe eine struct für ein Paket:</p>
<pre><code class="language-cpp">struct packet
{
    int type;
    union ...
} __ attribute__((packet));
</code></pre>
<p>Ist im alten C-Style... das empfangen ginge dann in etwa so:</p>
<pre><code class="language-cpp">Packet p;
send(&amp;p,/*...*/);
</code></pre>
<p>Also recht komfortabel</p>
<p>3.) Kann man so etwas auch mit Klassen machen? Z.B. so?</p>
<pre><code class="language-cpp">class PacketBase
{
    virtual void get_type() = 0;
};

class PositionPacket : public PacketBase
{
    virtual void get_type() { return POSITION_PACKET; }
    vector Position;
};

PositionPacket p;
send(&amp;p,/* ... */);
</code></pre>
<p>Das Problem ist ja, wenn ich direkt aus der Klasse lese (kann eine Klasse das Attribut packed haben?), können da ja immer noch Daten drin sein, die ich vllt gar nicht senden will (die virtual pointer table und wer weiß was)...</p>
<p>Welche Möglichkeit ist am ehesten ratsam/realisierbar? Gibt es andere gute Möglichkeiten?</p>
<p>Gruß,<br />
voidpointer</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/217573/netzwerkproblem-klassen-gegen-buffer</link><generator>RSS for Node</generator><lastBuildDate>Sat, 10 Oct 2026 08:48:50 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/217573.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 08 Jul 2008 20:17:04 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Netzwerkproblem - Klassen gegen Buffer on Tue, 08 Jul 2008 20:17:04 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich möchte ein Multiplayer-Spiel schreiben. Es müssen verschiedene Arten von Daten ausgetauscht werden: Spieler-Positionen, Abfeuern von Raketen, etc. (könnte man enummerieren).</p>
<p>Nun habe ich verschiedene Möglichkeiten:</p>
<p>1.) Ich schreibe eine Klasse, die einen großen char-Buffer enthält. Wenn ich Daten verschicken will sagt das erste Byte des Buffers, wie die restlichen Bytes zu interpretieren sind. Das Herüberkopieren könnte man mit casts oder memcpy() realisieren. Das ganz ist aber durch das Kopieren ein bischen langsamer, außerdem nicht ganz Typsicher und sieht zudem blöd aus. Und das ganze memcpy()-Geschreibe wird auch ziemlich nervtötend...</p>
<p>2.) Ich habe eine struct für ein Paket:</p>
<pre><code class="language-cpp">struct packet
{
    int type;
    union ...
} __ attribute__((packet));
</code></pre>
<p>Ist im alten C-Style... das empfangen ginge dann in etwa so:</p>
<pre><code class="language-cpp">Packet p;
send(&amp;p,/*...*/);
</code></pre>
<p>Also recht komfortabel</p>
<p>3.) Kann man so etwas auch mit Klassen machen? Z.B. so?</p>
<pre><code class="language-cpp">class PacketBase
{
    virtual void get_type() = 0;
};

class PositionPacket : public PacketBase
{
    virtual void get_type() { return POSITION_PACKET; }
    vector Position;
};

PositionPacket p;
send(&amp;p,/* ... */);
</code></pre>
<p>Das Problem ist ja, wenn ich direkt aus der Klasse lese (kann eine Klasse das Attribut packed haben?), können da ja immer noch Daten drin sein, die ich vllt gar nicht senden will (die virtual pointer table und wer weiß was)...</p>
<p>Welche Möglichkeit ist am ehesten ratsam/realisierbar? Gibt es andere gute Möglichkeiten?</p>
<p>Gruß,<br />
voidpointer</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1543773</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1543773</guid><dc:creator><![CDATA[voidpointer]]></dc:creator><pubDate>Tue, 08 Jul 2008 20:17:04 GMT</pubDate></item><item><title><![CDATA[Reply to Netzwerkproblem - Klassen gegen Buffer on Tue, 08 Jul 2008 21:29:51 GMT]]></title><description><![CDATA[<p>Also ich würde mir ein Protokoll ausdenken - und die Daten nicht binär rüberschicken...</p>
<p>So weit ich weiß, wird das auch (immer ?) so gemacht...</p>
<pre><code>POSPL x y -END- //POSitionen d. Spielers (PLayer)
FIRER x_from y_from x_to y_to zeit -END- //Abfeuern (FIRE) von Raketen (Rocket)
</code></pre>
<p>hätte den Nachteil, dass du die ints etc immer erst in strings, dann gibts aber auch noch so ne Möglichkeit:</p>
<pre><code>POSPL 10 //länge des Datenblocks
{binärdaten, genau 10 Byte}
x,
y
</code></pre>
<p>alternativ kannst du statt den Strings am Anfang auch deine Nummer nehmen, aber das wird irgendwann vll doch ein wenig unübersichtlich...</p>
<p>Ich würd halt Klassen für das jeweilige Ereignis machen und dann das Empfangen mithilfe eines Vectors machen, bsp.:</p>
<pre><code class="language-cpp">class Tnetwork_base
{
public:
virtual ~Tnetwork_base ();
// vll &lt;&lt; und &gt;&gt; als virtual deklarieren und die dann zum basteln und auslesen der Klasse nehmen, wenn sie empfangen wird... kA
};

class Trocket : Tnetwork_base
{
//...
};

std::vector &lt;Tnetwork_base *&gt; recv_data;

typedef char byte; //kannst auch char nehmen - die meisten compiler kennen ja auch byte...

void OnRecv (byte *recv_bytes)
{
 const size_t L (static_cast &lt;size_t&gt; (strlen (recv_bytes)));
 if ((L &gt; 5) &amp;&amp; (!_mbsncmp (recv_bytes, &quot;FIRER&quot;, 5))
  {
   //klasse aus den daten aufbauen und in den vector hauen;
  }
 else if (/*next*/)
{/*usw*/}
}
</code></pre>
<p>Das Senden hierzu würde analog gehen - also in etwa so:</p>
<pre><code class="language-cpp">std::vector &lt;Tnetwork_base *&gt; send_data;

void OnFireRocket (size_t dmg, const TPoint &amp;where_from, const TPoint &amp;where_to)
{
send_data.push_back (new Trocket (/*wie au immer*/) );
}
</code></pre>
<p>und dann kannste ja nen send-template bauen:</p>
<pre><code class="language-cpp">template &lt;class T&gt;
bool /*successful*/ send_data (const T &amp;value) throw (...)
{
throw std::bad_typeid (&quot;noch nicht gebaut...&quot;);
}

template &lt; &gt;
bool send_data &lt;Trocket&gt; (const Trocket &amp;value)
{
std::string tosend;
value &gt;&gt; tosend;
send /*API-fkt*/ (tosend.c_str ());
}
</code></pre>
<p>wobei mir gerade einfällt: std::deque wär wohl besser gewesen ^^ außerdem solltest du vll noch ne Wrapper funktion fürs push_back schreiben, damit irgendwo nen event ausgelöst wird, damit du nicht aller x sekunden gucken musst, ob was in der que (des vectors o.ä.) ist...</p>
<p>Hier hast du zwar auch immer x umwandlungen dabei aber ich denke, es sollte sich trotzdem nicht soo sehr bemerkbar machen und ist übersichtlich...</p>
<p>Also ich würds so machen, aber ist auch nur nen Vorschlag...</p>
<p>Und davon würd ich dir auf jeden Fall abraten:</p>
<blockquote>
<pre><code class="language-cpp">struct packet
{
    int type;
    union ...
} __ attribute__((packet));
</code></pre>
</blockquote>
<p>Mal davon abgesehen, dass es mit Sicherheit sehr fehleranfällig ist: Überleg mal, wie groß (vll nicht unbedingt vom speicher, weil da kann man ja ptr nehmen aber vom Code her) das ganze wird, wenn du genügend Dinge einbaust, chat, 7 versch. raketentypen und 12 versch. abfeuerungsarten, einheiten, rohstoffe, chat, bilder, ...<br />
Glaube nicht, dass du dann noch durchsiehst - abgesehen davon würd ich unions nur nehmen, wenn man sie unbedingt braucht - und das ist in meinen Augen nen klasse Bsp für templates...</p>
<p>bb - und ich hoffe, ich hab deine Frage wenigstens ansatzweise verstanden ^^</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1543816</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1543816</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Tue, 08 Jul 2008 21:29:51 GMT</pubDate></item><item><title><![CDATA[Reply to Netzwerkproblem - Klassen gegen Buffer on Wed, 09 Jul 2008 00:14:10 GMT]]></title><description><![CDATA[<p>Was ist denn so schlimm daran,eine Struct/Class mit den nötigen informationen zu versenden?<br />
Ich finde das ist wesentlich einfacher als einen string zu senden,der dann vom client erstmal geparst werden muss etc.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1543854</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1543854</guid><dc:creator><![CDATA[emanreztuneB]]></dc:creator><pubDate>Wed, 09 Jul 2008 00:14:10 GMT</pubDate></item><item><title><![CDATA[Reply to Netzwerkproblem - Klassen gegen Buffer on Wed, 09 Jul 2008 00:31:58 GMT]]></title><description><![CDATA[<p>emanreztuneB schrieb:</p>
<blockquote>
<p>Was ist denn so schlimm daran,eine Struct/Class mit den nötigen informationen zu versenden?<br />
Ich finde das ist wesentlich einfacher als einen string zu senden,der dann vom client erstmal geparst werden muss etc.</p>
</blockquote>
<p>spätestens mit dem ersten dynamischen speicher geht das nicht mehr. mit der methode des OPs ist man im grunde auf PODs beschränkt.</p>
<p>und im schlimmsten fall funktioniert nicht einmal das verschicken eines floats/doubles.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1543855</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1543855</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Wed, 09 Jul 2008 00:31:58 GMT</pubDate></item><item><title><![CDATA[Reply to Netzwerkproblem - Klassen gegen Buffer on Wed, 09 Jul 2008 02:12:09 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/17023">@voidpointer</a>:<br />
Was du suchst ist Serialisierung. Guck mal in se mighty Internetz, da findet man viel zu dem Thema.</p>
<p>Und änder mal deine Signatur, &quot;static_cast&lt;static void*&gt;&quot; is Blödsinn <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1543866</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1543866</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 09 Jul 2008 02:12:09 GMT</pubDate></item><item><title><![CDATA[Reply to Netzwerkproblem - Klassen gegen Buffer on Wed, 09 Jul 2008 06:32:20 GMT]]></title><description><![CDATA[<p>emanreztuneB schrieb:</p>
<blockquote>
<p>Was ist denn so schlimm daran,eine Struct/Class mit den nötigen informationen zu versenden?<br />
Ich finde das ist wesentlich einfacher als einen string zu senden,der dann vom client erstmal geparst werden muss etc.</p>
</blockquote>
<p>Guck Dir auch mal das hier an:<br />
<a href="http://en.wikipedia.org/wiki/Endianness" rel="nofollow">Endianess</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1543908</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1543908</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Wed, 09 Jul 2008 06:32:20 GMT</pubDate></item><item><title><![CDATA[Reply to Netzwerkproblem - Klassen gegen Buffer on Thu, 10 Jul 2008 14:46:36 GMT]]></title><description><![CDATA[<p>Oha also scheint die Idee mit der Umwandlung in eine Byte-Folge ja doch das einzig Sinnvolle, wenn man die Byte-Reihenfolge beachtet! Danke für die vielen Tipps und Beispiele... Ich werde mich nun erstmal schlau machen bezüglich Serialization...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1545148</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1545148</guid><dc:creator><![CDATA[voidpointer]]></dc:creator><pubDate>Thu, 10 Jul 2008 14:46:36 GMT</pubDate></item></channel></rss>