ある種のHTTPサーバーを使用して単純なPythonスクリプトを作成しました。
import SocketServer
response = b'HTTP/1.0 200 OK\r\nDate: Mon, 1 Jan 1996 01:01:01 GMT\r\n'
response += b'Content-Type: text/plain\r\nContent-Length: 14\r\n\r\n'
response += b'Hello, world!\n'
class MyTCPHandler(SocketServer.StreamRequestHandler):
def handle(self):
while True:
line = self.rfile.readline().strip()
print "{} {}:{} wrote: {}".format(self.connection, self.client_address[0], self.client_address[1], line)
if not line:
self.wfile.write(response)
print 'Sent hello world'
#break
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
ここで、abを起動して1つの接続を介して1つのリクエストを実行します:ab -n1 -c1 http://127.0.0.1:9999/
応答後に接続を閉じない場合、クライアントが応答を受信したらその側でソケットを閉じることを期待して、何か奇妙なことが起こります。
Abは、同じ接続を介して同じリクエストを送信することを常に繰り返します。
~$ python2.7 ./socket_server.py
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: GET / HTTP/1.0
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: Host: 127.0.0.1:9999
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: User-Agent: ApacheBench/2.3
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: Accept: */*
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote:
Sent hello world
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: GET / HTTP/1.0
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: Host: 127.0.0.1:9999
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: User-Agent: ApacheBench/2.3
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: Accept: */*
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote:
Sent hello world
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: GET / HTTP/1.0
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: Host: 127.0.0.1:9999
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: User-Agent: ApacheBench/2.3
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote: Accept: */*
<socket._socketobject object at 0x1068ca600> 127.0.0.1:64626 wrote:
Sent hello world
...そしてそれは同じソケットを通して細かく繰り返されます。
ソケットから生データを読み取ろうとしました:
import SocketServer
class MyTCPHandler2(SocketServer.BaseRequestHandler):
def handle(self):
while True:
self.data = self.request.recv(1024).strip()
print "{} wrote:".format(self.client_address[0])
print self.data
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler2)
server.serve_forever()
Abはまだ応答を待とうとはせず、同じ接続で大量の要求を急いでいます。
なんで?私が見逃しているHTTP1.0での何らかの接続の再利用ですか?最初の\r\ n \ r \ nペアの後に来るデータに関係なく、常に接続を閉じる必要がありますか?
同じ動作を再現しようとするための適切なhttperfパラメータは何でしょうか?