title: int/char conversion in network frames with C++/boost::asio
body: <p>Using g++ and boost::asio, I'm trying to format network message frames containing the size of the data to be transmited:</p>
  
  <pre><code>+----------------+------------------------+
  |  Length        |  Message string        |
  |        4 bytes |                n bytes |
  +----------------+------------------------+
  </code></pre>
  
  <p>Using the examples of asio blocking tcp echo client/server under a 32 byte Linux, I'm stucked with transmitting the correct size in the frame. The client is supposed to be a Windows machine.</p>
  
  <p>CLIENT:</p>
  
  <pre><code>#include &lt;cstdlib&gt;
  #include &lt;cstring&gt;
  #include &lt;iostream&gt;
  #include &lt;boost/asio.hpp&gt;
  #include &lt;stdint.h&gt;
  #include &lt;arpa/inet.h&gt;
  
  using boost::asio::ip::tcp;
  
  enum { max_length = 1024 };
  
  int main(int argc, char* argv[])
  {
    try
    {
      if (argc != 3)
      {
        std::cerr &lt;&lt; "Usage: blocking_tcp_echo_client &lt;host&gt; &lt;port&gt;\n";
        return 1;
      }
  
      boost::asio::io_service io_service;
  
      tcp::resolver resolver(io_service);
      tcp::resolver::query query(tcp::v4(), argv[1], argv[2]);
      tcp::resolver::iterator iterator = resolver.resolve(query);
  
      tcp::socket s(io_service);
      s.connect(*iterator);
  
      std::cout &lt;&lt; "sizeof uint32_t=" &lt;&lt; sizeof(uint32_t) &lt;&lt; std::endl;
  
      uint32_t len = 1234;
      std::cout &lt;&lt; "len=" &lt;&lt; len &lt;&lt; std::endl;
  
      // uint =&gt; char 4
      char char_len[4];
      char_len[0] = (len &gt;&gt; 0);
      char_len[1] = (len &gt;&gt; 8);
      char_len[2] = (len &gt;&gt; 16);
      char_len[3] = (len &gt;&gt; 24);
  
      std::cout &lt;&lt; "char[4] len=[" 
          &lt;&lt; char_len[0] &lt;&lt; ',' &lt;&lt; char_len[1] &lt;&lt; ',' 
          &lt;&lt; char_len[2] &lt;&lt; ',' &lt;&lt; char_len[3] &lt;&lt; ']' 
          &lt;&lt; std::endl;
  
      // char 4 =&gt; uint
      uint32_t uint_len = *(reinterpret_cast&lt;uint32_t *&gt;( char_len ));
      std::cout &lt;&lt; "uint len=" &lt;&lt; uint_len &lt;&lt; std::endl;
  
      // network bytes order
      uint32_t net_len = htonl( len );
      std::cout &lt;&lt; "net_len=" &lt;&lt; net_len &lt;&lt; std::endl;
  
      // uint =&gt; char 4
      char net_char_len[4];
      net_char_len[0] = (net_len &gt;&gt; 0);
      net_char_len[1] = (net_len &gt;&gt; 8);
      net_char_len[2] = (net_len &gt;&gt; 16);
      net_char_len[3] = (net_len &gt;&gt; 24);
  
      std::cout &lt;&lt; "net char[4] len=[" 
          &lt;&lt; net_char_len[0] &lt;&lt; ',' &lt;&lt; net_char_len[1] &lt;&lt; ',' 
          &lt;&lt; net_char_len[2] &lt;&lt; ',' &lt;&lt; net_char_len[3] &lt;&lt; ']' 
          &lt;&lt; std::endl;
  
      boost::asio::write(s, boost::asio::buffer(char_len, 4));
  
      char reply[max_length];
      size_t reply_length = boost::asio::read(s,
          boost::asio::buffer(reply, 1 ));
      std::cout &lt;&lt; "Reply is: ";
      std::cout.write(reply, reply_length);
      std::cout &lt;&lt; "\n";
    }
    catch (std::exception&amp; e)
    {
      std::cerr &lt;&lt; "Exception: " &lt;&lt; e.what() &lt;&lt; "\n";
    }
  
    return 0;
  }
  </code></pre>
  
  <p>SERVER:</p>
  
  <pre><code>#include &lt;cstdlib&gt;
  #include &lt;iostream&gt;
  #include &lt;boost/bind.hpp&gt;
  #include &lt;boost/smart_ptr.hpp&gt;
  #include &lt;boost/asio.hpp&gt;
  #include &lt;boost/thread.hpp&gt;
  
  using boost::asio::ip::tcp;
  
  const int max_length = 1024;
  
  typedef boost::shared_ptr&lt;tcp::socket&gt; socket_ptr;
  
  void session(socket_ptr sock)
  {
    try
    {
      for (;;)
      {
        char data[max_length];
  
        boost::system::error_code error;
        size_t length = sock-&gt;read_some(boost::asio::buffer(data), error);
        if (error == boost::asio::error::eof)
          break; // Connection closed cleanly by peer.
        else if (error)
          throw boost::system::system_error(error); // Some other error.
  
        uint32_t net_len;
        size_t len_len = sock-&gt;read_some( boost::asio::buffer( reinterpret_cast&lt;char*&gt;(&amp;net_len), 4), error );
        std::clog &lt;&lt; "net len=" &lt;&lt; net_len &lt;&lt; std::endl;
        uint32_t len = ntohl( net_len );
        std::clog &lt;&lt; "uint len=" &lt;&lt; len &lt;&lt; std::endl;
  
        char char_len = (char)len;
        std::clog &lt;&lt; "char len=" &lt;&lt; len &lt;&lt; std::endl;
  
        boost::asio::write(*sock, boost::asio::buffer( &amp;char_len, size_t(1)));
      }
    }
    catch (std::exception&amp; e)
    {
      std::cerr &lt;&lt; "Exception in thread: " &lt;&lt; e.what() &lt;&lt; "\n";
    }
  }
  
  void server(boost::asio::io_service&amp; io_service, short port)
  {
    tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
    for (;;)
    {
      socket_ptr sock(new tcp::socket(io_service));
      a.accept(*sock);
      boost::thread t(boost::bind(session, sock));
    }
  }
  
  int main(int argc, char* argv[])
  {
    try
    {
      if (argc != 2)
      {
        std::cerr &lt;&lt; "Usage: blocking_tcp_echo_server &lt;port&gt;\n";
        return 1;
      }
  
      boost::asio::io_service io_service;
  
      std::cout &lt;&lt; "Started" &lt;&lt; std::endl;
      std::cout &lt;&lt; "sizeof uint32_t=" &lt;&lt; sizeof(uint32_t) &lt;&lt; std::endl;
      using namespace std; // For atoi.
      server(io_service, atoi(argv[1]));
    }
    catch (std::exception&amp; e)
    {
      std::cerr &lt;&lt; "Exception: " &lt;&lt; e.what() &lt;&lt; "\n";
    }
  
    return 0;
  }
  </code></pre>
  
  <p>Should compile with a simple script:</p>
  
  <pre><code>g++ -o client -I/usr/include/boost -L/usr/lib -lboost_system -lboost_thread-mt  client.cpp
  g++ -o server -I/usr/include/boost -L/usr/lib -lboost_system -lboost_thread-mt  server.cpp
  </code></pre>
  
  <p>The client is unable to decode the length and the server does not seems to receive the right irt. What am I missing?</p>