<?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[Boost.Thread &amp;amp; Winsock -&amp;gt; Programmabsturz]]></title><description><![CDATA[<p>Ich versuche mich gerade an einem kleinen IRC Client, der gleichzeitig senden und empfangen soll. Stellt es euch vor wie im Sinne von mIRC. Als grobe Anleitung hat mir folgendes Tutorial gedient: <a href="http://www.tutorials.de/forum/c-c-tutorials/213492-irc-client-mit-hilfe-von-windows-sockets-programmieren.html" rel="nofollow">Tutorials.de/.../</a><br />
Wenn ich einfach das ganze Threading Zeugs rauslasse, funktioniert das Programm, doch wenn ich versuche mittels der Boost Bibliothek dem Programm Threads einzuhauchen, stürzt es wundersamer Weise (liegt wohl eher an meinem Laienwissen) ab.<br />
Die Dokumentation von Boost.Thread ist meiner Meinung nach auch nicht die beste...</p>
<p>Auf jeden Fall habe ich in meinem Programm 2 &quot;Endlosschleifen&quot;, eine zum Empfangen, die andere zum Senden von Daten an einen beliebigen IRC-Server. Dafür wollte ich 2 Threads gebrauchen. Und da mir Boost so gut gefällt, dacht ich, ich probiere es damit.</p>
<p>Hier mal der Source von der main.cpp:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
#include &quot;irc.hpp&quot;

// globals
bool runThread = true;
boost::mutex mMutex;

// protos
void recvProc(Jeix::IRC::Server&amp;);

int main()
{
	std::cout &lt;&lt; &quot;Jeix::IRC::Server test\n&quot;;
	try
	{
		Jeix::IRC::Server seilen;
		boost::thread recvThread(boost::bind(&amp;recvProc, boost::ref&lt;Jeix::IRC::Server&gt;(seilen)));

		seilen.Connect(&quot;irc.seilen.de&quot;, 6667);
		seilen.Login(&quot;diggllet&quot;, &quot;myhost&quot;, &quot;irc.seilen.org&quot;, &quot;max fischer&quot;);

		char input[1024];
		::std::string strInput;
		while(1)
		{
			std::cin.getline(input, 1024);
			strInput = input;
			if(!strInput.compare(&quot;/exit&quot;))
			{
				boost::unique_lock&lt;boost::mutex&gt; lock(mMutex);
				runThread = false;
				break;
			}
			strInput += &quot;\r\n&quot;;

			seilen.Send(strInput);
		} // while

		recvThread.join();
	}
	catch(std::string&amp; ex)
	{
		std::cout &lt;&lt; ex &lt;&lt; std::endl;
	}

	//PAUSE;
	std::cin.clear();
	std::cin.ignore();
	std::cin.get();
}

void recvProc(Jeix::IRC::Server&amp; serv)
{
	while(1)
	{
		boost::unique_lock&lt;boost::mutex&gt; lock(mMutex);
		std::cout &lt;&lt; serv.Receive();
		std::cout &lt;&lt; std::endl;

		if(runThread)
		{
			break;
		}
	}
}
</code></pre>
<p>Sorry erstmal für den doch relativ langen Quelltext, doch erschien mir der größte Teil nun doch wichtig.<br />
Hier noch die Implementation der Server.Receive() Methode. Falls ihr noch weiteres wissen wollt bzw. wichtig ist, sagt es bitte einfach.</p>
<pre><code class="language-cpp">::std::string Server::Receive()
	{
		::boost::mutex mTemp;
		::boost::unique_lock&lt;::boost::mutex&gt; lock(mTemp);
		char output[2000]; //declared in srv.hpp
		int countBytes = 0; //	 declared in srv.hpp

		countBytes = recv(sock, output, sizeof(output), 0);
		if (countBytes == SOCKET_ERROR)
		{	// Error
			throw &quot;Error, could not receive response from server!&quot;;
		}
		if (countBytes &gt; 0)
		{
			output[countBytes] = 0;	// recv doesn't put an \0 at the end of the string
			::std::string temp(output);
			return temp;
		}
		return &quot;&quot;;
	}
</code></pre>
<p>Bei der Zeile &quot;if (countBytes == SOCKET_ERROR)&quot; scheint es wohl irgendwie zu haken. Hier ein Screenshot von der Fehlermeldung:<br />
<a href="http://img521.imageshack.us/my.php?image=debugerrpx2.png" rel="nofollow">http://img521.imageshack.us/my.php?image=debugerrpx2.png</a></p>
<p>Ich hab mir das mit dem Boost.Thread größtenteils zusammengeraten, wenn ich ehrlich sein soll, da die Dokumentation in meinen Augen sehr mangelhaft ist und das einzige Beispiel, was ich finden konnte, war von 2002.</p>
<p>Vielleicht hab ich auch schon von Anfang an den falschen Ansatz, ich bin noch nicht so erfahren, danke für eure Hilfe!</p>
<p>MfG issen1</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/224256/boost-thread-amp-winsock-gt-programmabsturz</link><generator>RSS for Node</generator><lastBuildDate>Fri, 02 Oct 2026 18:25:58 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/224256.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 07 Oct 2008 15:22:40 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Boost.Thread &amp;amp; Winsock -&amp;gt; Programmabsturz on Tue, 07 Oct 2008 15:22:40 GMT]]></title><description><![CDATA[<p>Ich versuche mich gerade an einem kleinen IRC Client, der gleichzeitig senden und empfangen soll. Stellt es euch vor wie im Sinne von mIRC. Als grobe Anleitung hat mir folgendes Tutorial gedient: <a href="http://www.tutorials.de/forum/c-c-tutorials/213492-irc-client-mit-hilfe-von-windows-sockets-programmieren.html" rel="nofollow">Tutorials.de/.../</a><br />
Wenn ich einfach das ganze Threading Zeugs rauslasse, funktioniert das Programm, doch wenn ich versuche mittels der Boost Bibliothek dem Programm Threads einzuhauchen, stürzt es wundersamer Weise (liegt wohl eher an meinem Laienwissen) ab.<br />
Die Dokumentation von Boost.Thread ist meiner Meinung nach auch nicht die beste...</p>
<p>Auf jeden Fall habe ich in meinem Programm 2 &quot;Endlosschleifen&quot;, eine zum Empfangen, die andere zum Senden von Daten an einen beliebigen IRC-Server. Dafür wollte ich 2 Threads gebrauchen. Und da mir Boost so gut gefällt, dacht ich, ich probiere es damit.</p>
<p>Hier mal der Source von der main.cpp:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/thread.hpp&gt;
#include &quot;irc.hpp&quot;

// globals
bool runThread = true;
boost::mutex mMutex;

// protos
void recvProc(Jeix::IRC::Server&amp;);

int main()
{
	std::cout &lt;&lt; &quot;Jeix::IRC::Server test\n&quot;;
	try
	{
		Jeix::IRC::Server seilen;
		boost::thread recvThread(boost::bind(&amp;recvProc, boost::ref&lt;Jeix::IRC::Server&gt;(seilen)));

		seilen.Connect(&quot;irc.seilen.de&quot;, 6667);
		seilen.Login(&quot;diggllet&quot;, &quot;myhost&quot;, &quot;irc.seilen.org&quot;, &quot;max fischer&quot;);

		char input[1024];
		::std::string strInput;
		while(1)
		{
			std::cin.getline(input, 1024);
			strInput = input;
			if(!strInput.compare(&quot;/exit&quot;))
			{
				boost::unique_lock&lt;boost::mutex&gt; lock(mMutex);
				runThread = false;
				break;
			}
			strInput += &quot;\r\n&quot;;

			seilen.Send(strInput);
		} // while

		recvThread.join();
	}
	catch(std::string&amp; ex)
	{
		std::cout &lt;&lt; ex &lt;&lt; std::endl;
	}

	//PAUSE;
	std::cin.clear();
	std::cin.ignore();
	std::cin.get();
}

void recvProc(Jeix::IRC::Server&amp; serv)
{
	while(1)
	{
		boost::unique_lock&lt;boost::mutex&gt; lock(mMutex);
		std::cout &lt;&lt; serv.Receive();
		std::cout &lt;&lt; std::endl;

		if(runThread)
		{
			break;
		}
	}
}
</code></pre>
<p>Sorry erstmal für den doch relativ langen Quelltext, doch erschien mir der größte Teil nun doch wichtig.<br />
Hier noch die Implementation der Server.Receive() Methode. Falls ihr noch weiteres wissen wollt bzw. wichtig ist, sagt es bitte einfach.</p>
<pre><code class="language-cpp">::std::string Server::Receive()
	{
		::boost::mutex mTemp;
		::boost::unique_lock&lt;::boost::mutex&gt; lock(mTemp);
		char output[2000]; //declared in srv.hpp
		int countBytes = 0; //	 declared in srv.hpp

		countBytes = recv(sock, output, sizeof(output), 0);
		if (countBytes == SOCKET_ERROR)
		{	// Error
			throw &quot;Error, could not receive response from server!&quot;;
		}
		if (countBytes &gt; 0)
		{
			output[countBytes] = 0;	// recv doesn't put an \0 at the end of the string
			::std::string temp(output);
			return temp;
		}
		return &quot;&quot;;
	}
</code></pre>
<p>Bei der Zeile &quot;if (countBytes == SOCKET_ERROR)&quot; scheint es wohl irgendwie zu haken. Hier ein Screenshot von der Fehlermeldung:<br />
<a href="http://img521.imageshack.us/my.php?image=debugerrpx2.png" rel="nofollow">http://img521.imageshack.us/my.php?image=debugerrpx2.png</a></p>
<p>Ich hab mir das mit dem Boost.Thread größtenteils zusammengeraten, wenn ich ehrlich sein soll, da die Dokumentation in meinen Augen sehr mangelhaft ist und das einzige Beispiel, was ich finden konnte, war von 2002.</p>
<p>Vielleicht hab ich auch schon von Anfang an den falschen Ansatz, ich bin noch nicht so erfahren, danke für eure Hilfe!</p>
<p>MfG issen1</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1594917</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1594917</guid><dc:creator><![CDATA[issen1]]></dc:creator><pubDate>Tue, 07 Oct 2008 15:22:40 GMT</pubDate></item><item><title><![CDATA[Reply to Boost.Thread &amp;amp; Winsock -&amp;gt; Programmabsturz on Tue, 07 Oct 2008 15:40:03 GMT]]></title><description><![CDATA[<p>hmm ich weiß ja nicht aber du fängst die exception völlig falsch. Deswegen kommt auch die Meldung, da du die exception eben gar nicht auffängst:</p>
<pre><code class="language-cpp">catch(std::string&amp; ex)
{
        std::cout &lt;&lt; ex &lt;&lt; std::endl;
}
//Das nüsste aber so sein:
catch(std::exception&amp; ex)
{
        std::cout &lt;&lt; ex.what() &lt;&lt; std::endl;
}
</code></pre>
<p>Probiers mal aus, dann siehste wenigsten was da worklich fliegt.<br />
Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1594927</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1594927</guid><dc:creator><![CDATA[Fehler]]></dc:creator><pubDate>Tue, 07 Oct 2008 15:40:03 GMT</pubDate></item><item><title><![CDATA[Reply to Boost.Thread &amp;amp; Winsock -&amp;gt; Programmabsturz on Tue, 07 Oct 2008 15:53:50 GMT]]></title><description><![CDATA[<p>Aber er wirft doch einen std::string...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1594938</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1594938</guid><dc:creator><![CDATA[WildUmherWerfer]]></dc:creator><pubDate>Tue, 07 Oct 2008 15:53:50 GMT</pubDate></item><item><title><![CDATA[Reply to Boost.Thread &amp;amp; Winsock -&amp;gt; Programmabsturz on Tue, 07 Oct 2008 15:56:06 GMT]]></title><description><![CDATA[<p>Fehler schrieb:</p>
<blockquote>
<p>hmm ich weiß ja nicht aber du fängst die exception völlig falsch. Deswegen kommt auch die Meldung, da du die exception eben gar nicht auffängst:</p>
<pre><code class="language-cpp">catch(std::string&amp; ex)
{
        std::cout &lt;&lt; ex &lt;&lt; std::endl;
}
//Das nüsste aber so sein:
catch(std::exception&amp; ex)
{
        std::cout &lt;&lt; ex.what() &lt;&lt; std::endl;
}
</code></pre>
<p>Probiers mal aus, dann siehste wenigsten was da worklich fliegt.<br />
Gruß</p>
</blockquote>
<p>WildUmherWerfer schrieb:</p>
<blockquote>
<p>Aber er wirft doch einen std::string...</p>
</blockquote>
<p>Nein! Es wird ein const char* geworfen. Das ist KEIN std::string.<br />
Desshalb wird da nichts gefangen.<br />
Simon</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1594941</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1594941</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Tue, 07 Oct 2008 15:56:06 GMT</pubDate></item><item><title><![CDATA[Reply to Boost.Thread &amp;amp; Winsock -&amp;gt; Programmabsturz on Tue, 07 Oct 2008 16:06:18 GMT]]></title><description><![CDATA[<p>Glaube nicht, dass dies nur an Boost.Thread liegt. Die Dokumentation ist knapp und setzt halt ein Wissen in Threads voraus. Wenn ich deinen Quellcode anschaue, scheint das aber bei dir nicht vorhanden zu sein.</p>
<pre><code class="language-cpp">boost::thread recvThread(boost::bind(&amp;recvProc, boost::ref(seilen))); // &lt;Jeix::IRC::Server&gt; nach boost::ref ist unnötig, das findet der Compiler selber raus. (1)

seilen.Connect(&quot;irc.seilen.de&quot;, 6667); (2)
</code></pre>
<p>Was passiert hier?<br />
(1) Der Receiver Thread startet ... Wahrscheinlich wird er sofort versuchen Daten zu empfangen, du hinderst ihn ja nicht daran, gibt wahrscheinlich ein SOCKET_ERROR, da sich der Client noch mit keinem Server verbunden hat.<br />
(2) Nun kommt der erste Thread womöglich hier hin, und wird probieren sich zu verbinden. Das könnte sogar erfolgreich gehen.</p>
<p>Du musst diesen Teil auf jedenfall auch synchronisieren oder gar noch besser, den zweiten Thread erst nach erfoglreichem Connect und Login starten!</p>
<pre><code class="language-cpp">throw &quot;Error, could not receive response from server!&quot;;
</code></pre>
<p>Zwei Fehler hier!<br />
Diese Exception wird nirgend gefangen. Bei (1) startest du einen neuen Thread, der wird keine Exception in irgendeinen anderen Thread hineinwerfen. Diese Exception wird also ganz sicher nicht gefangen. Wird wohl zu einem terminate im anderen Thread führen und wahrscheinlich zum Absturz des Programmes.</p>
<p>Du hast ein catch im ersten Thread, welches aber diese Exception ganz sicher nicht fangen wird, auch wenn die Exception über Threadgrenzen geworfen würde, was aber nicht der Fall ist:</p>
<pre><code class="language-cpp">catch(std::string&amp; ex)
</code></pre>
<p>std::string ist != char const*<br />
Wäre mir zumindest neu, dass diese implizite Konvertierung bei Exceptions funktioniert.</p>
<pre><code class="language-cpp">::boost::mutex mTemp;
::boost::unique_lock&lt;::boost::mutex&gt; lock(mTemp);
</code></pre>
<p>Was das nützen soll, ist mir ein völliges Rätsel. Jeder Thread wird sein eigenes Mutex erstellen und dieses locken. Eine Synchronisation wird nie stattfinden.</p>
<p>Also, wenn ich mir das erlauben darf, lies vielleicht zuerst einmal ein Tutorial zu Threads durch, bevor du dich mit Boost.Thread beschäftigst. Zudem wäre auch ein Tutorial zu Exceptions und Templates wohl nicht all zu schlecht.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1594947</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1594947</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 07 Oct 2008 16:06:18 GMT</pubDate></item><item><title><![CDATA[Reply to Boost.Thread &amp;amp; Winsock -&amp;gt; Programmabsturz on Wed, 08 Oct 2008 18:05:14 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Glaube nicht, dass dies nur an Boost.Thread liegt. Die Dokumentation ist knapp und setzt halt ein Wissen in Threads voraus. Wenn ich deinen Quellcode anschaue, scheint das aber bei dir nicht vorhanden zu sein.</p>
</blockquote>
<p>Du hast natürlich Recht, mein Wissen über Threads bzw. Threading ist sehr oberflächlich. Vielleicht könntest du mir eine elektronische Lektüre empfehlen?</p>
<blockquote>
<p>Du hast ein catch im ersten Thread, welches aber diese Exception ganz sicher nicht fangen wird, auch wenn die Exception über Threadgrenzen geworfen würde, was aber nicht der Fall ist:</p>
<pre><code class="language-cpp">catch(std::string&amp; ex)
</code></pre>
<p>std::string ist != char const*<br />
Wäre mir zumindest neu, dass diese implizite Konvertierung bei Exceptions funktioniert.</p>
</blockquote>
<p>Ah, danke für den Hinweis (auch an die anderen Poster <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="😉"
    /> ). Da war mir ein Denkfehler unterlaufen. Das passiert mir des öfteren, besonders in der Woche, wenn es einem an Schlafdefiziten doch wirklich nicht mangelt. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<blockquote>
<pre><code class="language-cpp">::boost::mutex mTemp;
::boost::unique_lock&lt;::boost::mutex&gt; lock(mTemp);
</code></pre>
<p>Was das nützen soll, ist mir ein völliges Rätsel. Jeder Thread wird sein eigenes Mutex erstellen und dieses locken. Eine Synchronisation wird nie stattfinden.</p>
</blockquote>
<p>Das war nur einer von vielen Versuchen, die ich unternommen habe, damit es endlich funktioniert. Ich hätte da noch eine Frage:</p>
<pre><code class="language-cpp">boost::unique_lock&lt;boost::mutex&gt; lock(mMutex);
std::cout &lt;&lt; serv.Receive();
</code></pre>
<p>Wenn ich das so programmiere, wird dann jedes Objekt bzw. jede Variable, die genutzt wird gelocked? Denn ich bekomme neuerdings immer diesen &quot;WSANOTINITIALISED 10093&quot; Fehlercode, wenn ich versuche zu receiven oder zu senden. Da WSAStartup() jedoch eigentlich erfolgreich war, genau wie die Connect() Methode, erschließt sich mir der Sinn nicht ganz. Außer, dass halt folgendes eintritt:</p>
<blockquote>
<p>The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks), or WSACleanup has been called too many times.</p>
</blockquote>
<p>Auf jeden Fall, danke für eure Antworten, denn somit funktioniert mein kleines Programm erstmal (teilweise)! <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>
<blockquote>
<p>Also, wenn ich mir das erlauben darf, lies vielleicht zuerst einmal ein Tutorial zu Threads durch, bevor du dich mit Boost.Thread beschäftigst. Zudem wäre auch ein Tutorial zu Exceptions und Templates wohl nicht all zu schlecht.</p>
<p>Grüssli</p>
</blockquote>
<p>Natürlich darfst du. Kritik seh ich gerne, solange sie angemessen formuliert ist. Wie ich oben bereits sagt, wäre es schön, wenn mir einer einen (guten) Artikel über Threading nennen könnte. Ansonsten bin ich mit Exceptions eigentlich ganz gut vertraut, mit Templates habe ich mich noch nicht beschäftigt - außer, dass ich sie verwendet hab bei zB. std::vector; wird aber sicher noch kommen. Spätestens wenn der C++ Primer endlich bei mir zu Hause im Regal steht!</p>
<p>Beste Grüße<br />
- issen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1595768</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1595768</guid><dc:creator><![CDATA[issen1]]></dc:creator><pubDate>Wed, 08 Oct 2008 18:05:14 GMT</pubDate></item></channel></rss>