【问题标题】:Python Socket Getting Connection ResetPython套接字获取连接重置
【发布时间】:2010-03-09 18:00:16
【问题描述】:

我创建了一个线程套接字侦听器,它将新接受的连接存储在队列中。然后套接字线程从队列中读取并响应。出于某种原因,当使用 2 或更多并发使用 'ab' (apache benchmark) 进行基准测试时,我总是在它能够完成基准测试之前重置连接(这是在本地进行的,所以没有外部连接问题) .

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 基准测试,所以导致连接的积压堆积,此时连接开始被套接字丢弃。

【问题讨论】:

  • 如何发布回溯 - 首先它会准确说明连接检测到重置的位置。
  • 客户端发生错误(在 apache 基准测试中 - “apr_socket_connect(): Connection reset by peer (54)”),服务器继续正常运行。

标签: python sockets multithreading


【解决方案1】:

你不使用 Python 自带的 SocketServer 有什么原因吗?这样可以更好地处理这种情况。如果你正在寻找做 HTTP 的东西,BaseHTTPServer 也为此提供了一个框架。

【讨论】:

  • BaseHTTPServer 没有线程化,并且 SocketServer 没有让您选择执行线程池等操作。
  • 可以使用 SocketServer.ThreadingTcpServer 来编写一个多线程的 HTTP 服务器。示例见:stackoverflow.com/questions/2274320/…
猜你喜欢
  • 2014-08-25
  • 1970-01-01
  • 2018-11-12
  • 2020-12-09
  • 2016-08-19
  • 1970-01-01
  • 1970-01-01
  • 2021-03-11
  • 2016-01-27
相关资源
最近更新 更多