use*_*459 50 python webserver multithreading http
我正在尝试在python中创建多线程Web服务器,但它一次只响应一个请求,我无法弄清楚原因.你能帮我吗?
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from SocketServer import ThreadingMixIn
from  BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
from time import sleep
class ThreadingServer(ThreadingMixIn, HTTPServer):
    pass
class RequestHandler(SimpleHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/plain')
        sleep(5)
        response = 'Slept for 5 seconds..'
        self.send_header('Content-length', len(response))
        self.end_headers()
        self.wfile.write(response)
ThreadingServer(('', 8000), RequestHandler).serve_forever()
roo*_*oot 74
检查这个职位由道格·赫尔曼的博客.
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
import threading
class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        message =  threading.currentThread().getName()
        self.wfile.write(message)
        self.wfile.write('\n')
        return
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""
if __name__ == '__main__':
    server = ThreadedHTTPServer(('localhost', 8080), Handler)
    print 'Starting server, use <Ctrl-C> to stop'
    server.serve_forever()
小智 11
我开发了一个名为ComplexHTTPServer的PIP实用程序,它是SimpleHTTPServer的多线程版本.
要安装它,您需要做的就是:
pip install ComplexHTTPServer
使用它很简单:
python -m ComplexHTTPServer [PORT]
(默认情况下,端口为8000.)
令人惊讶的是,这些打破流媒体的解决方案获得了多少票。如果以后可能需要流式传输,那么ThreadingMixIngunicorn 就不好用了,因为它们只是收集响应并将其作为一个单元写在最后(如果您的流是无限的,实际上什么都不做)。
您BaseHTTPServer与线程结合的基本方法很好。但是默认BaseHTTPServer设置会在每个监听器上重新绑定一个新的套接字,如果所有监听器都在同一个端口上,这在 Linux 中将不起作用。在serve_forever()通话前更改这些设置。(就像你必须设置self.daemon = True在线程以阻止 ctrl-C 被禁用一样。)
以下示例在同一端口上启动 100 个处理程序线程,每个处理程序通过BaseHTTPServer.
import time, threading, socket, SocketServer, BaseHTTPServer
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path != '/':
            self.send_error(404, "Object not found")
            return
        self.send_response(200)
        self.send_header('Content-type', 'text/html; charset=utf-8')
        self.end_headers()
        # serve up an infinite stream
        i = 0
        while True:
            self.wfile.write("%i " % i)
            time.sleep(0.1)
            i += 1
# Create ONE socket.
addr = ('', 8000)
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen(5)
# Launch 100 listener threads.
class Thread(threading.Thread):
    def __init__(self, i):
        threading.Thread.__init__(self)
        self.i = i
        self.daemon = True
        self.start()
    def run(self):
        httpd = BaseHTTPServer.HTTPServer(addr, Handler, False)
        # Prevent the HTTP server from re-binding every handler.
        # /sf/ask/3234747071/
        httpd.socket = sock
        httpd.server_bind = self.server_close = lambda self: None
        httpd.serve_forever()
[Thread(i) for i in range(100)]
time.sleep(9e9)
在python3中,您可以使用以下代码(https或http):
from http.server import HTTPServer, BaseHTTPRequestHandler
from socketserver import ThreadingMixIn
import threading
USE_HTTPS = True
class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'Hello world\t' + threading.currentThread().getName().encode() + b'\t' + str(threading.active_count()).encode() + b'\n')
class ThreadingSimpleServer(ThreadingMixIn, HTTPServer):
    pass
def run():
    server = ThreadingSimpleServer(('0.0.0.0', 4444), Handler)
    if USE_HTTPS:
        import ssl
        server.socket = ssl.wrap_socket(server.socket, keyfile='./key.pem', certfile='./cert.pem', server_side=True)
    server.serve_forever()
if __name__ == '__main__':
    run()
您将发现此代码将创建一个新线程来处理每个请求。
以下命令生成自签名证书:
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
如果您使用的是Flask,则此博客很棒。