title: garbage text with c++ strings on send recv calls
body: <pre><code>// In server.cpp after connection has established
  
  std::string input;
  input.reserve(5);
  std::cout &lt;&lt; "Enter message to send: ";
  
  std::cin.ignore();  // =====(1)=====
  
  std::getline(std::cin, input);
  std::cout &lt;&lt; "Sending..." &lt;&lt; std::endl;
  auto len        = input.length();
  
  auto bytes_sent = send(newFD, input.data(), len, 0); // =====(2)=====
  
  std::cout &lt;&lt; "Input length : " &lt;&lt; input.length() &lt;&lt; std::endl
            &lt;&lt; "Input bytes sent : " &lt;&lt; bytes_sent &lt;&lt; std::endl;
  </code></pre>
  
  <p>My aim is to use <code>std::string</code> instead of plain old <code>char[fixed]</code> in simple <em>tcp client server</em> program. So in <code>server.cpp</code> I have 2 doubts. So far my initial guesses are working as expected. I've marked them above in code. </p>
  
  <ol>
  <li><code>cin.ignore()</code> <strong>vs</strong> <code>cin.clear()</code> <strong>+</strong> <code>cin.sync()</code></li>
  <li><code>std::string.data()</code> <strong>vs</strong> <code>std::string.c_str()</code></li>
  </ol>
  
  <p>Which should I use? I'm not even sure of the difference b/w any of these and I don't know if they're contributing to my problem.</p>
  
  <hr>
  
  <pre><code>// In client.cpp 
  
  std::string message;
  message.reserve(5);
  auto len        = message.capacity();
  
  auto bytes_recv = recv(sockFD, &amp;message.front(), len - 1, 0);  // =====(1)=====
  
  message[len] = 0; // =====(2)=====
  
  close(sockFD);
  freeaddrinfo(res);
  std::cout &lt;&lt; "Bytes recieved :" &lt;&lt; bytes_recv &lt;&lt; std::endl;
  
  std::cout &lt;&lt; message.c_str() &lt;&lt; std::endl;  // =====(3)=====
  </code></pre>
  
  <hr>
  
  <p>And in client.cpp, everything goes wrong when I try to send bigger strings. But I probably know the cause, however solution is somewhat tricky to implement.</p>
  
  <ol start="3">
  <li>Am I doing right thing to pass <code>&amp;std::string.front()</code> to write incoming data?</li>
  <li>This is wrong, string class should manage this, right? However since I'm directly writing to <code>&amp;front()</code>, I guess <code>length</code> won't get updated or I'm not sure what happens but data surely gets lost when outputting with <code>std::cout &lt;&lt; message;</code>.</li>
  <li>I'm doing this just because I'm directly writing to <code>&amp;front</code>, still it produces garbage if somehow data returned is smaller than total length, probably because it cannot find terminating character at right place?</li>
  </ol>
  
  <hr>
  
  <blockquote>
    <p><strong>server.cpp</strong></p>
    
    <p><code>// compile as 'g++ server.cpp -o server.app -std=c++14'</code></p>
    
    <p><code>// run as : './server.app 8080'</code></p>
  </blockquote>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;cstring&gt;
  
  extern "C" {
  #include &lt;unistd.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;netdb.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;netinet/in.h&gt;
  }
  
  int main(int argc, char *argv[])
  {
      if(argc != 2) {
          std::cerr &lt;&lt; "Run program as 'program port'" &lt;&lt; std::endl;
          return -1;
      }
      auto &amp;portNum              = argv[1];
      const unsigned int backLog = 5;
  
      struct addrinfo hints, *res, *p;
      memset(&amp;hints, 0, sizeof(hints));
      hints.ai_family   = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_flags    = AI_PASSIVE;
  
      int gAddRes = getaddrinfo(NULL, portNum, &amp;hints, &amp;res);
      if(gAddRes != 0) {
          std::cerr &lt;&lt; gai_strerror(gAddRes) &lt;&lt; std::endl;
          return -2;
      }
  
      std::cout &lt;&lt; "Detecting addresses" &lt;&lt; std::endl;
  
      unsigned int numOfAddr = 0;
      char ipStr[INET6_ADDRSTRLEN];
  
      for(p = res; p != NULL; p = p-&gt;ai_next) {
          void *addr;
          std::string ipVer = "IPv0";
  
          if(p-&gt;ai_family == AF_INET) {
              ipVer                    = "IPv4";
              struct sockaddr_in *ipv4 = (struct sockaddr_in *)p-&gt;ai_addr;
              addr                     = &amp;(ipv4-&gt;sin_addr);
              ++numOfAddr;
          }
  
          else {
              ipVer                     = "IPv6";
              struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p-&gt;ai_addr;
              addr                      = &amp;(ipv6-&gt;sin6_addr);
              ++numOfAddr;
          }
  
          inet_ntop(p-&gt;ai_family, addr, ipStr, sizeof(ipStr));
          std::cout &lt;&lt; "(" &lt;&lt; numOfAddr &lt;&lt; ") " &lt;&lt; ipVer &lt;&lt; " : " &lt;&lt; ipStr
                    &lt;&lt; std::endl;
      }
  
      if(!numOfAddr) {
          std::cerr &lt;&lt; "Found no host address to use" &lt;&lt; std::endl;
          return -3;
      }
  
      std::cout &lt;&lt; "Enter the number of host address to bind with:" &lt;&lt; std::endl;
      unsigned int choice = 0;
      bool madeChoice     = false;
      do {
          std::cin &gt;&gt; choice;
          if(choice &gt; (numOfAddr + 1) || choice &lt; 1) {
              madeChoice = false;
              std::cout &lt;&lt; "Wrong choice, try again!" &lt;&lt; std::endl;
          }
          else
              madeChoice = true;
      } while(!madeChoice);
  
      p           = res;
      bool isIPv4 = true;
      if(choice &gt; 1) {
          unsigned int temp = 1;
          while(choice &lt; temp) {
              p = p-&gt;ai_next;
              ++temp;
          }
          if(p-&gt;ai_family == AF_INET) {
              isIPv4 = true;
          }
          else
              isIPv4 = false;
      }
  
      int sockFD = socket(p-&gt;ai_family, p-&gt;ai_socktype, p-&gt;ai_protocol);
      if(sockFD == -1) {
          std::cerr &lt;&lt; "Error while creating socket" &lt;&lt; std::endl;
          freeaddrinfo(res);
          return -4;
      }
  
      int bindR = bind(sockFD, p-&gt;ai_addr, p-&gt;ai_addrlen);
      if(bindR == -1) {
          std::cerr &lt;&lt; "Error while binding socket" &lt;&lt; std::endl;
          close(sockFD);
          freeaddrinfo(res);
          return -5;
      }
  
      int listenR = listen(sockFD, backLog);
      if(listenR == -1) {
          std::cerr &lt;&lt; "Error while Listening on socket" &lt;&lt; std::endl;
          close(sockFD);
          freeaddrinfo(res);
          return -6;
      }
  
      struct sockaddr_storage client_addr;
      socklen_t client_addr_size = sizeof(client_addr);
      int newFD =
          accept(sockFD, (struct sockaddr *)&amp;client_addr, &amp;client_addr_size);
      if(newFD == -1) {
          std::cerr &lt;&lt; "Error while Accepting on socket" &lt;&lt; std::endl;
          close(sockFD);
          freeaddrinfo(res);
          return -7;
      }
  
  
      std::string input;
      input.reserve(5);
      std::cout &lt;&lt; "Enter message to send: ";
      std::cin.ignore();
      std::getline(std::cin, input);
      std::cout &lt;&lt; "Sending..." &lt;&lt; std::endl;
      auto len        = input.length();
      auto bytes_sent = send(newFD, input.data(), len, 0);
      std::cout &lt;&lt; "Input length : " &lt;&lt; input.length() &lt;&lt; std::endl
                &lt;&lt; "Input bytes sent : " &lt;&lt; bytes_sent &lt;&lt; std::endl;
      close(newFD);
      close(sockFD);
      freeaddrinfo(res);
  
      return 0;
  }
  </code></pre>
  
  <blockquote>
    <p><strong>client.cpp</strong></p>
    
    <p><code>// compile as 'g++ client.cpp -o client.app -std=c++14'</code></p>
    
    <p><code>// run as : './client.app 0 8080'</code></p>
  </blockquote>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;cstring&gt;
  
  extern "C" {
  #include &lt;unistd.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;netdb.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;netinet/in.h&gt;
  }
  
  int main(int argc, char *argv[])
  {
      if(argc != 3) {
          std::cerr &lt;&lt; "Run program as 'program ipaddress port'" &lt;&lt; std::endl;
          return -1;
      }
      auto &amp;ipAddress = argv[1];
      auto &amp;portNum   = argv[2];
  
      struct addrinfo hints, *res, *p;
      memset(&amp;hints, 0, sizeof(hints));
      hints.ai_family   = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_flags    = AI_PASSIVE;
  
      int gAddRes = getaddrinfo(ipAddress, portNum, &amp;hints, &amp;res);
      if(gAddRes != 0) {
          std::cerr &lt;&lt; gai_strerror(gAddRes) &lt;&lt; std::endl;
          return -2;
      }
  
      std::cout &lt;&lt; "Detecting addresses" &lt;&lt; std::endl;
  
      unsigned int numOfAddr = 0;
      char ipStr[INET6_ADDRSTRLEN];
  
      for(p = res; p != NULL; p = p-&gt;ai_next) {
          void *addr;
          std::string ipVer = "IPv0";
  
          if(p-&gt;ai_family == AF_INET) {
              ipVer                    = "IPv4";
              struct sockaddr_in *ipv4 = (struct sockaddr_in *)p-&gt;ai_addr;
              addr                     = &amp;(ipv4-&gt;sin_addr);
              ++numOfAddr;
          }
  
          else {
              ipVer                     = "IPv6";
              struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p-&gt;ai_addr;
              addr                      = &amp;(ipv6-&gt;sin6_addr);
              ++numOfAddr;
          }
  
          inet_ntop(p-&gt;ai_family, addr, ipStr, sizeof(ipStr));
          std::cout &lt;&lt; "(" &lt;&lt; numOfAddr &lt;&lt; ") " &lt;&lt; ipVer &lt;&lt; " : " &lt;&lt; ipStr
                    &lt;&lt; std::endl;
      }
  
      if(!numOfAddr) {
          std::cerr &lt;&lt; "Found no host address to use" &lt;&lt; std::endl;
          return -3;
      }
  
      std::cout &lt;&lt; "Enter the number of host address to bind with:" &lt;&lt; std::endl;
      unsigned int choice = 0;
      bool madeChoice     = false;
      do {
          std::cin &gt;&gt; choice;
          if(choice &gt; (numOfAddr + 1) || choice &lt; 1) {
              madeChoice = false;
              std::cout &lt;&lt; "Wrong choice, try again!" &lt;&lt; std::endl;
          }
          else
              madeChoice = true;
      } while(!madeChoice);
  
      p           = res;
      bool isIPv4 = true;
      if(choice &gt; 1) {
          unsigned int temp = 1;
          while(choice &lt; temp) {
              p = p-&gt;ai_next;
              ++temp;
          }
          if(p-&gt;ai_family == AF_INET) {
              isIPv4 = true;
          }
          else
              isIPv4 = false;
      }
  
      int sockFD = socket(p-&gt;ai_family, p-&gt;ai_socktype, p-&gt;ai_protocol);
      if(sockFD == -1) {
          std::cerr &lt;&lt; "Error while creating socket" &lt;&lt; std::endl;
          return -4;
      }
  
      int connectR = connect(sockFD, p-&gt;ai_addr, p-&gt;ai_addrlen);
      if(connectR == -1) {
          close(sockFD);
          std::cerr &lt;&lt; "Error while connecting socket" &lt;&lt; std::endl;
          return -5;
      }
  
      std::string message;
      message.reserve(5);
      auto len        = message.capacity();
      auto bytes_recv = recv(sockFD, &amp;message.front(), len - 1, 0);
      message[len] = 0;
      close(sockFD);
      freeaddrinfo(res);
      std::cout &lt;&lt; "Bytes recieved :" &lt;&lt; bytes_recv &lt;&lt; std::endl;
      std::cout &lt;&lt; message.c_str() &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>