Pourquoi suis-je de voir "connection reset by peer' erreur?

Je suis en train de tester cogen sur un Mac OS X 10.5 boîte à l'aide de python 2.6.1. J'ai un simple écho du serveur et du client-pumper qui crée de 10 000 connexions client comme un test. 1000, 5000, etc. tous les travaux magnifiquement. Cependant, à près de 10 000 connexions, le serveur commence à chuter aléatoire clients - les clients voir "connection reset by peer'.

Est-il une base de réseaux de connaissances qui me manque ici?

Remarque que mon système est configuré pour traiter les fichiers ouverts (launchctl limite, sysctl (maxfiles, etc.), et ulimit-n sont tous en cours de validité; été là, fait cela). Aussi, j'ai vérifié que la cogénération est la cueillette à l'utilisation kqueue sous les couvertures.

Si j'ajoute un léger retard pour le client-connect() appelle tout fonctionne très bien. Donc, ma question est, pourquoi un serveur sous le stress de la baisse d'autres clients quand il y a une haute fréquence de connexions dans un court laps de temps? Quiconque jamais couru dans cette?

À des fins d'exhaustivité, voici mon code.

Voici le serveur:

# 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()

Et ici, c'est le 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()

Merci pour toute information!

côté serveur, srv.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) me 16K connexions client..., il m'est apparu qu'en ce moment je suis à court de ports éphémères: > net.inet.ip.portrange.hifirst: 49152 > net.inet.ip.portrange.hilast: 65535
Je suppose alors, tout va bien, vraiment. Je suis preneuse si quelqu'un peut m'expliquer pourquoi pas à l'aide de TCP_NODELAY causes connexions être abandonné.
Re: les ports éphémères... j'ai été en mesure d'apporter une deuxième adresse IP manuellement et de lier les sockets client à chaque port dans [1024,65535] sur chaque IP. J'ai été en mesure de se connecter sur 80K clients à partir de la même machine exécutant le serveur. Whee!

OriginalL'auteur z8000 | 2009-01-13