<?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[[Winsock] Problem mit select() und Cleanup-Frage]]></title><description><![CDATA[<p>Hi,</p>
<p>ich möchte gerne einen Server schreiben der eine Nachricht nach folgenden Aufbau verarbeiten kann:</p>
<pre><code>Nachrichtenlänge\n
Anderes Zeug\n
Daten
</code></pre>
<p>Dazu habe ich mir folgende Funktionen geschrieben:</p>
<pre><code class="language-cpp">long recvLine(SOCKET s, std::string&amp; recv)
{
	std::stringstream buf;
	long rc = readLine(s, buf);

	if (rc == 0 || rc == SOCKET_ERROR)
	{
		closesocket(s);  
		s = INVALID_SOCKET;
		std::cout &lt;&lt; &quot;Verbindung getrennt.&quot; &lt;&lt; std::endl;
	}
	else
	{
		recv = buf.str();
	}

	return rc;
}

long readLine(SOCKET s, std::stringstream&amp; line)
{
	long rc;
	for (char c; (rc = recv(s, &amp;c, 1, 0)) &gt; 0; line &lt;&lt; c)
	{
		if (c == '\n')
		{
			return rc;
		}
	}

	return rc;
}
</code></pre>
<p>Diesen rufe ich hier auf:</p>
<pre><code class="language-cpp">// ...

if (clients[i] == INVALID_SOCKET)
			{
				continue;
			}

			if (FD_ISSET(clients[i], &amp;fdSet))
			{
				std::string line;
				rc = recvLine(clients[i], line);

				if (!line.empty())
				{
					std::cout &lt;&lt; &quot;Len: &quot; &lt;&lt; line &lt;&lt; std::endl;
					rc = recvLine(clients[i], line);

					if (!line.empty())
					{
						std::cout &lt;&lt; &quot;Other: &quot; &lt;&lt; line &lt;&lt; std::endl;

						// - Später die eigentlichen Daten hier empfangen -//
					}
				}
			}
// ...
</code></pre>
<p>Das funktioniert auch, aber wenn ich die Verbidung trenne, dann scheint select() ein SOCKET_ERROR zurückzugeben. Das ist aber wahrscheinlich unschön, da man es irgendwie vermeiden kann. Leider weiß ich nicht, wie ich das vermeiden kann und warum dieser Fehler überhaupt auftritt. Wie kann ich das Problem lösen?</p>
<p>Dann hätte ich noch eine Frage:</p>
<p>Sollte ich am Ende des Programms trotz der Endlosschleife ein WSACleanup() ausführen und auch alle Sockets schließen oder ist das wegen der Endlosschleife überflüssig? Ich meine, natürlich wird dieser Code nie ausgeführt, aber ist es guter Stil diesen Aufräum-Code trotzdem zu schreiben?</p>
<p>Würde mich über Antworten sehr freuen.</p>
<p>Viele Grüße,<br />
David K.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/230891/winsock-problem-mit-select-und-cleanup-frage</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 18:48:02 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/230891.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 03 Jan 2009 17:11:24 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Sat, 03 Jan 2009 17:11:24 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich möchte gerne einen Server schreiben der eine Nachricht nach folgenden Aufbau verarbeiten kann:</p>
<pre><code>Nachrichtenlänge\n
Anderes Zeug\n
Daten
</code></pre>
<p>Dazu habe ich mir folgende Funktionen geschrieben:</p>
<pre><code class="language-cpp">long recvLine(SOCKET s, std::string&amp; recv)
{
	std::stringstream buf;
	long rc = readLine(s, buf);

	if (rc == 0 || rc == SOCKET_ERROR)
	{
		closesocket(s);  
		s = INVALID_SOCKET;
		std::cout &lt;&lt; &quot;Verbindung getrennt.&quot; &lt;&lt; std::endl;
	}
	else
	{
		recv = buf.str();
	}

	return rc;
}

long readLine(SOCKET s, std::stringstream&amp; line)
{
	long rc;
	for (char c; (rc = recv(s, &amp;c, 1, 0)) &gt; 0; line &lt;&lt; c)
	{
		if (c == '\n')
		{
			return rc;
		}
	}

	return rc;
}
</code></pre>
<p>Diesen rufe ich hier auf:</p>
<pre><code class="language-cpp">// ...

if (clients[i] == INVALID_SOCKET)
			{
				continue;
			}

			if (FD_ISSET(clients[i], &amp;fdSet))
			{
				std::string line;
				rc = recvLine(clients[i], line);

				if (!line.empty())
				{
					std::cout &lt;&lt; &quot;Len: &quot; &lt;&lt; line &lt;&lt; std::endl;
					rc = recvLine(clients[i], line);

					if (!line.empty())
					{
						std::cout &lt;&lt; &quot;Other: &quot; &lt;&lt; line &lt;&lt; std::endl;

						// - Später die eigentlichen Daten hier empfangen -//
					}
				}
			}
// ...
</code></pre>
<p>Das funktioniert auch, aber wenn ich die Verbidung trenne, dann scheint select() ein SOCKET_ERROR zurückzugeben. Das ist aber wahrscheinlich unschön, da man es irgendwie vermeiden kann. Leider weiß ich nicht, wie ich das vermeiden kann und warum dieser Fehler überhaupt auftritt. Wie kann ich das Problem lösen?</p>
<p>Dann hätte ich noch eine Frage:</p>
<p>Sollte ich am Ende des Programms trotz der Endlosschleife ein WSACleanup() ausführen und auch alle Sockets schließen oder ist das wegen der Endlosschleife überflüssig? Ich meine, natürlich wird dieser Code nie ausgeführt, aber ist es guter Stil diesen Aufräum-Code trotzdem zu schreiben?</p>
<p>Würde mich über Antworten sehr freuen.</p>
<p>Viele Grüße,<br />
David K.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1638901</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1638901</guid><dc:creator><![CDATA[David K.]]></dc:creator><pubDate>Sat, 03 Jan 2009 17:11:24 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Sat, 03 Jan 2009 23:43:04 GMT]]></title><description><![CDATA[<p>Es ist schlechter Stil, Code zu schreiben, der nie ausgeführt wird.<br />
Es ist aber auch schlechter Stil, Programme zu schreiben, die man nicht beenden kann <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/1639067</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1639067</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 03 Jan 2009 23:43:04 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Sun, 04 Jan 2009 14:29:27 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Es ist schlechter Stil, Code zu schreiben, der nie ausgeführt wird.<br />
Es ist aber auch schlechter Stil, Programme zu schreiben, die man nicht beenden kann <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>Damit wäre die Frage ja dann beantwortet. Danke <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>
<p>Hat noch jemand eine Idee für mein eigentliches Problem? Konnte es leider noch immer nicht lösen...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1639265</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1639265</guid><dc:creator><![CDATA[David K.]]></dc:creator><pubDate>Sun, 04 Jan 2009 14:29:27 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Mon, 05 Jan 2009 14:25:01 GMT]]></title><description><![CDATA[<p>Hat niemand eine Idee? <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="😞"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1639853</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1639853</guid><dc:creator><![CDATA[David K.]]></dc:creator><pubDate>Mon, 05 Jan 2009 14:25:01 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Mon, 05 Jan 2009 21:54:08 GMT]]></title><description><![CDATA[<p>Was meinst du mit &quot;Verbindung trennen&quot;? Trennt der andere PC die Verbindung oder schliesst du den Socket aus einem anderen Thread?</p>
<p>Und was für einen Fehlercode liefert select (bzw. genauer: was liefert WSAGetLastError() nachdem select SOCKET_ERROR zurückgegeben hat)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1640141</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640141</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 05 Jan 2009 21:54:08 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Tue, 06 Jan 2009 12:28:05 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Was meinst du mit &quot;Verbindung trennen&quot;? Trennt der andere PC die Verbindung oder schliesst du den Socket aus einem anderen Thread?</p>
<p>Und was für einen Fehlercode liefert select (bzw. genauer: was liefert WSAGetLastError() nachdem select SOCKET_ERROR zurückgegeben hat)?</p>
</blockquote>
<p>Hi,</p>
<p>ich starte meine Server-Anwendung und verbinde mich anschließend mit irgendeinem Programm zu diesem Server. Ich sende ein paar Dinge und alles klappt perfekt. Nun schließe ich das Clientprogramm. Mein Server erkennt das die Verbindung getrennt wurde, aber spuckt gleichzeitig einen Fehler bei <code>select()</code> aus (Zeile 68). Der Fehlercode lautet: <code>10038</code> . Das entspricht wohl <code>WSAENOTSOCK</code> . Ich weiß aber nicht warum dieser Fehler auftritt und wie ich ihn beheben kann. Deswegen hier mal mein gesamter Code:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
#include &lt;windows.h&gt;
#include &lt;winsock.h&gt;

const int MAX_CLIENTS = 10;
const int PORT = 4321;

long recvLine(SOCKET s, std::string&amp; recv);
long readLine(SOCKET s, std::stringstream&amp; line);
void error(const std::string&amp; str);
int startWinsock();

int main()
{
	long rc;
	SOCKET acceptSocket;
	SOCKADDR_IN addr;
	FD_SET fdSet;
	SOCKET clients[MAX_CLIENTS];

	if ((rc = startWinsock()) != 0)
	{
		error(&quot;startWinsock()&quot;);
	}

	acceptSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (acceptSocket == INVALID_SOCKET)
	{
		error(&quot;acceptSocket = socket()&quot;);
	}

	memset(&amp;addr, 0, sizeof(SOCKADDR_IN));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = INADDR_ANY;
	if ((rc = bind(acceptSocket, (SOCKADDR*)&amp;addr, sizeof(SOCKADDR_IN))) == SOCKET_ERROR)
	{
		error(&quot;bind()&quot;);
	}

	if ((rc = listen(acceptSocket, 10)) == SOCKET_ERROR)
	{
		error(&quot;listen()&quot;);
	}

	for (int i = 0; i &lt; MAX_CLIENTS; ++i)
	{
		clients[i] = INVALID_SOCKET;
	}

	while (true)
	{
		FD_ZERO(&amp;fdSet);
		FD_SET(acceptSocket, &amp;fdSet);

		for (int i = 0; i &lt; MAX_CLIENTS; ++i)
		{
			if (clients[i] != INVALID_SOCKET)
			{
				FD_SET(clients[i], &amp;fdSet);
			}
		}

		if ((rc = select(0, &amp;fdSet, NULL, NULL, NULL)) == SOCKET_ERROR)
		{
			error(&quot;select()&quot;);
			printf(&quot;WSA: %i\n&quot;, WSAGetLastError()); // Debug
		}

		if (FD_ISSET(acceptSocket, &amp;fdSet)) 
		{
			for (int i = 0; i &lt; MAX_CLIENTS; ++i)
			{
				if (clients[i] == INVALID_SOCKET)
				{
					clients[i] = accept(acceptSocket, NULL, NULL);
					std::cout &lt;&lt; &quot;Neuer Client.&quot; &lt;&lt; std::endl;
					break;
				}
			}
		}

		for (int i = 0; i &lt; MAX_CLIENTS; ++i)
		{
			if (clients[i] == INVALID_SOCKET)
			{
				continue;
			}

			if (FD_ISSET(clients[i], &amp;fdSet))
			{
				std::string line;
				rc = recvLine(clients[i], line);

				if (!line.empty())
				{
					std::cout &lt;&lt; &quot;Len: &quot; &lt;&lt; line &lt;&lt; std::endl;

					rc = recvLine(clients[i], line);

					if (!line.empty())
					{
						std::cout &lt;&lt; &quot;Other: &quot; &lt;&lt; line &lt;&lt; std::endl;

						// - Data -//
					}
				}
			}
		}
	}
}

long recvLine(SOCKET s, std::string&amp; recv)
{
	std::stringstream buf;
	long rc = readLine(s, buf);

	if (rc == 0 || rc == SOCKET_ERROR)
	{
		closesocket(s);  
		s = INVALID_SOCKET;
		std::cout &lt;&lt; &quot;Verbindung getrennt.&quot; &lt;&lt; std::endl;
	}
	else
	{
		recv = buf.str();
	}

	return rc;
}

long readLine(SOCKET s, std::stringstream&amp; line)
{
	long rc;
	for (char c; (rc = recv(s, &amp;c, 1, 0)) &gt; 0; line &lt;&lt; c)
	{
		if (c == '\n')
		{
			return rc;
		}
	}

	return rc;
}

void error(const std::string&amp; str)
{
	std::cerr &lt;&lt; &quot;Error: &quot; &lt;&lt; str &lt;&lt; std::endl;
}

int startWinsock()
{
	WSADATA wsa;
	return WSAStartup(MAKEWORD(2, 0), &amp;wsa);
}
</code></pre>
<p>Ich hoffe, ihr könnt mir nun besser helfen und habt vielleicht noch ein paar Anregungen zu meinem Code <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_down"
      title=":-1:"
      alt="👎"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1640350</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640350</guid><dc:creator><![CDATA[David K.]]></dc:creator><pubDate>Tue, 06 Jan 2009 12:28:05 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Tue, 06 Jan 2009 13:03:20 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich würd mal behaupten das liegt daran, dass du nur die lokale Kopie des Sockets in &quot;recvLine&quot; auf INVALID_SOCKET setzt und nicht in der main.</p>
<p>Gruß Pingu</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1640369</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640369</guid><dc:creator><![CDATA[Pingu-Group]]></dc:creator><pubDate>Tue, 06 Jan 2009 13:03:20 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Tue, 06 Jan 2009 14:20:17 GMT]]></title><description><![CDATA[<p>Pingu-Group schrieb:</p>
<blockquote>
<p>Hi,</p>
<p>ich würd mal behaupten das liegt daran, dass du nur die lokale Kopie des Sockets in &quot;recvLine&quot; auf INVALID_SOCKET setzt und nicht in der main.</p>
<p>Gruß Pingu</p>
</blockquote>
<p>Ich übergebe nun Referenzen an die Funktionen und es klappt <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="😃"
    /> Vielen Dank <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/1640413</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640413</guid><dc:creator><![CDATA[David K.]]></dc:creator><pubDate>Tue, 06 Jan 2009 14:20:17 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Tue, 06 Jan 2009 15:28:17 GMT]]></title><description><![CDATA[<p>Hiho, wegen dem Problem des immer-rennenden-Servers.</p>
<p>Schau dir mal signal() an, damit könntest du deinen Server zum Beenden bringen, wenn der Benutzer es so will (SIGABRT -&gt; STRG+C).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1640457</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640457</guid><dc:creator><![CDATA[~Exit]]></dc:creator><pubDate>Tue, 06 Jan 2009 15:28:17 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Tue, 06 Jan 2009 19:24:59 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>select + Blocking I/O macht keinen Sinn.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1640624</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640624</guid><dc:creator><![CDATA[3]]></dc:creator><pubDate>Tue, 06 Jan 2009 19:24:59 GMT</pubDate></item><item><title><![CDATA[Reply to [Winsock] Problem mit select() und Cleanup-Frage on Tue, 06 Jan 2009 22:15:15 GMT]]></title><description><![CDATA[<p>3 schrieb:</p>
<blockquote>
<p>Hallo,</p>
<p>select + Blocking I/O macht keinen Sinn.</p>
</blockquote>
<p>Da hast du jetzt auch wieder Recht <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/1640711</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1640711</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 06 Jan 2009 22:15:15 GMT</pubDate></item></channel></rss>