Question

J'ai un serveur TCP très basique mis en œuvre en Ruby. En général, il fait ce qu'il est censé, mais chaque fois en temps, je reçois « La connexion au serveur a été remis à zéro alors que la page a été chargement » erreur. J'ai le sentiment qu'il a quelque chose à voir avec close terminer la connexion trop tôt. Si oui, comment puis-je attendre que toutes les données à envoyer? Ou est-ce autre chose?

require 'socket'

server = TCPServer.new('', 80)
loop do
    session = server.accept
    begin
        session.print Time.now
    ensure
        session.close
    end
end
Était-ce utile?

La solution

Je soupçonne que c'est parce que le navigateur attend une réponse HTTP avec les en-têtes et c. Chose curieuse, vous pouvez faire l'erreur « reset » arrive à chaque fois que si vous mettez avant la « assurer » un sommeil de, disons, une seconde.

Résolution du problème dépend de ce que vous recherchez. Si ce ne doit pas être un serveur HTTP, alors ne pas utiliser le navigateur pour le tester. Au lieu de cela, utilisez telnet ou écrire un petit programme. Si elle doit être un serveur HTTP, puis jeter un oeil à webrick , qui est construit en Ruby IRM> = 1,8. Voici comment:

#!/usr/bin/ruby1.8

require 'webrick'

# This class handles time requests

class TimeServer < WEBrick::HTTPServlet::AbstractServlet

  def do_GET(request, response)
    response.status = 200
    response['Content-Type'] = 'text/plain'
    response.body = Time.now.to_s
  end

end

# Create the server.  There are many other options, if you need them.
server = WEBrick::HTTPServer.new(:Port=>8080)

# Whenever a request comes in for the root page, use TimeServer to handle it
server.mount('/', TimeServer)

# Finally, start the server.  Does not normally return.
server.start

Autres conseils

Je ne suis pas un expert dans ce domaine, mais voici ce que je crois qui se passe ....

Le navigateur envoie une requête GET avec le champ d'en-tête « Connexion: keep-alive ». Ainsi, le navigateur attend à maintenir la connexion au moins jusqu'à ce qu'il reçoive un morceau complet de la réponse. En vertu de ce protocole, la réponse du serveur doit inclure un en-tête spécifiant la longueur de la réponse, de sorte que le navigateur sait quand il a reçu la réponse complète. Après ce point, la connexion peut être fermée sans la prise en charge du navigateur.

L'exemple d'origine ferme la connexion trop rapidement, avant que le navigateur peut valider qu'une réponse complète a été reçue. Curieusement, si je lance cet exemple et tranquillise mon navigateur plusieurs fois, il charge environ tous les 1 à 10 essais. Peut-être que ce comportement erratique est dû au navigateur d'exécuter de temps en temps assez rapide pour battre mon serveur fermer la connexion.

Ci-dessous un exemple de code qui exécute de manière cohérente dans mon navigateur:

require 'socket'

response = %{HTTP/1.1 200 OK
Content-Type: text;charset=utf-8
Content-Length: 12

Hello World!
}

server = TCPServer.open(80)

loop do
  client = server.accept
  client.puts response
  sleep 1
  client.close
end

En outre, devrait noter que l'inclusion Connection: close dans l'en-tête de réponse ne me semble pas aider du tout avec cette erreur de réinitialisation de la connexion dans mon navigateur (FFv3.6). Je dois inclure à la fois le champ d'en-tête de content-length, et notamment de la méthode de sleep pour mettre un peu de retard dans la fermeture de la connexion afin d'obtenir une réponse cohérente dans mon navigateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top