Escribo un pequeño servidor Comet en C#, y para probarlo he escrito un pequeño programa que abre un grupo de conexiones, escribe un pequeño texto para cada una de ellas, y luego cierra cada una de ellos:Creando conexiones de 100,000 tcp usando .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);
}
estoy utilizando Windows XP en este momento, que sólo se asigna puertos de cliente dinámicas de la gama de 1025 a 5000, por lo que he añadido explícita unión a los puertos a partir de 30000. Esto me tomó de debajo de 4000 conexiones a un poco más de 16000, pero ahora obtengo la siguiente excepción en Socket.Connect:
"No se pudo realizar una operación en un socket se realizó porque el sistema carecía de espacio suficiente en el búfer o porque una cola estaba llena 127.0.0.1:1999 "
¿Alguna idea? Cambiar el tamaño del búfer de envío y recepción no parece hacer ninguna diferencia, y siempre parece ser la aplicación de mi cliente la que se rompe, nunca mi servidor. Me doy cuenta de que me voy a quedar sin puertos cliente antes de llegar a las 100.000 conexiones, pero aún me gustaría entender qué está pasando un poco mejor.
Creo que ya tengo solucionado el problema del agotamiento del puerto. El enlace explícito está ahí para tratar con la cantidad limitada de puertos asignados dinámicamente, y Socket.Disconnect libera el socket un poco más rápido que un Socket.Close, por lo que puedo volver a ejecutar mi prueba sin esperar el intervalo TIME_WAIT. – Daryl
Creo que también hay un parámetro de límite de velocidad, pero no encontré una referencia de MSDN para eso. La otra sospecha que tengo es la cantidad de almacenamientos intermedios de red disponibles. – tvanfosson
No necesita un enlace explícito para lidiar con el límite dinámico, solo necesita ajustar el límite como lo sugirió tvanfosson. –