title: Ruby TCPServer strange behavior in writing to client
body: <p>I'm creating a Ruby gem named EmeraldCutter which is, essentially, a very simple TCP server. It happens that I detected a very strange behavior and I'd be very glad if someone could give me some clue about this.</p>
  
  <p>As you may see by the code below, it starts a new Thread for each request received, grabs the message sent to the server, separate its parameters and stores them in a hash and then writes to the client a list with the elements of this hash in a list of the form</p>
  
  <pre><code>key =&gt; parameter
  </code></pre>
  
  <p>Then when I run this server and navigate to <code>http://localhost:4321/something</code> my browser should receive something like </p>
  
  <pre><code>http_verb =&gt; GET
  query_string =&gt; /something
  http_version =&gt; HTTP/1.1
  host =&gt; localhost:4321
  connection =&gt; keep-alive
  cache_control =&gt; max-age=0
  accept =&gt; text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  upgrade_insecure_requests =&gt; 1
  user_agent =&gt; Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
  dnt =&gt; 1
  accept_encoding =&gt; gzip, deflate, sdch
  accept_language =&gt; pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4,fr-CA;q=0.2,fr;q=0.2
  </code></pre>
  
  <p>but nothing is displayed and when I visit the Network tab at the developer's console to examine this request, I see a message saying <code>Failed to load response data</code>.</p>
  
  <p>Here is my code:</p>
  
  <p><strong>lib/emerald.rb</strong></p>
  
  <pre><code>require "emeraldcutter/auxiliary"
  require "emeraldcutter/version"
  
  module EmeraldCutter
  
    def self.start
      require 'socket'
  
      server = TCPServer.new 4321
      loop do 
        Thread.start(server.accept) do |client|
          message = client.recvmsg[0]
          request = get_request_parameters(message)
          request.each{ |k,v| client.puts "#{k} =&gt; #{v}" }
          client.close
        end
      end
    end
  
    private
  
    def self.http_verb(msg_token)
      msg_token.split(' ')[0]
    end
  
    def self.http_protocol(msg_token)
      msg_token.split(' ')[2]
    end
  
    def self.query_string(msg_token)
      msg_token.split(' ')[1]
    end
  
    def self.get_request_parameters(message)
      result = Hash.new
      lines = message.split("\n");
      first_line = lines.shift
      result['http_verb'] = http_verb(first_line)
      result['query_string'] = query_string(first_line)
      result['http_version'] = http_protocol(first_line)
      lines.each{ |line|
        key_value = line.split(': ')
        key = EmeraldCutter::Auxiliary.normalize_hash_key(key_value[0].strip)
        result[key] = key_value[1].strip if not key.empty?
      }
      result
    end
  
  end
  </code></pre>
  
  <p><strong>lib/emeraldcutter/auxiliary.rb</strong></p>
  
  <pre><code>module EmeraldCutter
    module Auxiliary
  
      def self.normalize_hash_key(key)
        key.downcase.tr('-','_')
      end
  
    end
  end
  </code></pre>
  
  <p>This wouldn't be so strange. But things get really weird when I add <code>client.puts "Teste"</code> to the Thread block like this</p>
  
  <pre><code>    server = TCPServer.new 4321
      loop do 
        Thread.start(server.accept) do |client|
          client.puts "Test"
          message = client.recvmsg[0]
          request = get_request_parameters(message)
          request.each{ |k,v| client.puts "#{k} =&gt; #{v}" }
          client.close
        end
      end
    end
  </code></pre>
  
  <p>and then it works perfectly well and I get</p>
  
  <pre><code>Test
  http_verb =&gt; GET
  query_string =&gt; /something
  http_version =&gt; HTTP/1.1
  host =&gt; localhost:4321
  connection =&gt; keep-alive
  cache_control =&gt; max-age=0
  accept =&gt; text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  upgrade_insecure_requests =&gt; 1
  user_agent =&gt; Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
  dnt =&gt; 1
  accept_encoding =&gt; gzip, deflate, sdch
  accept_language =&gt; pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4,fr-CA;q=0.2,fr;q=0.2
  </code></pre>
  
  <p>Have you ever seen something like this? If so, what is the reason?</p>