<?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[Zeilenorientierter Datenempfang über Sockets]]></title><description><![CDATA[<p>Hallo, ich habe ein Problem bei der Nachrichtenübertragung über Sockets. Folgend der Source für senden un empfangen der Daten.</p>
<p>Bei kleinen Datenmengen funktiooniert alles prächtig. Aber wenn man viel auf einmal oder knapp hintereinander Daten schickt, gibt es ein Problem beim Empfangen der Daten.</p>
<p>Scheinbar sind mehrere Nachrichten im Empfangbuffer und es wird nach der letzten Terminierung gesucht. Wenn ich jedoch nach der ersten suchen würde, lösche ich den rest dahinter wieder.</p>
<p>Wechlchen ansatz kann man hier verfolgen um mit dem Aufruf der empfangsfunktion immer nur eine Nachricht zu empfangen?</p>
<p><strong>Senden:</strong></p>
<pre><code>while(1)
	{
		string msg = client.message_List.get();
		if (msg == &quot;CLOSE&quot;)
		{
			return 0;
		}
		msg += &quot;\n&quot;;
		int iResult = send(client.socket, msg.c_str(), msg.length(), 0);
		if (iResult == SOCKET_ERROR)
		{
			return 0;
		}
		cout &lt;&lt; iResult &lt;&lt; &quot;\n&quot;;
	}
	return 0;
</code></pre>
<p><strong>Empfangen:</strong></p>
<pre><code>string msg, strBuffer;
	int lastChar;

	do {
		int iResult = recv(client.socket, client.rcv_buffer, IO_BUFFSIZE, 0);
		if( iResult &gt; 0)
		{
			for(int i=0; i &lt; iResult; i++)
			{
				strBuffer += client.rcv_buffer[i];
			}
			lastChar = strBuffer.find_last_of(&quot;\n&quot;);
			if(lastChar &gt; -1)
			{
				strBuffer.erase(lastChar);
				msg += strBuffer;
			}
			else
			{				
				msg += strBuffer;
			}
		}
		else if (iResult == 0)
		{
			return &quot;CLOSE&quot;;
		}
		else
		{
			return &quot;ERROR&quot;;
		}
	} while(lastChar &lt; 0);
	return msg;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/322090/zeilenorientierter-datenempfang-über-sockets</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Jul 2026 08:07:52 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/322090.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 06 Dec 2013 08:14:06 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Fri, 06 Dec 2013 08:14:06 GMT]]></title><description><![CDATA[<p>Hallo, ich habe ein Problem bei der Nachrichtenübertragung über Sockets. Folgend der Source für senden un empfangen der Daten.</p>
<p>Bei kleinen Datenmengen funktiooniert alles prächtig. Aber wenn man viel auf einmal oder knapp hintereinander Daten schickt, gibt es ein Problem beim Empfangen der Daten.</p>
<p>Scheinbar sind mehrere Nachrichten im Empfangbuffer und es wird nach der letzten Terminierung gesucht. Wenn ich jedoch nach der ersten suchen würde, lösche ich den rest dahinter wieder.</p>
<p>Wechlchen ansatz kann man hier verfolgen um mit dem Aufruf der empfangsfunktion immer nur eine Nachricht zu empfangen?</p>
<p><strong>Senden:</strong></p>
<pre><code>while(1)
	{
		string msg = client.message_List.get();
		if (msg == &quot;CLOSE&quot;)
		{
			return 0;
		}
		msg += &quot;\n&quot;;
		int iResult = send(client.socket, msg.c_str(), msg.length(), 0);
		if (iResult == SOCKET_ERROR)
		{
			return 0;
		}
		cout &lt;&lt; iResult &lt;&lt; &quot;\n&quot;;
	}
	return 0;
</code></pre>
<p><strong>Empfangen:</strong></p>
<pre><code>string msg, strBuffer;
	int lastChar;

	do {
		int iResult = recv(client.socket, client.rcv_buffer, IO_BUFFSIZE, 0);
		if( iResult &gt; 0)
		{
			for(int i=0; i &lt; iResult; i++)
			{
				strBuffer += client.rcv_buffer[i];
			}
			lastChar = strBuffer.find_last_of(&quot;\n&quot;);
			if(lastChar &gt; -1)
			{
				strBuffer.erase(lastChar);
				msg += strBuffer;
			}
			else
			{				
				msg += strBuffer;
			}
		}
		else if (iResult == 0)
		{
			return &quot;CLOSE&quot;;
		}
		else
		{
			return &quot;ERROR&quot;;
		}
	} while(lastChar &lt; 0);
	return msg;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2370126</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370126</guid><dc:creator><![CDATA[Daddaaff]]></dc:creator><pubDate>Fri, 06 Dec 2013 08:14:06 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Fri, 06 Dec 2013 09:43:11 GMT]]></title><description><![CDATA[<p>Daddaaff schrieb:</p>
<blockquote>
<p>Wechlchen ansatz kann man hier verfolgen um mit dem Aufruf der empfangsfunktion immer nur eine Nachricht zu empfangen?</p>
</blockquote>
<p>Du kannst <code>recv()</code> immer mit einem 1-Byte Puffer aufrufen - was aber nicht sehr effizient ist.</p>
<p>Wieso nicht sowas in der Art</p>
<pre><code class="language-cpp">Message Foo::ReceiveMessage()
{
    while (m_receivedMessages.empty())
        ReceiveChunk();

    Message const m = m_receivedMessages.front();
    m_receivedMessages.pop_front();
    return m;
}
</code></pre>
<p><code>ReceiveChunk</code> muss dabei natürlich sämtliche in einem Rutsch empfangene Nachrichten in <code>m_receivedMessages</code> einfügen, nicht immer nur eine.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2370151</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370151</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 06 Dec 2013 09:43:11 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Sat, 07 Dec 2013 10:57:42 GMT]]></title><description><![CDATA[<p>Nach einiger Zeit hab hab folgendes daraus gemacht.</p>
<p>Zusätzlich verwende ich Base64, um zu verhindern, dass in den Daten vorhandene &quot;\n&quot; Probleme bereiten.</p>
<p><strong>Senden</strong></p>
<pre><code>while(1)
	{
		string msg = client.message_List.get();
		if (msg == &quot;CLOSE&quot;)
		{
			return 0;
		}
		const unsigned char * constStr = reinterpret_cast&lt;const unsigned char *&gt; (msg.c_str());
		msg = base64_encode(constStr, msg.size());
		msg += &quot;\n&quot;;
		int iResult = send(client.socket, msg.c_str(), msg.length(), 0);
		if (iResult == SOCKET_ERROR)
		{
			return 0;
		}
	}
	return 0;
</code></pre>
<p><strong>Empfangen</strong></p>
<pre><code>string msg, strBuffer;
	int lastChar, firstChar;

	if(client.rcv_rest_lenght != 0) {
		for(int i=0; i &lt; client.rcv_rest_lenght; i++)
		{
			strBuffer += client.rcv_rest[i];
		}
		client.rcv_rest_lenght = 0;

		firstChar = strBuffer.find_first_of(&quot;\n&quot;);
		if(firstChar &gt; -1)
		{		
			int test = (int)strBuffer.length();
			if(firstChar != (int)strBuffer.length() - 1)
			{
				for(int i=firstChar + 1; i &lt; (int)strBuffer.length(); i++)
				{
					client.rcv_rest[i - firstChar - 1]  = client.rcv_rest[i];
					client.rcv_rest_lenght++;
				}
				strBuffer.erase(firstChar);

				msg += strBuffer;

				string decoded_msg = base64_decode(msg);

				return  decoded_msg;	
			}
			else
			{
				strBuffer.erase(firstChar);

				msg += strBuffer;

				string decoded_msg = base64_decode(msg);

				return  decoded_msg;
			}
		}
		else
			msg += strBuffer;
		}
	}

	do {
		int iResult = recv(client.socket, client.rcv_buffer, IO_BUFFSIZE, 0);
		if( iResult &gt; 1)
		{
			for(int i=0; i &lt; iResult; i++)
			{
				strBuffer += client.rcv_buffer[i];
			}
			firstChar = strBuffer.find_first_of(&quot;\n&quot;);
			if(firstChar &gt; -1)
			{				
				if(firstChar != iResult - 1)
				{
					for(int i=firstChar + 1; i &lt; (int)strBuffer.length(); i++) 
					{
						client.rcv_rest[i - firstChar - 1]  = client.rcv_buffer[i];
						client.rcv_rest_lenght++;
					}
				}			

				strBuffer.erase(firstChar);

				msg += strBuffer;
			}
			else
			{				
				msg += strBuffer;
			}
		}
		else if (iResult == 0)
		{
			return &quot;CLOSE&quot;;
		}
		else if (iResult == 1)
		{
			return &quot;CLOSE&quot;;
		}
		else
		{
			return &quot;ERROR&quot;;
		}
	} while(firstChar &lt; 0);

	string decoded_msg = base64_decode(msg);

	return  decoded_msg;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2370364</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370364</guid><dc:creator><![CDATA[Daddaaff]]></dc:creator><pubDate>Sat, 07 Dec 2013 10:57:42 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Sat, 07 Dec 2013 15:20:30 GMT]]></title><description><![CDATA[<p>Sorry, aber das mag doch keiner lesen.<br />
Der Code ist grauenhaft.</p>
<p>Und base64 zu verwenden um \n zu vermeiden ist schon etwas krass.</p>
<p>Wenn du dir das Message-Format sowieso selbst aussuchen kannst, wieso machst du dann nicht das was man normalerweise macht, und schickst erst die Länge der Nachricht und danach die Nachricht selbst?</p>
<p>Der Code zum Empfangen einer Nachricht könnte dann so aussehen:</p>
<pre><code class="language-cpp">void Foo::Receive(void* buffer, size_t length)
{
    while (length &gt; 0)
    {
        int const rc = recv(m_socket, buffer, length, 0);
        if (rc &lt;= 0)
        {
            // TODO: Fehlerbehandlung
            throw SomeException(...);
        }
        if (rc &gt; length)
        {
            // TODO: Fehlerbehandlung
            throw SomeException(...);
        }
        length -= rc;
        buffer = reinterpret_cast&lt;char*&gt;(buffer) + rc;
    }
}

size_t Foo::ReceiveSize()
{
    unsigned char buffer[4];
    Receive(&amp;buffer[0], 4);
    return buffer[0]
        + (static_cast&lt;size_t&gt;(buffer[1]) &lt;&lt;  8)
        + (static_cast&lt;size_t&gt;(buffer[2]) &lt;&lt; 16)
        + (static_cast&lt;size_t&gt;(buffer[3]) &lt;&lt; 24);
}

std::string Foo::ReceiveMessage()
{
    // Länge empfangen
    size_t const length = ReceiveSize();
    // Nachricht empfangen
    std::vector buffer(length);
    Receive(&amp;buffer[0], length);
    // Als string zurückgeben
    return std::string(buffer.begin(), buffer.end());
}
</code></pre>
<p>Ist übersichtlicher, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2370404</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370404</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 07 Dec 2013 15:20:30 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Sat, 07 Dec 2013 19:47:43 GMT]]></title><description><![CDATA[<p>Ein selterner Quatsch für sowas base64 zu verwenden.<br />
Das wäre ein Hasch zuviel.</p>
<p>Und byteweise zu lesen ist auch nicht wirklich der Hammer.</p>
<p>Vielleicht liegts auch an dem komischen Wetter daß ihr komische Ideen habt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2370462</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370462</guid><dc:creator><![CDATA[EOP]]></dc:creator><pubDate>Sat, 07 Dec 2013 19:47:43 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Sun, 08 Dec 2013 01:07:19 GMT]]></title><description><![CDATA[<p>lollig. hustbaer sagt das 1 byte pro call zu recv'en wäre ineffizient, aber baut selbst einen code der gerade mal 3 bytes mehr empfängt</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2370488</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370488</guid><dc:creator><![CDATA[i]]></dc:creator><pubDate>Sun, 08 Dec 2013 01:07:19 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Sun, 08 Dec 2013 04:05:27 GMT]]></title><description><![CDATA[<p>i schrieb:</p>
<blockquote>
<p>lollig. hustbaer sagt das 1 byte pro call zu recv'en wäre ineffizient, aber baut selbst einen code der gerade mal 3 bytes mehr empfängt</p>
</blockquote>
<p>Hehe, wenn Foo:: zu Bar:: wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2370495</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370495</guid><dc:creator><![CDATA[EOP]]></dc:creator><pubDate>Sun, 08 Dec 2013 04:05:27 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Sun, 08 Dec 2013 05:23:01 GMT]]></title><description><![CDATA[<p>i schrieb:</p>
<blockquote>
<p>lollig. hustbaer sagt das 1 byte pro call zu recv'en wäre ineffizient, aber baut selbst einen code der gerade mal 3 bytes mehr empfängt</p>
</blockquote>
<p>Er macht es aber nur einmal pro Line.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2370498</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370498</guid><dc:creator><![CDATA[theliquidwave]]></dc:creator><pubDate>Sun, 08 Dec 2013 05:23:01 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Mon, 09 Dec 2013 10:06:28 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13960">@hustbaer</a><br />
Wann kann denn Zeile 11 true werden?</p>
<p>Besser ist mMn folgender Ansatz:</p>
<ol>
<li>lies alles, was im Puffer ist, und hänge es an einen Lesepuffer an</li>
<li>stehen genügend Daten für den Telegrammkopf im Lesepuffer?<br />
nein: fertig</li>
<li>lies den Telegrammkopf aus dem Lesepuffer und bestimme die Telegrammlänge</li>
<li>stehen genügend Daten für das Telegramm im Lesepuffer?<br />
nein: fertig</li>
<li>lies das Telegramm aus dem Lesepuffer</li>
<li>entferne die Telegrammdaten aus dem Lesepuffer</li>
<li>behandle das Telegramm</li>
<li>zurück zu 2</li>
</ol>
]]></description><link>https://www.c-plusplus.net/forum/post/2370680</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370680</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Mon, 09 Dec 2013 10:06:28 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Mon, 09 Dec 2013 12:00:10 GMT]]></title><description><![CDATA[<p>DocShoe schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/13960">@hustbaer</a><br />
Wann kann denn Zeile 11 true werden?</p>
</blockquote>
<p>Wenn das OS Blödsinn zurückgibt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<blockquote>
<p>Besser ist mMn folgender Ansatz:</p>
</blockquote>
<p>Besser ist relativ.<br />
Du siehst ja was der OP für Code schreibt.<br />
Ich denke da ist erstmal das besser was einfacher umzusetzen ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2370716</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370716</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 09 Dec 2013 12:00:10 GMT</pubDate></item><item><title><![CDATA[Reply to Zeilenorientierter Datenempfang über Sockets on Mon, 09 Dec 2013 21:54:40 GMT]]></title><description><![CDATA[<p>Eingabe und Ausgabe in C++ funktioniert über Streams und Streambufs (weiß aber keiner <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> )<br />
Das vereinfacht die Sache hier ziemlich - Erst der Streambuf:</p>
<pre><code>class ISocketStreambuf : public std::streambuf
{
public:
    ISocketStreambuf( /* ipc oder was auch immer */ )
        : socket( /* connect? */ )
    {}
protected:
    virtual int_type underflow()
    {
        int iResult = recv( socket, rcv_buffer, IO_BUFFSIZE, 0 );
        if( iResult &gt; 0 )
        {
            setg( rcv_buffer, rcv_buffer, rcv_buffer + iResult );
            return traits_type::t_int_type( *rcv_buffer );
        }
        else
            ; // Fehlerbehandlung
        return traits_type::eof(); // oder Exception
    }
private:
    /* implementation detail */ socket;
    char rcv_buffer[IO_BUFFSIZE];
};
</code></pre>
<p>und dann die Anwendung</p>
<pre><code>ISocketStreambuf socket_sb( /* ... */ );
    istream in( &amp;socket_sb );
    for( string zeile; getline( in, zeile ); ) // Zeilenweises Einlesen, wenn's sein muss
        cout &lt;&lt; zeile &lt;&lt; endl;
</code></pre>
<p>.. setzt natürlich 'lesbare' Daten voraus. Falls reiner Binärcode daherkommt, kann man sich aber ggf. mit einem <a href="http://www.c-plusplus.net/forum/p2142354#2142354" rel="nofollow">entsprechenden Stream</a> behelfen. Der Streambuf bleibt davon unangetastet. Siehe auch das Beispiel <a href="http://www.c-plusplus.net/forum/p2318739#2318739" rel="nofollow">hier</a>.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2370854</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2370854</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Mon, 09 Dec 2013 21:54:40 GMT</pubDate></item></channel></rss>