4

Python で POST リクエストを送受信する方法を理解するために使用している次の 2 つの Python スクリプトがあります。

クライアント:

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()

問題は、クライアントで conn.close() が呼び出されるまでサーバーが self.rfile.read() でハングすることですが、クライアントで conn.close() が呼び出された場合、クライアントはサーバーからの応答を受信できません。これにより、サーバーから応答を取得するか、POST データを読み取ることができますが、両方を行うことはできません。この問題を解決するために、ここに欠けているものがあると思います。

追加情報:

conn.getresponse() は、サーバーから応答を受信するまでクライアントをハングさせます。サーバー上の関数の実行が完了するまで、応答は受信されないようです。

4

2 に答える 2

5

元の例にはいくつかの問題があります。1 つ目は、メソッドを使用する場合、個別requestに呼び出すのではなく、その呼び出しに送信するメッセージ本文を含める必要があることです。ドキュメンテーション ノート send() は、次の代わりsend使用できます。request

上記の request() メソッドを使用する代わりに、以下の 4 つの関数を使用して、リクエストを段階的に送信することもできます。

あなたはただ欲しいconn.request("POST", "/testurl", "clientdata")

2 番目の問題は、サーバーに送信されたものを読み取ろうとする方法です。self.rfile.read()クライアントからの入力ストリーム全体を読み取ろうとします。つまり、ストリームが閉じられるまでブロックされます。接続が閉じられるまで、ストリームは閉じられません。あなたがしたいことは、クライアントから送信されたバイト数を正確に読み取ることです。それだけです。それが何バイトかどうやってわかりますか?もちろん、ヘッダーは次のとおりです。

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

非常に基本的なテスト以上のことを行う場合は、python-requests ライブラリを強くお勧めします。また、非常に基本的なテスト (フラスコ、ボトル、トルネードなど) 以外にも、BaseHTTPServer よりも優れた HTTP フレームワーク/サーバーを使用することをお勧めします。

于 2014-05-05T16:28:31.620 に答える