如何在不使用任何库的情况下使用Python实现简单的Web服务器?

时间:2012-04-10 15:05:21

标签: python http sockets webserver websocket

我需要在Python中实现一个非常简单的类似Web服务器的应用程序,该应用程序将执行基本的HTTP请求和响应,并在网页上显示非常基本的输出。我并不太关心用Python编写它,但我不知道从哪里开始?如何设置?一个文件?多个文件?我想我不知道如何处理这是一个“服务器”的事实 - 所以我不熟悉如何处理HTTP请求/套接字/处理请求等等。任何建议?资源?

4 个答案:

答案 0 :(得分:10)

您应该查看SimpleHttpServer(py3:http.server)模块。

根据您要执行的操作,您可以使用它,也可以查看模块的来源(py2py3)以获取相关提示。

如果您希望获得更多低级别,SimpleHttpServer会扩展BaseHttpServersource)以使其正常工作。

如果您想让更多更低级别,请查看SocketServer(来源:py2py3)。

人们经常会像python -m SimpleHttpServer(或python3 -m http.server)一样运行python,如果他们只是想共享一个目录:它是一个功能齐全且简单的服务器。

答案 1 :(得分:4)

您可以使用socket programming来实现此目的。以下代码段创建了一个tcp套接字,并在端口9000上侦听http请求:

from socket import *

def createServer():
    serversocket = socket(AF_INET, SOCK_STREAM)
    serversocket.bind(('localhost',9000))
    serversocket.listen(5)
    while(1):
        (clientsocket, address) = serversocket.accept()
        clientsocket.send("HTTP/1.1 200 OK\n"
         +"Content-Type: text/html\n"
         +"\n" # Important!
         +"<html><body>Hello World</body></html>\n")
        clientsocket.shutdown(SHUT_WR)
        clientsocket.close()

    serversocket.close()

createServer()

启动服务器$ python server.py。 在Web浏览器中打开http://localhost:9000/(充当客户端)。然后在浏览器窗口中,您可以看到文本“Hello World”(http响应)。

编辑** 之前的代码仅在chrome上进行了测试,正如您所建议的其他浏览器一样,代码被修改为:

  1. 要使响应类似于http,您可以使用http版本1.1,状态代码200 OK和内容类型text / html发送普通标题。
  2. 提交响应后,客户端套接字需要关闭,因为它是TCP套接字。
  3. 要正确关闭客户端套接字,需要调用shutdown()
  4. {{1}}

    然后代码在chrome,firefox(socket.shutdown vs socket.close)和终端中的简单curl(curl http://localhost:9000/)上进行了测试。

答案 2 :(得分:0)

我决定在Python 3中进行这项工作,并使其可以供Chrome浏览器用作我正在开发的在线课程的示例。当然,Python 3在正确的位置需要encode()decode()。 Chrome-确实希望在获取数据之前发送其 GET 请求。我还添加了一些错误检查,以便在中止服务器或服务器崩溃时清理其套接字:

def createServer():
    serversocket = socket(AF_INET, SOCK_STREAM)
    try :
        serversocket.bind(('localhost',9000))
        serversocket.listen(5)
        while(1):
            (clientsocket, address) = serversocket.accept()

            rd = clientsocket.recv(5000).decode()
            pieces = rd.split("\n")
            if ( len(pieces) > 0 ) : print(pieces[0])

            data = "HTTP/1.1 200 OK\r\n"
            data += "Content-Type: text/html; charset=utf-8\r\n"
            data += "\r\n"
            data += "<html><body>Hello World</body></html>\r\n\r\n"
            clientsocket.sendall(data.encode())
            clientsocket.shutdown(SHUT_WR)

    except KeyboardInterrupt :
        print("\nShutting down...\n");
    except Exception as exc :
        print("Error:\n");
        print(exc)

    serversocket.close()

print('Access http://localhost:9000')
createServer()

服务器还会打印出传入的HTTP请求。当然,无论浏览器发出什么请求,该代码都只会发送text / html-即使浏览器正在请求该图标:

$ python3 server.py
Access http://localhost:9000
GET / HTTP/1.1
GET /favicon.ico HTTP/1.1
^C
Shutting down...

但这是一个很好的示例,主要显示了为什么要使用Flask或DJango之类的框架而不是编写自己的框架。感谢您的初始代码。

答案 3 :(得分:-1)

上面有一个非常简单的解决方案,但是上面的解决方案不起作用。此解决方案在chrome上经过测试,可以正常工作。这是python 3,尽管它可能在python 2上可用,因为我从未测试过。

from socket import *

def createServer():
    serversocket = socket(AF_INET, SOCK_STREAM)
    serversocket.bind(('localhost',9000))
    serversocket.listen(5)
    while(1):
        (clientsocket, address) = serversocket.accept()
        clientsocket.send(bytes("HTTP/1.1 200 OK\n"
         +"Content-Type: text/html\n"
         +"\n" # Important!
         +"<html><body>Hello World</body></html>\n",'utf-8'))
        clientsocket.shutdown(SHUT_WR)
        clientsocket.close()

    serversocket.close()

createServer()

相对于已接受的答案有所改进,但我将其发布,以便将来的用户可以轻松使用。