4

我有这两个 Python 脚本,用于尝试解决如何在 Python 中发送和接收 POST 请求:

客户端:

import httplib

conn = httplib.HTTPConnection("localhost:8000")
conn.request("POST", "/testurl")
conn.send("clientdata")
response = conn.getresponse()
conn.close()

print(response.read())

服务器:

from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer

ADDR = "localhost"
PORT = 8000

class RequestHandler(BaseHTTPRequestHandler):        
    def do_POST(self):
        print(self.path)
        print(self.rfile.read())
        self.send_response(200, "OK")
        self.end_headers()
        self.wfile.write("serverdata")

httpd = HTTPServer((ADDR, PORT), RequestHandler)
httpd.serve_forever()

问题是服务器在 self.rfile.read() 上挂起,直到在客户端上调用 conn.close() 但如果在客户端上调用 conn.close() ,则客户端无法接收来自服务器的响应。这会产生一种情况,即可以从服务器获得响应或读取 POST 数据,但不能同时读取两者。我认为这里缺少一些可以解决此问题的东西。

附加信息:

conn.getresponse() 导致客户端挂起,直到收到来自服务器的响应。在服务器上的函数完成执行之前,似乎没有收到响应。

4

2 回答 2

5

您的原始示例存在几个问题。第一个是如果您使用该request方法,您应该在该调用中包含您要发送的消息正文,而不是send单独调用。文档说明 send() 可以用作以下内容的替代方法request

作为使用上述 request() 方法的替代方法,您还可以使用以下四个函数逐步发送请求。

你只是想要conn.request("POST", "/testurl", "clientdata")

第二个问题是您尝试读取发送到服务器的内容的方式。self.rfile.read()尝试读取来自客户端的整个输入流,这意味着它将阻塞直到流关闭。在关闭连接之前不会关闭流。您要做的是准确读取从客户端发送了多少字节,仅此而已。你怎么知道那是多少字节?标题,当然:

length = int(self.headers['Content-length'])
print(self.rfile.read(length))

如果您要做的不仅仅是非常基本的测试,我强烈推荐使用 python-requests 库。我还建议使用比 BaseHTTPServer 更好的 HTTP 框架/服务器来进行非常基本的测试(烧瓶、瓶子、龙卷风等)。

于 2014-05-05T16:28:31.620 回答
1

很长时间回答但在搜索过程中出现,所以我带来了另一个答案。为了防止服务器保持流打开(导致永远不会发送响应),您应该使用self.rfile.read1()而不是self.rfile.read()

于 2021-06-22T09:33:49.550 回答