TCP 服务器与 HTTP 服务器

mac*_*azo 5 python httpserver tcpserver

我正在编写一个简单的 python3 网络服务器。我尝试过各种教程,并且效果都很好。尽管如此,还是有一个我不明白的区别。

在一篇教程中,他们使用 HTTPServer,如下所示:

server = HTTPServer(('', PORT_NUMBER), myHandler) 
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)

在另一个教程中,他们使用 socketserver.TCPServer ,如下所示:

with socketserver.TCPServer(('', PORT_NUMBER), myHandler) as httpd:
    httpd.serve_forever()
Run Code Online (Sandbox Code Playgroud)

两种方法有什么区别?我所需要的只是一个简单的网络服务器,它能够通过 POST 接收 JSON 文件并使用另一个 JSON 进行询问。在这两种情况下,我都会使用相同的处理程序:

class myHandler(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()

    def do_GET(self):
        self._set_headers()
        self.wfile.write("{dummy:'dummy'}")

    def do_POST(self):
        # Doesn't do anything with posted data for this example
        self._set_headers()
        self.wfile.write("{dummy:'dummy'}")
Run Code Online (Sandbox Code Playgroud)

其中一种方法更适合我的需求吗?有没有更好的方法来编写这个服务器来满足我的需要?

感谢您的帮助和时间!

Yu *_*hen 5

TCP 是OSI 第 4 层传输协议,而 HTTP 是建立在 TCP 之上的更高层 7 应用协议。

事实上,根据文档HTTPServer,它看起来像是直接继承自:socketserver.TCPServer

其中一个类 HTTPServer 是 socketserver.TCPServer 的子类。它创建并侦听 HTTP 套接字,将请求分派给处理程序。

例如,TCP 将负责建立连接(使用 、SYN和SYN-ACK进行三向握手ACK),但它在数据交互的结构(请求/响应)方面并没有真正规定太多。如果您使用 TCP 协议,您通常需要编写自己的所有数据处理代码。

我所需要的只是一个简单的网络服务器,它能够通过 POST 接收 JSON 文件并使用另一个 JSON 进行询问

这表明 HTTP 服务器更适合您的需求,因为 a 的概念POST,并且您对 an 的描述answer with another JSON可能会包含响应(带有响应正文、响应标头和响应状态)。所有这些都将是HTTP概念。作为状态的文档http.server. BaseHTTPRequestHandler,它将包含一个名为的实例变量,command该变量是您的请求方法(GET例如)。

我无法确切说明myhandler示例代码中是如何分配的,但查看其他一些文档示例,它看起来像http.server.SimpleHTTPRequestHandler:

import http.server
import socketserver

PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print("serving at port", PORT)
    httpd.serve_forever()
Run Code Online (Sandbox Code Playgroud)

服务器实例化工作的常见模式似乎是

  1. 要实例化较低级别的协议服务器(即 TCP)并传入较高级别的处理程序(如http.server.SimpleHTTPRequestHandler),因此socketserver.TCPServer(("", PORT), myhandler).
  2. 要在上下文管理器(with关键字)中使用它,很可能是因为您需要在服务器完成执行后拆除/释放资源。