<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: reliable TCP reconnect made easy</title>
	<atom:link href="http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/feed/" rel="self" type="application/rss+xml" />
	<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/</link>
	<description>枕草子</description>
	<lastBuildDate>Tue, 08 Jun 2010 21:01:37 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<item>
		<title>By: jdmurray</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-920</link>
		<dc:creator>jdmurray</dc:creator>
		<pubDate>Mon, 20 Oct 2008 19:17:01 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-920</guid>
		<description>For syslog TCP reliability, would it not be easier to just prevent TCP from buffering the outgoing syslog messages? This would allow the syslog client to immediately know if the syslog message was sent successfully or not by the send exception thrown. The app itself would then keep track of the &quot;first unsent&quot; message.

I have implemented a syslog TCP client using C# and .NET 2.0 that sends event log messages to a syslog TCP server. If the TCP connection is broken, the next syslog message sent will cause the TcpClient object to return a Winsock error (10061 or 10054) and my app can then keep track of which event messages were not sent until a new connection can be established. It works very well.</description>
		<content:encoded><![CDATA[<p>For syslog TCP reliability, would it not be easier to just prevent TCP from buffering the outgoing syslog messages? This would allow the syslog client to immediately know if the syslog message was sent successfully or not by the send exception thrown. The app itself would then keep track of the &#8220;first unsent&#8221; message.</p>
<p>I have implemented a syslog TCP client using C# and .NET 2.0 that sends event log messages to a syslog TCP server. If the TCP connection is broken, the next syslog message sent will cause the TcpClient object to return a Winsock error (10061 or 10054) and my app can then keep track of which event messages were not sent until a new connection can be established. It works very well.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-212</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Mon, 09 Jun 2008 10:06:02 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-212</guid>
		<description>Hi Martin,

some more quick feedback: I have now implemented your approach in rsyslog, it will come out as part of 3.19.7. Initial testing confirms the findings - it works well in local, low-traffic environments, but still fails in others. However, even in the fail cases, the message loss is somewhat less than without the recv(). So I think it is useful to have this work-around in the code. Thanks for pointing it out :)

Rainer</description>
		<content:encoded><![CDATA[<p>Hi Martin,</p>
<p>some more quick feedback: I have now implemented your approach in rsyslog, it will come out as part of 3.19.7. Initial testing confirms the findings &#8211; it works well in local, low-traffic environments, but still fails in others. However, even in the fail cases, the message loss is somewhat less than without the recv(). So I think it is useful to have this work-around in the code. Thanks for pointing it out :)</p>
<p>Rainer</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-207</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Fri, 06 Jun 2008 10:10:19 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-207</guid>
		<description>Hi Martin,

I just wanted to let you know that I have written a final &quot;analysis&quot;: http://blog.gerhards.net/2008/06/getting-bit-more-reliability-from-plain.html . In short, I&#039;ll see that I give it a try in rsyslog, too. It&#039;s not a perfect solution (what on earth is that...), but it looks like it offers sufficient benefit to be worth implementing ;)

Thanks for bringing it up.

Rainer</description>
		<content:encoded><![CDATA[<p>Hi Martin,</p>
<p>I just wanted to let you know that I have written a final &#8220;analysis&#8221;: <a href="http://blog.gerhards.net/2008/06/getting-bit-more-reliability-from-plain.html" rel="nofollow">http://blog.gerhards.net/2008/06/getting-bit-more-reliability-from-plain.html</a> . In short, I&#8217;ll see that I give it a try in rsyslog, too. It&#8217;s not a perfect solution (what on earth is that&#8230;), but it looks like it offers sufficient benefit to be worth implementing ;)</p>
<p>Thanks for bringing it up.</p>
<p>Rainer</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-192</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Mon, 02 Jun 2008 13:40:34 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-192</guid>
		<description>OK, I have done some further stress testing. Unfortunately, the solution does not work as soon as the traffic gets higher. In client.c, you do a sleep. This sleep makes sure that the remote end has time to do its close and notify the client before the next message is sent. I modified you examples so that the sleep() is no longer used and 1000 messages are sent by the client. Then, the disconnect happens 1 byte into message 423 (stream was partly received). The next message I see is 701. The client also notices the problem at 701. So I have lost around 280 messages without anybody noticing it. Of course, on a non-busy server that does not happen, but it proves the point that even in a nice clean close scenario without packet loss you can lose data on a server restart. There is no reliable cure. I&#039;ll now evaluate if it makes sense to add your suggested recv() logic for those cases where it helps. I am just unsure if these are a large enough sample to justify this code change. Anyhow... Please let me know any further findings you may have (did I overlook something)?

Rainer</description>
		<content:encoded><![CDATA[<p>OK, I have done some further stress testing. Unfortunately, the solution does not work as soon as the traffic gets higher. In client.c, you do a sleep. This sleep makes sure that the remote end has time to do its close and notify the client before the next message is sent. I modified you examples so that the sleep() is no longer used and 1000 messages are sent by the client. Then, the disconnect happens 1 byte into message 423 (stream was partly received). The next message I see is 701. The client also notices the problem at 701. So I have lost around 280 messages without anybody noticing it. Of course, on a non-busy server that does not happen, but it proves the point that even in a nice clean close scenario without packet loss you can lose data on a server restart. There is no reliable cure. I&#8217;ll now evaluate if it makes sense to add your suggested recv() logic for those cases where it helps. I am just unsure if these are a large enough sample to justify this code change. Anyhow&#8230; Please let me know any further findings you may have (did I overlook something)?</p>
<p>Rainer</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-185</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Fri, 30 May 2008 13:02:42 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-185</guid>
		<description>Interesting. I&#039;ve now done a wireshark trace. As it looks, the IP stack does NOT process the incoming connection request until after it actually sends the message. If you do the recv(), this forces this evaluation. I have not verified this with the tcp sources and I don&#039;t think it makes much sense to do so. It&#039;s probably a bit platform-specific, depending on what the IP stack does. Anyhow, it seems to greatly reduce the problem in non-failure cases and does not cause much performance pain. So it is worth adding it. I&#039;ll now apply it once again to the real rsyslog and see how it performs there. I keep you posted. Rainer</description>
		<content:encoded><![CDATA[<p>Interesting. I&#8217;ve now done a wireshark trace. As it looks, the IP stack does NOT process the incoming connection request until after it actually sends the message. If you do the recv(), this forces this evaluation. I have not verified this with the tcp sources and I don&#8217;t think it makes much sense to do so. It&#8217;s probably a bit platform-specific, depending on what the IP stack does. Anyhow, it seems to greatly reduce the problem in non-failure cases and does not cause much performance pain. So it is worth adding it. I&#8217;ll now apply it once again to the real rsyslog and see how it performs there. I keep you posted. Rainer</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-184</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Fri, 30 May 2008 12:34:36 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-184</guid>
		<description>OK, I am not just ignorant ;) I&#039;ve given it another try, while racy it looks like it indeed solves the problem in the majority of simple cases. I just wonder what happens under the hood. I&#039;ll have a look :) -- Rainer</description>
		<content:encoded><![CDATA[<p>OK, I am not just ignorant ;) I&#8217;ve given it another try, while racy it looks like it indeed solves the problem in the majority of simple cases. I just wonder what happens under the hood. I&#8217;ll have a look :) &#8212; Rainer</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-183</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Fri, 30 May 2008 09:55:57 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-183</guid>
		<description>Martin, I have read your update. This use case isn&#039;t fixed either, at least not reliably. It is racy. You get the same results be just doing the send() without the recv() - just give it a try. ;) -- Rainer</description>
		<content:encoded><![CDATA[<p>Martin, I have read your update. This use case isn&#8217;t fixed either, at least not reliably. It is racy. You get the same results be just doing the send() without the recv() &#8211; just give it a try. ;) &#8212; Rainer</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-180</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Thu, 29 May 2008 15:37:18 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-180</guid>
		<description>OK, I have updated my last blog post with references to RFC 793, which provides clear evidence that there is no way around this problem (at least for a compliant implementation). Rainer</description>
		<content:encoded><![CDATA[<p>OK, I have updated my last blog post with references to RFC 793, which provides clear evidence that there is no way around this problem (at least for a compliant implementation). Rainer</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-179</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Thu, 29 May 2008 15:13:14 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-179</guid>
		<description>Martin, I saw you post from noon today only after posting my comment. You are now using two error states:

74 	        } else if (rc == -1 &amp;&amp; errno == ECONNRESET) {
75 	            /* server closed connection */
76 	            printf(&quot;got ECONNRESET, reconnect\n&quot;);
77 	            connected = 0;
78 	        } else if (rc == -1 &amp;&amp; errno == ENOTCONN)

However, you do get ECONNRESET and ENOTCONN also from the send() call, but ONLY after the TCP stack has detected that the connection is broken. I propose this test: make the client connect to the server. Pull the network cable from the server. Make the client continue to send some data to the server. The client will be unable to detect the server failure for &quot;n&quot; records. Plug in the network cable to the server. Server will now receive the &quot;lost&quot; messages. So the client was right in assuming the server was available.

Another test: connect to server as before. Do not pull the network cable but switch the machine off (do NOT shut it down). Client will not see any problems. Problem will be seen only after server comes back online (TCP connections can be reset at this point).

Rainer</description>
		<content:encoded><![CDATA[<p>Martin, I saw you post from noon today only after posting my comment. You are now using two error states:</p>
<p>74 	        } else if (rc == -1 &amp;&amp; errno == ECONNRESET) {<br />
75 	            /* server closed connection */<br />
76 	            printf(&#8220;got ECONNRESET, reconnect\n&#8221;);<br />
77 	            connected = 0;<br />
78 	        } else if (rc == -1 &amp;&amp; errno == ENOTCONN)</p>
<p>However, you do get ECONNRESET and ENOTCONN also from the send() call, but ONLY after the TCP stack has detected that the connection is broken. I propose this test: make the client connect to the server. Pull the network cable from the server. Make the client continue to send some data to the server. The client will be unable to detect the server failure for &#8220;n&#8221; records. Plug in the network cable to the server. Server will now receive the &#8220;lost&#8221; messages. So the client was right in assuming the server was available.</p>
<p>Another test: connect to server as before. Do not pull the network cable but switch the machine off (do NOT shut it down). Client will not see any problems. Problem will be seen only after server comes back online (TCP connections can be reset at this point).</p>
<p>Rainer</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rainer Gerhards</title>
		<link>http://mschuette.name/wp/2008/05/29/reliable-tcp-reconnect-made-easy/comment-page-1/#comment-178</link>
		<dc:creator>Rainer Gerhards</dc:creator>
		<pubDate>Thu, 29 May 2008 15:04:52 +0000</pubDate>
		<guid isPermaLink="false">http://mschuette.name/wp/?p=71#comment-178</guid>
		<description>I am sorry, but it doesn&#039;t work out. I have now also been able to define why it is impossible to do reliable delivery over plain tcp without app-level acks: http://blog.gerhards.net/2008/05/why-you-cant-build-reliable-tcp.html

Rainer</description>
		<content:encoded><![CDATA[<p>I am sorry, but it doesn&#8217;t work out. I have now also been able to define why it is impossible to do reliable delivery over plain tcp without app-level acks: <a href="http://blog.gerhards.net/2008/05/why-you-cant-build-reliable-tcp.html" rel="nofollow">http://blog.gerhards.net/2008/05/why-you-cant-build-reliable-tcp.html</a></p>
<p>Rainer</p>
]]></content:encoded>
	</item>
</channel>
</rss>
