python 为什么我会看到“对等方重置连接”错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/441374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why am I seeing 'connection reset by peer' error?
提问by z8000
I am testing cogenon a Mac OS X 10.5 box using python 2.6.1. I have a simple echo server and client-pumper that creates 10,000 client connections as a test. 1000, 5000, etc. all work splendidly. However at around 10,000 connections, the server starts dropping random clients - the clients see 'connection reset by peer'.
我正在使用 python 2.6.1 在 Mac OS X 10.5 机器上测试cogen。我有一个简单的回显服务器和客户端泵,可以创建 10,000 个客户端连接作为测试。1000、5000 等等,都表现出色。然而,在大约 10,000 个连接时,服务器开始丢弃随机客户端 - 客户端看到“对等方重置连接”。
Is there some basic-networking background knowledge I'm missing here?
我在这里缺少一些基本的网络背景知识吗?
Note that my system is configured to handle open files (launchctl limit, sysctl (maxfiles, etc.), and ulimit -n are all valid; been there, done that). Also, I've verified that cogen is picking to use kqueue under the covers.
请注意,我的系统配置为处理打开的文件(launchctl limit、sysctl(maxfiles 等)和 ulimit -n 都是有效的;去过那里,做到了)。此外,我已经证实,cogen 正在选择在幕后使用 kqueue。
If I add a slight delay to the client-connect() calls everything works great. Thus, my question is, why would a server under stress drop other clients when there's a high frequency of connections in a short period of time? Anyone else ever run into this?
如果我对 client-connect() 调用添加一点延迟,则一切正常。因此,我的问题是,为什么在短时间内连接频率很高的情况下,处于压力下的服务器会断开其他客户端?还有其他人遇到过这种情况吗?
For completeness' sake, here's my code.
为了完整起见,这是我的代码。
Here is the server:
这是服务器:
# 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()
And here is the client:
这是客户端:
# 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()
Thanks for any information!
感谢您提供任何信息!
回答by S.Lott
Python's socket I/O sometimes suffers from connection reset by peer. It has to do with the Global Interpreter Lock and how threads are scheduled. I bloggedsome references on the subject.
Python 的套接字 I/O 有时会受到对等连接重置的影响。它与全局解释器锁以及线程的调度方式有关。我在博客上写了一些关于这个主题的参考资料。
The time.sleep(0.0001)
appears to be the recommended solution because it adjusts thread scheduling and allows the socket I/O to finish.
这time.sleep(0.0001)
似乎是推荐的解决方案,因为它调整线程调度并允许套接字 I/O 完成。