2

I'm trying to write a python web server using the socket library. I've been through several sources and can't figure out why the code I've written doesn't work. Others have run very similar code and claim it works. I'm new to python so I might be missing something simple.

The only way it will work now is I send the data variable back to the client. The browser prints the original GET request. When I try to send an HTTP response, the connection times out.

import socket

##Creates several variables, including the host name, the port to use
##the size of a transmission, and how many requests can be handled at once
host = ''
port = 8080
backlog = 5
size = 1024

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
    client, address = s.accept()
    data = client.recv(16)
    if data:
        client.send('HTTP/1.0 200 OK\r\n')
        client.send("Content-Type: text/html\r\n\r\n")
        client.send('<html><body><h1>Hello World</body></html>')

    client.close()
    s.close()
2
  • What exactly happens when you try to run it [BTW apart from doing this for learning sockets and/or HTTP, what you're doing is a BAD idea] Commented Apr 11, 2012 at 18:33
  • When I run this the shell pops up and waits until I type localhost:8080 into the browser. When I do, the shell closes. After a moment, the browser says the connection timed out. As I mentioned earlier, If I only send the client the data variable, the web browser will display the GET request. Commented Apr 11, 2012 at 18:43

1 Answer 1

2

You need to consume the input before responding, and you shouldn't close the socket in your while loop:

  1. Replace client.recv(16) with client.recv(size), to consume the request.

  2. Move your last line, s.close() back one indent, so that it is not in your while loop. At the moment you are closing the connection, then trying to accept from it again, so your server will crash after the first request.

Unless you are doing this as an exercise, you should extend SimpleHTTPServer instead of using sockets directly.

Also, adding this line after your create the socket (before bind) fixes any "Address already in use" errors you might be getting.

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

Good luck!

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your response, Graham. I've implemented the changes (I originally had client.recv(size) and changed it because I was troubleshooting). However, these two changes don't make a difference.
Oh. It works for me on Linux with Chrome browser. Try size = 4096 to be sure you're consuming everything. Look in Chrome or Firefox's network inspector to see if that gives any clues.
That's strange. I'm on Windows 7 with IE and FF. I tried increasing the size. The only thing I've noticed that is different is that the shell doesn't close now when I type localhost:8080 into the browser. Nothing shows up in Live HTTP Headers.
I uninstalled my current version (3.2.3) and installed 2.7 and it worked. Thanks for your help, Graham.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.