XP: "An existing connection was forcibly closed" ECONNRESET

Hello,
I am running Ruby 1-185-21 on Win XP without any proxy enabled.
When trying to connect to HTTP server (both server and client are my
Ruby scripts) at localhost I get this error:
"
c:/usr/ruby/lib/ruby/1.8/net/protocol.rb:133:in `sysread’: An existing
connection was forcibly closed by the remote host. (Errno::ECONNRESET)
"

Interesting facts:

  1. Firefox works without any problems with my Ruby server!!!
  2. IE doesn’t work with my Ruby server!!!
  3. My client works fine with all other HTTP servers on the Internet,
    except for my Ruby server on localhost :frowning:

(see bellow complete trace of this error and source of my simple server
and client)

Any ideas?
Thanks,
Dima

=== localhost error trace:

ruby test-serv.rb localhost 10001
[Sat Sep 23 01:22:16 2006] TimeServer 127.0.0.1:10001 start
Server started...
Connecting to server localhost:10001 at Sat Sep 23 01:22:21 +0400 2006
[Sat Sep 23 01:22:21 2006] TimeServer 127.0.0.1:10001 client:1203 
localhost<127.0.0.1> connect
[Sat Sep 23 01:22:21 2006] TimeServer 127.0.0.1:10001 client:1203 
disconnect
[Sat Sep 23 01:22:21 2006] TimeServer 127.0.0.1:10001 stop
c:/usr/ruby/lib/ruby/1.8/net/protocol.rb:133:in `sysread': An existing 
connection was forcibly closed by the remote host. (Errno::ECONNRESET)
        from c:/usr/ruby/lib/ruby/1.8/net/protocol.rb:133:in `rbuf_fill'
        from c:/usr/ruby/lib/ruby/1.8/timeout.rb:56:in `timeout'
        from c:/usr/ruby/lib/ruby/1.8/timeout.rb:76:in `timeout'
        from c:/usr/ruby/lib/ruby/1.8/net/protocol.rb:132:in `rbuf_fill'
        from c:/usr/ruby/lib/ruby/1.8/net/protocol.rb:116:in `readuntil'
        from c:/usr/ruby/lib/ruby/1.8/net/protocol.rb:126:in `readline'
        from c:/usr/ruby/lib/ruby/1.8/net/http.rb:2017:in 
`read_status_line'
        from c:/usr/ruby/lib/ruby/1.8/net/http.rb:2006:in `read_new'
        from c:/usr/ruby/lib/ruby/1.8/net/http.rb:1047:in `request'
        from c:/usr/ruby/lib/ruby/1.8/net/http.rb:1034:in `request'
        from c:/usr/ruby/lib/ruby/1.8/net/http.rb:543:in `start'
        from c:/usr/ruby/lib/ruby/1.8/net/http.rb:1032:in `request'
        from c:/usr/ruby/lib/ruby/1.8/net/http.rb:769:in `get'
        from test-serv.rb:35

=== no error trace:

C:\wks\ruby-wks>ruby test-serv.rb www.rubycentral.com 80
Connecting to server www.rubycentral.com:80 at Sat Sep 23 01:29:28 +0400 
2006
Code: 200 Msg: OK
Connecting to server www.rubycentral.com:80 at Sat Sep 23 01:29:34 +0400 
2006
Code: 200 Msg: OK

=== source:
require 'gserver'
require 'net/http'

  TIME_OUT  = 5
  host      = ARGV[0]
  port      = ARGV[1]


  if host == 'localhost' then
  #
  # A server that returns the time in seconds since 1970.
  #

    class TimeServer < GServer
      def initialize(port=10001, *args)
        super(port, *args)
      end
      def serve(io)
        io.puts(Time.now.to_i)
      end
    end

    # Run the server with logging enabled (it's a separate thread).
    server = TimeServer.new
    server.audit = true                  # Turn logging on.
    server.start
    puts "Server started...\n"
  end #host == 'localhost'

  # Test server
  while (true)
    sleep TIME_OUT
    puts("Connecting to server #{host}:#{port} at #{Time.now}\n")
    h = Net::HTTP.new(host,port)
    res, data = h.get('/index.html', nil )
    puts("Code: #{res.code} Msg: #{res.message}\n")
  end

Dima,

You’re connecting to the server using HTTP, so the server should
return valid HTTP header, i.e.:

 class TimeServer < GServer
   def initialize(port=10001, *args)
     super(port, *args)
   end
   def serve(io)
     str = "HTTP/1.0 200 OK\r\n\r\n#{Time.now.to_i}"
     puts str
     io.puts(str)
   end
 end

Haven’t tried it on Windows, but this works on Mac whereas your
version fails as you described.

Best,
Mike D.
http://www.rubywizards.com

Mike,
This doesn’t help. Before, eventually looking into the source of
gserver.rb I tried my code on Debian Linux - same error. Which is good,
at least Ruby is consistent accross platforms.
If you look at gserver.rb you will see that this server closes client
socket right after it servers it, which he must not do and which
perfectly explains why gserver.rb does not work correctly.
Also see my coments (#dk:) inline:

Dima,

You’re connecting to the server using HTTP, so the server should
return valid HTTP header, i.e.:

 class TimeServer < GServer
   def initialize(port=10001, *args)
     super(port, *args)
   end
   def serve(io)
     str = "HTTP/1.0 200 OK\r\n\r\n#{Time.now.to_i}"
     puts str
       ~~~~~~~~

#dk: This may confuse: server itself outputs its own response

     io.puts(str)
   end
 end

Haven’t tried it on Windows, but this works on Mac whereas your
version fails as you described.

gserver.rb closes client socket right after serving it :frowning:
From gserver.rb:

      client = @tcpServer.accept
      @connections << Thread.new(client)  { |myClient|
        begin
          myPort = myClient.peeraddr[1]
          serve(myClient) if !@audit or connecting(myClient)
        rescue => detail
          error(detail) if @debug
        ensure
          begin
            myClient.close
          rescue
          end
          @connectionsMutex.synchronize {
            @connections.delete(Thread.current)
            @connectionsCV.signal
          }
          disconnecting(myPort) if @audit
        end
      }
    end

Dima

On 9/22/06, Dmitri K. [email protected] wrote:

Hello,
I am running Ruby 1-185-21 on Win XP without any proxy enabled.
When trying to connect to HTTP server (both server and client are my
Ruby scripts) at localhost I get this error:
"
c:/usr/ruby/lib/ruby/1.8/net/protocol.rb:133:in `sysread’: An existing
connection was forcibly closed by the remote host. (Errno::ECONNRESET)
"

I don’t have anything useful to say about the possible problem in
gserver,
but if you’re interested in an alternative approach to your application,
look at the EventMachine library in Rubyforge.

Francis C. wrote:

I don’t have anything useful to say about the possible problem in
gserver,
but if you’re interested in an alternative approach to your application,
look at the EventMachine library in Rubyforge.

Thanks, I am looking at it now. I need some good messaging framework for
Ruby IPC, maybe EventMachine is just what I need!

Thanks again!
Dima