2009-05-25 10 views
6

Ich schreibe einen kleinen Comet-Server in C#, und um es zu testen, habe ich ein kleines Programm geschrieben, das eine Reihe von Verbindungen öffnet, schreibt einen kleinen Text zu jedem von ihnen und schließt dann jeden das nahm mich unter 4000Erstellen von 100.000 TCP-Verbindungen mit .NET

int basePort = 30000; 
IPAddress localAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }); 
List<Socket> sockets = new List<Socket>(); 

for(int i = 0; i < 20000; i++) { 
    Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    s.Bind(new IPEndPoint(localAddress, basePort + i)); 
    s.Connect("localhost", 1999); 
    sockets.Add(s); 
} 

string message = "hello"; 
byte[] messageData = Encoding.ASCII.GetBytes(message); 
foreach(Socket s in sockets) { 
    s.Send(messageData); 
} 

foreach(Socket s in sockets) { 
    s.Disconnect(false); 
} 

ich verwende Windows XP zur Zeit, welche Ports dynamische Client aus dem 1025-5000 Bereich zuordnet nur, so habe ich beginnen explizite Bindung an Ports an 30000. hinzugefügt: von ihnen Verbindungen zu etwas mehr als 16000, aber jetzt bekomme ich die folgende Ausnahme auf Socket.Connect:

"Eine Operation auf einem Socket konnte nicht sein durchgeführt, weil das System nicht genügend Pufferkapazität hatte oder weil eine Warteschlange voll war 127.0.0.1:1999 "

Irgendwelche Gedanken? Das Ändern der Sende- und Empfangspuffergröße scheint keinen Unterschied zu machen, und es scheint immer, dass meine Client-Anwendung bricht, niemals mein Server. Mir ist klar, dass mir die Client-Ports ausgehen werden, bevor ich 100.000 Verbindungen bekomme, aber ich würde trotzdem gerne verstehen, was hier besser läuft.

Antwort

1

Windows XP (und vermutlich auch andere Versionen) haben Beschränkungen für die Anzahl offener Ports, die gleichzeitig zulässig sind. Diese MSDN articl e kann hilfreich bei der Modifizierung der TcpIp-Parameter sein, um die Anzahl der verfügbaren Ports zu erhöhen und die Zeit zu verkürzen, die Windows den Port geöffnet hält, bevor er wieder verwendet werden kann.

+0

Ich denke, ich habe die Port Erschöpfung Sachen bereits behandelt. Die explizite Bindung ist da, um mit der begrenzten Anzahl von dynamisch zugewiesenen Ports fertig zu werden, und die Socket.Disconnect gibt den Socket etwas schneller frei als ein Socket.Close, sodass ich meinen Test erneut ausführen kann, ohne auf das TIME_WAIT-Intervall zu warten. – Daryl

+0

Ich denke, dass es auch einen Rate-Limit-Parameter gibt, aber ich habe keine MSDN-Referenz dafür gefunden. Der andere Verdacht, den ich habe, ist die Anzahl der verfügbaren Netzwerkpuffer. – tvanfosson

+0

Sie brauchen keine explizite Bindung, um mit dem dynamischen Limit umzugehen, Sie müssen nur das Limit anpassen, wie tvanfosson vorgeschlagen hat. –

3

Möglicherweise haben Sie keinen nicht ausgelagerten Speicher mehr. Es gibt Grenzen pro Maschine und pro Prozess, die auf der Menge installierter RAM-, OS-/3GB-Schaltereinstellungen usw. basieren. 32-Bit-OS-Skus haben eine viel niedrigere Grenze für nicht ausgelagerten Speicher als 64-Bit-OS-Skus.

+0

Das sah vielversprechend aus, aber wenn mein Testclient stirbt, verwende ich weniger als 28 MB nicht ausgelagerten Kernelspeicher. Nach dem, was ich gelesen habe, sollte das systemweite Limit mindestens 100 MB betragen. Es sieht so aus, als würde ich auch nicht die pro-Prozess-Grenze erreichen, denn wenn der Client stirbt, verbraucht er weniger als 8 MB, während der Server bei über 10 MB in Ordnung zu sein scheint. – Daryl

3

Ich denke 100.000 Verbindungen ist kein realisierbares Ziel.

TCP/IP-Ports sind 16-Bit-Nummern. Alles über 65535 ist also ein Nein.

+0

Ja, in der Beschreibung erwähne ich, dass mir die Client-Ports ausgehen werden, bevor ich 100.000 erreiche, aber ich würde gerne versuchen, ein solches Limit zu erreichen, bevor ich aufhöre. – Daryl

+0

Ich habe darüber ein bisschen mehr nachgedacht. TCP/IP-Ports werden tatsächlich über IP und Port adressiert, sodass ich jeden Port für jede IP-Adresse einmal verwenden kann. Verbindung zu einem lokalen Dienst Ich kann die lokale Adresse (127.0.0.1) und die externe Standardadresse verwenden, was mir weit über 100.000 verschiedene Client-Endpunkte gibt. Ich habe das getestet und es funktioniert gut auf meiner Windows XP-Box. – Daryl

+1

immer noch, wenn Sie eine Verbindung zu einem externen oder internen IP/Port herstellen, benötigt es immer noch eine lokale IP/Port-Kombination. z.B. Sagen wir, dass ich mich mit google.com:80 verbinde, dann wird auch ein lokaler Port zugewiesen. Es ist die Localport Combos, wo Sie ausgehen. Also ich verstehe nicht, wie Sie über das 65536 Limit gehen können. – Toad

Verwandte Themen