我实现了一个简单的 HTTP server和一个客户。后者使用 requests library 发出 PUT 请求, 发送一些任意的 JSON 然后退出。
当我启动服务器,然后运行客户端时,服务器和客户端都会阻塞。然而,服务器似乎还没有完成整个处理函数。
这是我在服务器端得到的:
$ python3 server.py
PUT / HTTP/1.1
即打印请求行后,不打印内容JSON字符串。此时由于某种原因客户端和服务器都阻塞了。
有趣的是,当我向客户端触发 KeyboardInterrupt
时,服务器会继续:
$ python3 server.py
PUT / HTTP/1.1
b'{"content": "Hello World"}'
127.0.0.1 - - [25/Feb/2016 11:52:54] "PUT / HTTP/1.1" 200 -
我的问题:
- 为什么必须杀死客户端才能让服务器继续运行?
- 我是否以错误的方式使用了这些组件?
- 如何让客户端和服务器(几乎)即时运行?
这是 HTTP 服务器的代码。它只处理 PUT 请求。它打印请求行和内容数据并使用成功代码响应客户端:
import http.server
class PrintPUTRequestHandler(http.server.BaseHTTPRequestHandler):
def do_PUT(self):
print(self.requestline)
print(self.rfile.read())
self.send_response(200)
self.end_headers()
server_address = ('', 8000)
httpd = http.server.HTTPServer(server_address, PrintHTTPRequestHandler)
httpd.serve_forever()
这是 HTTP 客户端。本意是尽快连接到服务器,写入请求并返回(但并没有):
import requests
server_address = "http://127.1:8000"
data = '{"content": "Hello World"}'
requests.put(server_address, data, headers={"Content-type": "application/json"})
这是我在服务器启动后运行它的方式(没有可观察到的输出):
python client.py
最佳答案
服务器在这条线上阻塞了它自己和客户端:
print(self.rfile.read())
发生这种情况是因为您没有指定要读取的数据量,因此服务器会读取输入流直到它关闭。在您的情况下,一旦您杀死客户端,输入流就会关闭。
请记住,服务器并不知道数据流何时结束,因为您可能希望逐 block 发送数据(例如,当您发送大文件时)。
请求的大小应该在 Content-Length
header 中传递,所以这是你应该做的:
length = int(self.headers['Content-Length'])
print(self.rfile.read(length))
这是假设长度足够小以适合您的内存(在您的情况下是这样)。
关于python - 使用简单的自定义 HTTP 客户端和服务器 PUT 请求阻塞时间过长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35625314/