﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-ngaut-随笔分类-asio</title><link>http://www.cppblog.com/ngaut/category/8573.html</link><description>asm/c/c++/......</description><language>zh-cn</language><lastBuildDate>Wed, 13 Jun 2012 03:56:28 GMT</lastBuildDate><pubDate>Wed, 13 Jun 2012 03:56:28 GMT</pubDate><ttl>60</ttl><item><title>[转] C++扫盲系列--第一个服务器程序</title><link>http://www.cppblog.com/ngaut/archive/2009/09/06/95406.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Sun, 06 Sep 2009 03:26:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2009/09/06/95406.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/95406.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2009/09/06/95406.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/95406.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/95406.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 来自：http://blog.csdn.net/NewNebuladream/archive/2009/08/12/4437888.aspx&nbsp;&nbsp;C++扫盲系列--第一个服务器程序&nbsp;收藏关于需求&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;进行程序开发，对于需求的把握是至关重要的。可以说，我之前没有任何开发服...&nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2009/09/06/95406.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/95406.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2009-09-06 11:26 <a href="http://www.cppblog.com/ngaut/archive/2009/09/06/95406.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>asio工程向boost.asio转换注意事项</title><link>http://www.cppblog.com/ngaut/archive/2008/10/21/64602.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Tue, 21 Oct 2008 03:50:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2008/10/21/64602.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/64602.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2008/10/21/64602.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/64602.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/64602.html</trackback:ping><description><![CDATA[<h3>What are the differences in the source code?</h3>
<p>— Asio is in a namespace called <tt>asio::</tt>, whereas Boost.Asio puts everything under <tt>boost::asio::</tt>.</p>
<p>— The main Asio header file is called <tt>asio.hpp</tt>. The corresponding header in Boost.Asio is <tt>boost/asio.hpp</tt>. All other headers are similarly changed.</p>
<p>— Any macros used by or defined in Asio are prefixed with <tt>ASIO_</tt>. In Boost.Asio they are prefixed with <tt>BOOST_ASIO_</tt>.</p>
<p>— Asio includes a class for launching threads, <tt>asio::thread</tt>. Boost.Asio does not include this class, to avoid overlap with the Boost.Thread library</p>
<p>— Boost.Asio uses the Boost.System library to provide support for error codes (<tt>boost::system::error_code</tt> and <tt>boost::system::system_error</tt>). Asio includes these under its own namespace (<tt>asio::error_code</tt> and <tt>asio::system_error</tt>). The Boost.System version of these classes currently supports better extensibility for user-defined error codes. 需要包含&lt;boost/system/system_error.hpp&gt; 头文件</p>
<p>— Asio is header-file-only and for most uses does not require linking against any Boost library. Boost.Asio always requires that you link against the Boost.System library, and also against Boost.Thread if you want to launch threads using <tt>boost::thread</tt>.需要包含&lt;boost/thread.hpp&gt; </p>
<img src ="http://www.cppblog.com/ngaut/aggbug/64602.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2008-10-21 11:50 <a href="http://www.cppblog.com/ngaut/archive/2008/10/21/64602.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>asio终于随boost一起发布了</title><link>http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Tue, 01 Apr 2008 10:46:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/45940.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/45940.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/45940.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html'>阅读全文</a><img src ="http://www.cppblog.com/ngaut/aggbug/45940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2008-04-01 18:46 <a href="http://www.cppblog.com/ngaut/archive/2008/04/01/45940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>asio:如何正确关闭socket</title><link>http://www.cppblog.com/ngaut/archive/2008/02/22/43102.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Fri, 22 Feb 2008 11:31:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2008/02/22/43102.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/43102.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2008/02/22/43102.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/43102.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/43102.html</trackback:ping><description><![CDATA[&gt; Also now I am confused and it will be helpful to know in asio sockets:<br>&gt; 1. In what situation we need to use both <br>&gt; "basic_stream_socket::shutdown()" &amp; "basic_stream_socket::close()"<br>&gt; functions?<br><br>If you want graceful closure of the socket, and you want it to work <br>consistently on Windows, use shutdown() before close(). There are <br>circumstances where just calling close() can result in the Windows TCP <br>stack sending a RST to the peer, which means possible data loss (i.e. <br>anything but a graceful closure).<br><br>&gt; 2. In what situation we need to use just "basic_stream_socket::close()"<br>&gt; function?<br><br>When you just want to close the connection as soon as possible and don't <br>care about possible loss of data under Windows.<br><br>
<img src ="http://www.cppblog.com/ngaut/aggbug/43102.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2008-02-22 19:31 <a href="http://www.cppblog.com/ngaut/archive/2008/02/22/43102.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用asio需要注意的两个问题</title><link>http://www.cppblog.com/ngaut/archive/2008/02/14/42745.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Thu, 14 Feb 2008 13:52:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2008/02/14/42745.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/42745.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2008/02/14/42745.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/42745.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/42745.html</trackback:ping><description><![CDATA[Message: 2<br>Date: Wed, 6 Feb 2008 23:43:09 -0000<br>From: "Roger Austin" &lt;Roger@wallingfordsoftware.com&gt;<br>Subject: Re: [asio-users] asio::async_write &amp; WriteHander<br>To: &lt;asio-users@lists.sourceforge.net&gt;<br>Message-ID:<br>&lt;0CEE50132F7DB142AA8632D6FB1BE982E7E462@bob.internal.wallingfordsoftware.co.uk&gt;<br><br>Content-Type: text/plain; charset="us-ascii"<br><br>If there is ever an asio FAQ, the correct use of async_write will be at<br>the top of the list<br><br><br><br>Cliff is correct in what he says but the key clause is "when the first<br>async_write completes". If you start your second async_write before the<br>first has completed, you risk interleaving the data. Thus if you want to<br>write code like:<br><br><br><br>DoAsyncWrite("Message 1");<br><br>DoAsyncWrite("Message 2");<br><br><br><br>Then your implementation of DoAsyncWrite (which will call async_write<br>internally) must check if there is already an async_write pending and,<br>if so, put the message somewhere (i.e. in a queue), ready to be sent<br>when the pending async_write has completed. The asio chat example does<br>this.<br><br><br><br>This is not a limitation of asio as such. The underlying socket<br>functions (send or equivalent) make no guarantee that the entire message<br>can be transferred to the TCP stream in a single asynchronous operation<br>- the write handler will be told how many bytes were actually<br>transferred and the application is responsible for issuing a new call to<br>send the remaining bytes. The asio async_write function does this for<br>you via one or more calls to async_write_some, but in doing so it tends<br>to hide the fact that the second and later calls to async_write_some<br>(needed to complete sending the first message) may happen later in the<br>thread than the first call to async_write_some for the second message.<br><br><br><br><br><br>From: asio-users-bounces@lists.sourceforge.net<br>[mailto:asio-users-bounces@lists.sourceforge.net] On Behalf Of X Wang<br>Sent: Thursday, 7 February 2008 9:37 AM<br>To: asio-users@lists.sourceforge.net<br>Subject: Re: [asio-users] asio::async_write &amp; WriteHander<br><br><br><br><br><br>"Green, Cliff" &lt;cliff.green@boeing.com&gt; wrote: <br><br>&gt; Sender sends out 2 messages back to back (on the same end-to-end<br>socket <br>&gt; connection), message 1 is 10 MB, message 2 is 10 bytes, with no<br>receiver <br>&gt; ACK in between. <br><br>Assuming the two messages are generated in order (e.g. in a single<br>thread), there is not an issue - one async_write of 10 MB, followed by<br>an async_write of 10 bytes (when the first async_write completes). Since<br>the actual "buffer" passed to Asio async_write does not copy the 10 MB /<br>10 b, you will need to manage the lifetime of the two original message<br>buffers. If the "message generation" is completely independent of the<br>thread invoking the async_writes, you need to manage the coordination<br>(this could be a queue, as previously mentioned, or some other form of<br>coordination).<br><br>You will be guaranteed that the data gets to the receiver in the same<br>order - 10 MB followed by 10 b (however, the receiver will need to take<br>responsibility for the message delimiter handling).<br><br>Am I missing something?<br><br>(Asio experts, please correct any of my mistakes on the Asio aspects.)<br><br>Much of this explanation is not dependent on async concepts and designs<br>- it would need to be similar whether your app is blocking, non-blocking<br>(polling), non-blocking (reactive), multi-threaded, etc.<br><br>Cliff<br><br>------------------------------------------------------------------------<br>-<br>This SF.net email is sponsored by: Microsoft<br>Defy all challenges. Microsoft(R) Visual Studio 2008.<br>http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/<br>_______________________________________________<br>asio-users mailing list<br>asio-users@lists.sourceforge.net<br>https://lists.sourceforge.net/lists/listinfo/asio-users<br><br><br>Yeah, you are right. What I said about TCP did not make much sense...<br>need some coffee :)<br>
<img src ="http://www.cppblog.com/ngaut/aggbug/42745.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2008-02-14 21:52 <a href="http://www.cppblog.com/ngaut/archive/2008/02/14/42745.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>asio作者写的好东东,不容错过哦</title><link>http://www.cppblog.com/ngaut/archive/2007/12/28/39863.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Fri, 28 Dec 2007 12:43:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/12/28/39863.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/39863.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/12/28/39863.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/39863.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/39863.html</trackback:ping><description><![CDATA[<h2 class=date-header>Wednesday, August 08, 2007</h2>
<div class="post hentry uncustomized-post-template"><a name=9091214669274461484></a>
<h3 class="post-title entry-title"><a href="http://think-async.blogspot.com/2007/08/time-travel.html"><u><font color=#0000ff>Time Travel</font></u></a> </h3>
<div class=post-header-line-1></div>
<div class="post-body entry-content">
<p>Many event-driven programs involve state changes that are triggered according to the system clock. You might be coding for:
<ul><br>
    <li>A share market that opens at 10:00am and closes at 4:00pm.<br>
    <li>An off-peak phone billing rate that starts after 7:00pm.<br>
    <li>An interest calculation that is run on the last day of every month.<br></li>
</ul>
The <code>asio::deadline_timer</code> class lets you handle this easily. For example:<br>
<pre>using namespace boost::posix_time;<br>typedef boost::date_time::c_local_adjustor&lt;ptime&gt; local_adj;<br><br>...<br><br>asio::deadline_timer timer(io_service);<br><br>ptime open_time(second_clock::local_time().date(), hours(10));<br>timer.expires_at(local_adj::local_to_utc(open_time));<br>timer.async_wait(open_market);<br></pre>
There's a catch: to test that your timer events work correctly, you have to run your program at the right time of day. It usually isn't practical to sit around all day (or, worse, all year) waiting for the timers to expire.<br><br>
<h3>Time Traits</h3>
<br>You may have noticed that the <code>asio::deadline_timer</code> class is actually a typedef:<br>
<pre>typedef basic_deadline_timer&lt;boost::posix_time::ptime&gt;<br>  deadline_timer;</pre>
where the basic_deadline_timer class template is declared as follows:<br>
<pre>template &lt;<br>    typename Time,<br>    typename TimeTraits<br>      = asio::time_traits&lt;Time&gt;,<br>    typename TimerService<br>      = deadline_timer_service&lt;Time, TimeTraits&gt; &gt;<br>class basic_deadline_timer;<br></pre>
In the context of our problem, the most interesting template parameter is the second one: <code>TimeTraits</code>. An implementation of <code>TimeTraits</code> lets us customise the treatment of the template's <code>Time</code> parameter, and consequently the behaviour of the timer itself.<br><br>A <code>TimeTraits</code> class must implement an interface that matches the following:<br>
<pre>class TimeTraits<br>{<br>public:<br>  // The type used to represent an absolute time, i.e. the same<br>  // as the Time template parameter to basic_deadline_timer.<br>  typedef ... time_type;<br><br>  // The type used to represent the difference between two<br>  // absolute times.<br>  typedef ... duration_type;<br><br>  // Returns the current time.<br>  static time_type now();<br><br>  // Returns a new absolute time resulting from adding the<br>  // duration d to the absolute time t.<br>  static time_type add(time_type t, duration_type d);<br><br>  // Returns the duration resulting from subtracting t2 from t1.<br>  static duration_type subtract(time_type t1, time_type t2);<br><br>  // Returns whether t1 is to be treated as less than t2.<br>  static bool less_than(time_type t1, time_type t2);<br><br>  // Returns a "posix" duration corresponding to the duration d.<br>  static boost::posix_time::time_duration to_posix_duration(<br>      duration_type d);<br>};</pre>
As you can see from the declaration of the <code>basic_deadline_timer</code> class template, Asio provides a default <code>TimeTraits</code> implementation called <code>asio::time_traits&lt;&gt;</code>.<br><br>
<h3>Offsetting Now</h3>
<br>To test our timer events at any time of our choosing, we simply need to change the definition of "now" using a custom <code>TimeTraits</code> class.<br><br>Since we want to use the same time types as the regular <code>deadline_timer</code> class, we'll start by reusing the default traits implementation:<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br>};</pre>
The value returned by the <code>now()</code> function will be offset from the system clock by a specified duration:<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br><br>private:<br>  <font color=red>static duration_type offset_;</font><br>};</pre>
which is simply added to the system clock:<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br>public:<br>  <font color=red>static time_type now()<br>  {<br>    return add(asio::deadline_timer::traits_type::now(), offset_);<br>  }</font><br><br>private:<br>  static duration_type offset_;<br>};</pre>
Of course, we will also need to provide a way to set the offset, which can be done by setting an initial value for "now":<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br>public:<br>  static time_type now()<br>  {<br>    return add(asio::deadline_timer::traits_type::now(), offset_);<br>  }<br><br>  <font color=red>static void set_now(time_type t)<br>  {<br>    offset_ =<br>      subtract(t, asio::deadline_timer::traits_type::now());<br>  }</font><br><br>private:<br>  static duration_type offset_;<br>};</pre>
<br>
<h3>Creating a Timer</h3>
<br>To use our custom traits type with the <code>basic_deadline_timer</code> template, we simply need to add the following typedef:<br>
<pre>typedef asio::basic_deadline_timer&lt;<br>    boost::posix_time::ptime, offset_time_traits&gt; offset_timer;</pre>
To see the offset timer in action, let's create a timer to fire precisely at the start of the coming new year. So we don't have to wait until then, we'll set "now" to be just ten seconds prior to midnight:<br>
<pre>offset_time_traits::set_now(<br>    boost::posix_time::from_iso_string("20071231T235950"));<br><br>offset_timer timer(io_service);<br>timer.expires_at(<br>    boost::posix_time::from_iso_string("20080101T000000"));<br>timer.async_wait(handle_timeout);<br><br>io_service.run();</pre>
When the program is run, it will take just ten seconds to complete.<br><br>
<h3>Jumping Through Time</h3>
<br>One feature not supported by the above solution is the ability to change the definition of "now" after the timers have been started. However, if your timer events are spread across a long period of time, then this is likely to be something you would want.<br><br>Let's say that the next timer does not expire for several hours, but in an attempt to speed things up we call <code>set_now()</code> to move to just seconds before. The problem with the above traits class is that the existing asynchronous wait operation does not know about the change to "now", and so will continue to run for the remaining hours.<br><br>Fortunately, Asio provides a way around this: by customising the <code>to_posix_duration()</code> function in our traits class.<br><br>The <code>to_posix_duration()</code> function is normally used to convert from a user-defined duration type to a type that Asio knows about (namely <code>boost::posix_time::time_duration</code>). The key point here is that this converted duration value is used by Asio to determine how long to wait until the timer expires. Furthermore, it doesn't matter if this function returns a duration that is smaller (even substantially so) than the actual duration. The timer won't fire early, because Asio guarantees that it won't expire until the following condition holds true:<br>
<pre>!TimeTraits::less_than(Time_Traits::now(), timer.expires_at())</pre>
So, by adding the <code>to_posix_duration()</code> function to our traits class:<br>
<pre>class offset_time_traits<br>  : public asio::deadline_timer::traits_type<br>{<br>public:<br>  static time_type now()<br>  {<br>    return add(asio::deadline_timer::traits_type::now(), offset_);<br>  }<br><br>  static void set_now(time_type t)<br>  {<br>    offset_ =<br>      subtract(t, asio::deadline_timer::traits_type::now());<br>  }<br><br>  <font color=red>static boost::posix_time::time_duration to_posix_duration(<br>      duration_type d)<br>  {<br>    return d &lt; boost::posix_time::seconds(5)<br>      ? d : boost::posix_time::seconds(5);<br>  }</font><br><br>private:<br>  static duration_type offset_;<br>};</pre>
we can ensure that Asio detects changes to the offset within seconds.
<p>&nbsp;</p>
<div style="CLEAR: both"></div>
</div>
<div class=post-footer>
<p class="post-footer-line post-footer-line-1"><span class="post-author vcard">Posted by <span class=fn>chris</span> </span><span class=post-timestamp>at <a class=timestamp-link title="permanent link" href="http://think-async.blogspot.com/2007/08/time-travel.html" rel=bookmark><abbr class=published title=2007-08-08T23:00:00+10:00><u><font color=#0000ff>11:00 PM</abbr></font></u></a> </span><span class=post-comment-link><a class=comment-link onclick="" href="http://www.blogger.com/comment.g?blogID=35024958&amp;postID=9091214669274461484"><u><font color=#0000ff>1 comments</font></u></a> </span><span class="post-backlinks post-comment-link"></span><span class=post-icons><span class="item-control blog-admin pid-660467121"><a title="Edit Post" href="http://www.blogger.com/post-edit.g?blogID=35024958&amp;postID=9091214669274461484"><u><font color=#0000ff><span class=quick-edit-icon>&nbsp;</span> </font></u></a></span></span></p>
<p class="post-footer-line post-footer-line-2"><span class=post-labels>Labels: <a href="http://think-async.blogspot.com/search/label/asio" rel=tag><u><font color=#0000ff>asio</font></u></a>, <a href="http://think-async.blogspot.com/search/label/boost" rel=tag><u><font color=#0000ff>boost</font></u></a>, <a href="http://think-async.blogspot.com/search/label/timer" rel=tag><u><font color=#0000ff>timer</font></u></a> </span></p>
<p class="post-footer-line post-footer-line-3"></p>
</div>
</div>
<h2 class=date-header>Thursday, April 26, 2007</h2>
<div class="post hentry uncustomized-post-template"><a name=7236229129837214596></a>
<h3 class="post-title entry-title"><a href="http://think-async.blogspot.com/2007/04/new-home-heating-solution.html"><u><font color=#0000ff>New home heating solution</font></u></a> </h3>
<div class=post-header-line-1></div>
<div class="post-body entry-content">
<p>For quite some time I have wanted to take a really good look at improving Boost.Asio's scalability across multiple processors. Unfortunately, getting unlimited access to this sort of hardware has been somewhat problematic. What I really needed was a decent multiprocessor box at home :)<br><br>The arrival of Intel's Clovertown quad core CPUs gave me the opportunity. The primary goal was to maximise parallelism while minimising the cost, and the lowest spec quad cores were cheap enough for me to justify spending the money. So, after months of <strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">thinking</strong> (and weeks of waiting for parts), last week I finally completed my home-built server.<br><br>Here are the headline specs:
<ul><br>
    <li>Two Intel Xeon E5310 quad core processors (1.6 GHz)<br><br>
    <li>Tyan Tempest i5000XL motherboard<br><br>
    <li>2GB DDR2-667 fully buffered ECC DIMMs<br><br>
    <li>OCZ GameXStream 700W power supply (OK, OK, it's a little overpowered, but it was in stock!)<br><br>
    <li>Other stuff like case, hard disk, DVD drive, video card and wireless LAN card<br><br>
    <li>Lots of fans to provide soothing ambient noise<br><br></li>
</ul>
So far I have installed CentOS Linux 5 on it, but also plan to try Solaris 10 and FreeBSD. It seems pretty snappy.
<p>&nbsp;</p>
<div style="CLEAR: both"></div>
</div>
<div class=post-footer>
<p class="post-footer-line post-footer-line-1"><span class="post-author vcard">Posted by <span class=fn>chris</span> </span><span class=post-timestamp>at <a class=timestamp-link title="permanent link" href="http://think-async.blogspot.com/2007/04/new-home-heating-solution.html" rel=bookmark><abbr class=published title=2007-04-26T23:57:00+10:00><u><font color=#0000ff>11:57 PM</abbr></font></u></a> </span><span class=post-comment-link><a class=comment-link onclick="" href="http://www.blogger.com/comment.g?blogID=35024958&amp;postID=7236229129837214596"><u><font color=#0000ff>2 comments</font></u></a> </span><span class="post-backlinks post-comment-link"></span><span class=post-icons><span class="item-control blog-admin pid-660467121"><a title="Edit Post" href="http://www.blogger.com/post-edit.g?blogID=35024958&amp;postID=7236229129837214596"><u><font color=#0000ff><span class=quick-edit-icon>&nbsp;</span> </font></u></a></span></span></p>
<p class="post-footer-line post-footer-line-2"><span class=post-labels>Labels: <a href="http://think-async.blogspot.com/search/label/asio" rel=tag><u><font color=#0000ff>asio</font></u></a>, <a href="http://think-async.blogspot.com/search/label/boost" rel=tag><u><font color=#0000ff>boost</font></u></a>, <a href="http://think-async.blogspot.com/search/label/hardware" rel=tag><u><font color=#0000ff>hardware</font></u></a> </span></p>
<p class="post-footer-line post-footer-line-3"></p>
</div>
</div>
<h2 class=date-header>Monday, January 15, 2007</h2>
<div class="post hentry uncustomized-post-template"><a name=993190014642551346></a>
<h3 class="post-title entry-title"><a href="http://think-async.blogspot.com/2007/01/unbuffered-socket-iostreams.html"><u><font color=#0000ff>Unbuffered socket iostreams</font></u></a> </h3>
<div class=post-header-line-1></div>
<div class="post-body entry-content">
<p>Boost.Asio includes an iostreams-based interface to TCP sockets, <code>ip::tcp::iostream</code>, for simple use cases. However, like the file iostreams provided by the standard library, <code>ip::tcp::iostream</code> buffers input and output data. This can lead to problems if you forget to explicitly flush the stream. For example, consider the following code to perform an HTTP request:<br>
<pre>ip::tcp::iostream stream("www.boost.org", "http");<br>stream &lt;&lt; "GET / HTTP/1.0\r\n"<br>       &lt;&lt; "Host: www.boost.org\r\n"<br>       &lt;&lt; "\r\n";<br><br>std::string response_line;<br>std::getline(stream, response_line);<br>...</pre>
The code will be stuck on the <code>getline()</code> call waiting for the response, because the request will still be sitting <code>stream</code>'s output buffer. The correct code looks like this:<br>
<pre>ip::tcp::iostream stream("www.boost.org", "http");<br>stream &lt;&lt; "GET / HTTP/1.0\r\n"<br>       &lt;&lt; "Host: www.boost.org\r\n"<br>       &lt;&lt; "\r\n"<br>       <font color=red>&lt;&lt; std::flush</font>;</pre>
The <code>std::flush</code> will cause the stream to send the entire contents of its output buffer at that point.<br><br>Boost.Asio now supports an alternative solution: turn off the stream's output buffering. This is accomplished as follows:<br>
<pre>ip::tcp::iostream stream("www.boost.org", "http");<br><font color=red>stream.rdbuf()-&gt;pubsetbuf(0, 0);</font><br>stream &lt;&lt; "GET / HTTP/1.0\r\n"<br>       &lt;&lt; "Host: www.boost.org\r\n"<br>       &lt;&lt; "\r\n";</pre>
Now you can send and receive to your heart's content, without having to worry about whether your message is stuck in the output buffer, but be warned: an unbuffered stream is a lot less efficient in terms of system calls. Don't use this feature if you care about performance.</div>
</div>
<img src ="http://www.cppblog.com/ngaut/aggbug/39863.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-12-28 20:43 <a href="http://www.cppblog.com/ngaut/archive/2007/12/28/39863.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]asio Buffer debugging </title><link>http://www.cppblog.com/ngaut/archive/2007/12/28/39862.html</link><dc:creator>ngaut</dc:creator><author>ngaut</author><pubDate>Fri, 28 Dec 2007 12:40:00 GMT</pubDate><guid>http://www.cppblog.com/ngaut/archive/2007/12/28/39862.html</guid><wfw:comment>http://www.cppblog.com/ngaut/comments/39862.html</wfw:comment><comments>http://www.cppblog.com/ngaut/archive/2007/12/28/39862.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ngaut/comments/commentRss/39862.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ngaut/services/trackbacks/39862.html</trackback:ping><description><![CDATA[<h2 class=date-header>Friday, November 10, 2006</h2>
<div class="post hentry uncustomized-post-template"><a name=119676204538372997></a>
<h3 class="post-title entry-title"><a href="http://think-async.blogspot.com/2006/11/buffer-debugging.html"><u><font color=#800080>Buffer debugging</font></u></a> </h3>
<div class=post-header-line-1></div>
<div class="post-body entry-content">
<p>Some standard library implementations, such as the one that ships with MSVC 8.0, provide a nifty feature called iterator debugging. What this means is that the validity of your iterators is checked at runtime. If you try to use an iterator that has been invalidated, you'll get an assertion. For example:<br>
<pre>std::vector&lt;int&gt; v(1)<br>std::vector&lt;int&gt;::iterator i = v.begin();<br>v.clear(); // invalidates iterators<br>*i = 0; // assertion!</pre>
<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">Boost</strong>.<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Asio</strong> now takes advantage of this feature to add buffer debugging. Consider the following code:<br>
<pre>void dont_do_this()<br>{<br> std::string msg = "Hello, world!";<br> <strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>::async_write(sock, <strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>::buffer(msg), my_handler);<br>}</pre>
When you call an asynchronous read or write you need to ensure that the buffers for the operation are valid until the completion handler is called. In the above example, the buffer is the <code>std::string</code> variable <code>msg</code>. This variable is on the stack, and so it goes out of scope before the asynchronous operation completes. If you're lucky, your application will crash. Often you will get random failures.<br><br>With the new buffer debug checking, however, <strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">Boost</strong>.<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Asio</strong> stores an iterator into the string until the asynchronous operation completes, and then dereferences it to check its validity. In the above example you get an assertion failure just before <strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">Boost</strong>.<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Asio</strong> tries to call the completion handler.<br><br>This feature has only been tested with MSVC 8.0 so far, but it should work with any other implementation that supports iterator debugging. Obviously there's a <strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">performance</strong> cost to this checking, so it's only enabled in debug builds. You can also explicitly disable it by defining <code>BOOST_ASIO_DISABLE_BUFFER_DEBUGGING</code> (or <code>ASIO_DISABLE_BUFFER_DEBUGGING</code> if you're using standalone <strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>).
<p>&nbsp;</p>
<div style="CLEAR: both"></div>
</div>
<div class=post-footer>
<p class="post-footer-line post-footer-line-1"><span class="post-author vcard">Posted by <span class=fn>chris</span> </span><span class=post-timestamp>at <a class=timestamp-link title="permanent link" href="http://think-async.blogspot.com/2006/11/buffer-debugging.html" rel=bookmark><abbr class=published title=2006-11-10T09:33:00+11:00><u><font color=#800080>9:33 AM</abbr></font></u></a> </span><span class=post-comment-link></span><span class="post-backlinks post-comment-link"></span><span class=post-icons><span class="item-control blog-admin pid-660467121"><a title="Edit Post" href="http://www.blogger.com/post-edit.g?blogID=35024958&amp;postID=119676204538372997"><u><font color=#0000ff><span class=quick-edit-icon>&nbsp;</span> </font></u></a></span></span></p>
<p class="post-footer-line post-footer-line-2"><span class=post-labels>Labels: <a href="http://think-async.blogspot.com/search/label/asio" rel=tag><strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff"><u>asio</u></strong></a>, <a href="http://think-async.blogspot.com/search/label/boost" rel=tag><strong style="COLOR: black; BACKGROUND-COLOR: #ffff66"><u>boost</u></strong></a> </span></p>
<p class="post-footer-line post-footer-line-3"></p>
</div>
</div>
<div class=comments id=comments><a name=comments></a>
<h4>4 comments: </h4>
<dl id=comments-block>
<dt class=comment-author id=c7021563657052953269><a name=c7021563657052953269></a>andi said...
<dd class=comment-body>
<p>Hi Chris!<br><br>First of all, thanks for the great library!<br><br>I just wondered about the behaviour of this buffer debugging thing if the buffer length is zero, e.g.:<br><br>[...]<br>string content = ...<br>array&lt;<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>::const_buffer, 2&gt; buffers = {<br><strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>::buffer(header_ptr, sizeof(header_t)),<br><strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>::buffer(content)<br>};<br><strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>::async_write(socket_, buffers, <strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">boost</strong>::bind(...));<br><br>This is what I tried to do in my prototype I'm currently building.<br>Well, the problem I ran into is that the content string would sometimes have length 0, and that triggered an assertion failure because (obviously) the iterator could not be dereferenced then.<br>So, I wondered whether this is the intended behaviour (in other words: a feature, not a bug)?</p>
<dd class=comment-footer><span class=comment-timestamp><a title="comment permalink" href="http://think-async.blogspot.com/2006/11/buffer-debugging.html#c7021563657052953269"><font color=#800080><u>August 09, 2007 4:26 AM </u></font></a><span class="item-control blog-admin pid-1296653505"><a title="Delete Comment" href="http://www.blogger.com/delete-comment.g?blogID=35024958&amp;postID=7021563657052953269"><font color=#0000ff><u><span class=delete-comment-icon>&nbsp;</span> </u></font></a></span></span>
<dt class=comment-author id=c5351348731187031276><a name=c5351348731187031276></a><a href="http://www.blogger.com/profile/09159109667366328919" rel=nofollow><u><font color=#800080>chris</font></u></a> said...
<dd class=comment-body>
<p>Hi Andi,<br><br>Actually I fixed this bug not so long ago:<br><br>http://<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>.cvs.sourceforge.net/<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>/<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>/include/<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">asio</strong>/buffer.hpp?r1=1.22&amp;r2=1.23</p>
<dd class=comment-footer><span class=comment-timestamp><a title="comment permalink" href="http://think-async.blogspot.com/2006/11/buffer-debugging.html#c5351348731187031276"><font color=#800080><u>August 15, 2007 11:54 PM </u></font></a><span class="item-control blog-admin pid-660467121"><a title="Delete Comment" href="http://www.blogger.com/delete-comment.g?blogID=35024958&amp;postID=5351348731187031276"><font color=#0000ff><u><span class=delete-comment-icon>&nbsp;</span> </u></font></a></span></span>
<dt class=comment-author id=c4343940823203335352><a name=c4343940823203335352></a><a href="http://www.blogger.com/profile/09159109667366328919" rel=nofollow><u><font color=#800080>chris</font></u></a> said...
<dd class=comment-body>
<p>Let's try that link again:<br><br><a href="http://asio.cvs.sourceforge.net/asio/asio/include/asio/buffer.hpp?r1=1.22&amp;r2=1.23" rel=nofollow><font color=#0000ff><u>diff for bug fix</u></font></a></p>
<dd class=comment-footer><span class=comment-timestamp><a title="comment permalink" href="http://think-async.blogspot.com/2006/11/buffer-debugging.html#c4343940823203335352"><font color=#800080><u>August 15, 2007 11:56 PM </u></font></a><span class="item-control blog-admin pid-660467121"><a title="Delete Comment" href="http://www.blogger.com/delete-comment.g?blogID=35024958&amp;postID=4343940823203335352"><u><font color=#0000ff><span class=delete-comment-icon>&nbsp;</span> </font></u></a></span></span>
<dt class=comment-author id=c3214864233971047230><a name=c3214864233971047230></a>andi said...
<dd class=comment-body>
<p>Oh! Thanks for telling and good luck with your async' arts!</p>
<dd class=comment-footer><span class=comment-timestamp><a title="comment permalink" href="http://think-async.blogspot.com/2006/11/buffer-debugging.html#c3214864233971047230"><font color=#800080><u>August 24, 2007 1:39 AM </u></font></a><span class="item-control blog-admin pid-1296653505"><a title="Delete Comment" href="http://www.blogger.com/delete-comment.g?blogID=35024958&amp;postID=3214864233971047230"><font color=#0000ff><u><span class=delete-comment-icon>&nbsp;</span> </u></font></a></span></span></dd></dl>
<p class=comment-footer><a onclick="" href="http://www.blogger.com/comment.g?blogID=35024958&amp;postID=119676204538372997"><u><font color=#0000ff>Post a Comment</font></u></a> </p>
<div id=backlinks-container>
<div id=Blog1_backlinks-container></div>
</div>
</div>
<img src ="http://www.cppblog.com/ngaut/aggbug/39862.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ngaut/" target="_blank">ngaut</a> 2007-12-28 20:40 <a href="http://www.cppblog.com/ngaut/archive/2007/12/28/39862.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>