Python 3.x BaseHTTPServer 或 http.server

67 投票
4 回答
114755 浏览
提问于 2025-04-18 04:03

我正在尝试制作一个BaseHTTPServer程序。我更喜欢用Python 3.3或3.2来实现这个程序。我发现文档里关于要导入什么的部分很难理解,所以我尝试把导入的内容从:

from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer

改成:

from http.server import BaseHTTPRequestHandler,HTTPServer

这样导入就成功了,程序也启动了,并且在等待一个GET请求。但是,当请求到达时,就会出现一个异常:

File "C:\Python33\lib\socket.py", line 317, in write return self._sock.send(b)
TypeError: 'str' does not support the buffer interface

问题是:有没有一个可以直接在Python 3.x上使用的BaseHTTPServer或http.server版本,还是我做错了什么?

这是我在Python 3.3和3.2中尝试运行的“我的”程序:

#!/usr/bin/python
# from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
from http.server import BaseHTTPRequestHandler,HTTPServer

PORT_NUMBER = 8080

# This class will handle any incoming request from
# a browser 
class myHandler(BaseHTTPRequestHandler):

    # Handler for the GET requests
    def do_GET(self):
        print   ('Get request received')
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        # Send the html message
        self.wfile.write("Hello World !")
        return

try:
    # Create a web server and define the handler to manage the
    # incoming request
    server = HTTPServer(('', PORT_NUMBER), myHandler)
    print ('Started httpserver on port ' , PORT_NUMBER)

    # Wait forever for incoming http requests
    server.serve_forever()

except KeyboardInterrupt:
    print ('^C received, shutting down the web server')
    server.socket.close()

这个程序在Python 2.7中部分可以运行,但在2到8个请求后就会出现这个异常:

error: [Errno 10054] An existing connection was forcibly closed by the remote host

4 个回答

4

你需要修改一下wfile这个参数,因为在Python 3中,它接受的是类似字节的对象。所以你需要把你的字符串转换成字节,方法是:

self.wfile.write(b"<h1> Hello </h1>")

或者

self.wfile.write( bytes("<h1> Hello </h1>") )

4

负责编写 Python 3 的 http.server 文档的人没有提到这个变化。Python 2.7 的文档一开始就说明了:“注意,BaseHTTPServer 模块已经合并到 Python 3 的 http.server 中。2to3 工具在将你的代码转换为 Python 3 时会自动调整导入的内容。”

8

你可以这样做:

self.send_header('Content-type','text/html'.encode())
self.end_headers()
# Send the html message
self.wfile.write("Hello World !".encode())
83

你的程序在python 3.xx中几乎可以直接运行,但有一个小问题。这个问题不是出在你的代码上,而是出在你写这些代码的地方:

self.wfile.write("Hello World !")

你试图在这里写“字符串”,但实际上应该写的是字节。所以你需要把你的字符串转换成字节。

看看我的代码,它和你的几乎一样,而且运行得很好。我的代码是用python 3.4写的:

from http.server import BaseHTTPRequestHandler, HTTPServer
import time

hostName = "localhost"
hostPort = 9000

class MyServer(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(bytes("<html><head><title>Title goes here.</title></head>", "utf-8"))
        self.wfile.write(bytes("<body><p>This is a test.</p>", "utf-8"))
        self.wfile.write(bytes("<p>You accessed path: %s</p>" % self.path, "utf-8"))
        self.wfile.write(bytes("</body></html>", "utf-8"))

myServer = HTTPServer((hostName, hostPort), MyServer)
print(time.asctime(), "Server Starts - %s:%s" % (hostName, hostPort))

try:
    myServer.serve_forever()
except KeyboardInterrupt:
    pass

myServer.server_close()
print(time.asctime(), "Server Stops - %s:%s" % (hostName, hostPort))

请注意我如何使用“UTF-8”编码把字符串转换成字节。一旦你在程序中做了这个修改,你的程序就应该能正常工作了。

撰写回答