title: boost::asio separate array for each client
body: <p>I learned C++ and now I would like to move on and learn some network programming. I decided to use boost::asio because it's multiplatform. I wrote this simple program:</p>
  
  <p>client:</p>
  
  <pre><code>#include &lt;cstdlib&gt;
  #include &lt;cstring&gt;
  #include &lt;iostream&gt;
  #include &lt;boost/asio.hpp&gt;
  
  using boost::asio::ip::tcp;
  
  enum { max_length = 1000000 };
  
  int main(int argc, char* argv[])
  {
      while(1)
        {
  
    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);
  
      using namespace std; // For strlen.
  
      std::cout &lt;&lt; "Enter message: ";
      char request[max_length];
      std::cin.getline(request, max_length);
      if (request == "\n")
        continue;
  
      size_t request_length = strlen(request);
      boost::asio::write(s, boost::asio::buffer(request, request_length));
  
      char reply[max_length];
      boost::system::error_code error;
      size_t reply_length = s.read_some(boost::asio::buffer(reply), 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.
  
  
  
  
      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";
      exit(1);
    }
    }
  
    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;
  #include &lt;boost/regex.hpp&gt; 
  #include &lt;boost/lexical_cast.hpp&gt;
  #include &lt;string&gt;
  
  using boost::asio::ip::tcp;
  const int max_length = 1000000;
  
  std::string user_array[100];
  
  typedef boost::shared_ptr&lt;tcp::socket&gt; socket_ptr;
  
  unsigned short analyze_user_request(std::string&amp; user_request, short unsigned* ID, std::string* request_value)
  {
    // function returns:
    // 0: if user request is incorrect
    // 1: if user requests "PUT" operation
    // 2: if user requests "GET" operation
    // Furthermore, if request is correct, its value (i.e. ID number and/or string) is saved to short unsigned and string values passed by pointers. 
  
   boost::regex exp("^[[:space:]]*(PUT|GET)[[:space:]]+([[:digit:]]{1,2})(?:[[:space:]]+(.*))?$");
  
    boost::smatch what; 
    if (regex_match(user_request, what, exp, boost::match_extra)) 
     { 
       short unsigned id_number = boost::lexical_cast&lt;short unsigned&gt;(what[2]);
  
       if (what[1] == "PUT")
         {
           boost::regex exp1("^[a-zA-Z0-9]+$");
       std::string value = boost::lexical_cast&lt;std::string&gt;(what[3]);
       if (value.length() &gt; 4095)
         return 0;
       if (!regex_match(value, exp1))
         return 0;
       else
         {
            *request_value = value;
            *ID = id_number;
           return 1;
             }
         }
  
       if (what[1] == "GET")
         {
       *ID = id_number;
           return 2;
         }
  
     }
  
    if (!regex_match(user_request, what, exp, boost::match_extra)) 
      return 0;
     }
  
  
  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.
        // convert buffer data to string for further procession
        std::string line(boost::asio::buffers_begin(boost::asio::buffer(data)), boost::asio::buffers_begin(boost::asio::buffer(data)) + length);
        std::string reply; // will be "QK", "INVALID", or "OK &lt;value&gt;"
             unsigned short vID;
  
        unsigned short* ID = &amp;vID;
        std::string vrequest_value;
        std::string* request_value = &amp;vrequest_value;
  
        unsigned short output = analyze_user_request(line, ID, request_value);
  
        if (output == 1)
      {
      // PUT    
        reply = "OK";
        user_array[*ID] = *request_value;
      }
  
          else if (output == 2)
        {
          // GET
          reply = user_array[*ID];
          if (reply == "")
            reply = "EMPTY";
  
        }
  
      else
        reply = "INVALID";
  
              boost::system::error_code ignored_error;
              size_t ans_len=reply.length();
          boost::asio::write(*sock, boost::asio::buffer(reply));
      }
    }
    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;
  
      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>Basically, it's an application that allows user to store data on server. User can insert new data using PUT command followed by ID number and data value, and retrieve data using GET command followed by ID. User requests are processed in analyze_user_request function and are subsequently written to or read from array. The problem is that now all clients are using the same global arry. That means that if one client saves something under particular ID all other clients can read it, because they access the same array. I wonder, how can I associate array with different clients, and create a new array when a new client connects?</p>