1


0

Pythonソケットの接続リセットの取得

新しく受け入れられた接続をキューに格納するスレッドソケットリスナーを作成しました。 次に、ソケットスレッドはキューから読み取り、応答します。 何らかの理由で、2以上の同時実行を使用して 'ab'(apacheベンチマーク)でベンチマークを実行すると、ベンチマークを完了する前に常に接続がリセットされます(これはローカルで行われるため、外部接続の問題はありません) 。

class server:
_ip = ''
_port = 8888

def __init__(self, ip=None, port=None):
    if ip is not None:
        self._ip    = ip
    if port is not None:
        self._port  = port
    self.server_listener(self._ip, self._port)

def now(self):
    return time.ctime(time.time())

def http_responder(self, conn, addr):
    httpobj = http_builder()
    httpobj.header('HTTP/1.1 200 OK')
    httpobj.header('Content-Type: text/html; charset=UTF-8')
    httpobj.header('Connection: close')
    httpobj.body("Everything looks good")
    data = httpobj.generate()

    sent = conn.sendall(data)


def http_thread(self, id):
    self.log("THREAD %d: Starting Up..." % id)

    while True:
        conn, addr = self.q.get()
        ip, port = addr
        self.log("THREAD %d: responding to request: %s:%s - %s" % (id, ip, port, self.now()))
        self.http_responder(conn, addr)
        self.q.task_done()
        conn.close()

def server_listener(self, host, port):
    self.q = Queue.Queue(0)

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind( (host, port) )
    sock.listen(5)


    for i in xrange(4): #thread count
        thread.start_new(self.http_thread, (i+1, ))

    while True:
        self.q.put(sock.accept())

    sock.close()

server('', 9999)

ベンチマークを実行すると、エラーが発生する前に、通常は4〜500の、完全にランダムな数の適切なリクエストが取得されます。

編集:それを理解するのにしばらく時間がかかりましたが、問題は `sock.listen(5)`にありました。 並行性が高い(5以上)apacheベンチマークを使用していたため、接続のバックログが蓄積され、その時点で接続がソケットによってドロップされ始めました。

1 Answer


0


Pythonに付属のSocketServerを使用しない理由はありますか? これは、状況をより良く処理します。 HTTPのことをしようとしているなら、BaseHTTPServerはこのためのフレームワークも提供します。