我正在使用python 2.6.1在Mac OS X 10.5盒子上测试cogen.我有一个简单的echo服务器和客户端泵,可以创建10,000个客户端连接作为测试.1000,5000等都工作得很好.但是,在大约10,000个连接处,服务器开始丢弃随机客户端 - 客户端看到"通过对等方重置连接".
我在这里缺少一些基本的网络背景知识吗?
请注意,我的系统配置为处理打开的文件(launchctl limit,sysctl(maxfiles等),ulimit -n都是有效的;在那里,完成了).此外,我已经证实cogen正在选择使用kqueue.
如果我给client-connect()调用添加一点延迟,一切都很好.因此,我的问题是,当短时间内连接频率很高时,为什么服务器会在压力下降其他客户端?有没有人遇到过这个?
为了完整起见,这是我的代码.
这是服务器:
# echoserver.py from cogen.core import sockets, schedulers, proactors from cogen.core.coroutines import coroutine import sys, socket port = 1200 @coroutine def server(): srv = sockets.Socket() srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) addr = ('0.0.0.0', port) srv.bind(addr) srv.listen(64) print "Listening on", addr while 1: conn, addr = yield srv.accept() m.add(handler, args=(conn, addr)) client_count = 0 @coroutine def handler(sock, addr): global client_count client_count += 1 print "SERVER: [connect] clients=%d" % client_count fh = sock.makefile() yield fh.write("WELCOME TO (modified) ECHO SERVER !\r\n") yield fh.flush() try: while 1: line = yield fh.readline(1024) #print `line` if line.strip() == 'exit': yield fh.write("GOOD BYE") yield fh.close() raise sockets.ConnectionClosed('goodbye') yield fh.write(line) yield fh.flush() except sockets.ConnectionClosed: pass fh.close() sock.close() client_count -= 1 print "SERVER: [disconnect] clients=%d" % client_count m = schedulers.Scheduler() m.add(server) m.run()
这是客户:
# echoc.py import sys, os, traceback, socket, time from cogen.common import * from cogen.core import sockets port, conn_count = 1200, 10000 clients = 0 @coroutine def client(num): sock = sockets.Socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) reader = None try: try: # remove this sleep and we start to see # 'connection reset by peer' errors time.sleep(0.001) yield sock.connect(("127.0.0.1", port)) except Exception: print 'Error in client # ', num traceback.print_exc() return global clients clients += 1 print "CLIENT #=%d [connect] clients=%d" % (num,clients) reader = sock.makefile('r') while 1: line = yield reader.readline(1024) except sockets.ConnectionClosed: pass except: print "CLIENT #=%d got some other error" % num finally: if reader: reader.close() sock.close() clients -= 1 print "CLIENT #=%d [disconnect] clients=%d" % (num,clients) m = Scheduler() for i in range(0, conn_count): m.add(client, args=(i,)) m.run()
感谢您的任何信息!
Python的套接字I/O有时会受到peer的连接重置的影响.它与Global Interpreter Lock以及如何安排线程有关.我在博客上写了一些关于这个主题的参考
在time.sleep(0.0001)
似乎是推荐的解决方案,因为它调整线程调度,并允许套接字I/O完成.