write socketclient socket read getoutputstream examples java sockets networking tcp

socketclient - "Java.net.BindException: dirección que ya está en uso" al intentar hacer una creación y destrucción rápida de socket para pruebas de carga



socketclient java (3)

Creo que debe planificar el puerto que desea usar para conectarse y estar en uso. Con eso me refiero a intentar conectar usando el puerto dado. Si la conexión falla (o en su caso arroja una excepción), intente abrir la conexión utilizando el siguiente número de puerto.

Intente envolver la declaración de connect en un try/catch .

Aquí hay un pseudo-código que transmite lo que creo que funcionará:

portNumber = x //where x is the first port number you will try numConnections = 200 // or however many connections you want to open while(numConnections > 0){ try{ connect(host, portNumber) numConnections-- }catch(){} portNumber++ }

Este código no cubre casos de esquina como "¿qué sucede cuando todos los puertos están en uso?"

Estoy intentando cargar la prueba de un servidor Java abriendo una gran cantidad de conexiones de socket al servidor, autenticando, cerrando la conexión, y luego repitiendo. Mi aplicación funciona bien por un tiempo, pero eventualmente obtengo:

java.net.BindException: dirección que ya está en uso: connect

De acuerdo con la documentación que leí, la razón de esto es que los sockets cerrados aún ocupan la dirección local que se les asignó durante un período de tiempo después de llamar a close (). Esto depende del sistema operativo, pero puede ser del orden de minutos. Intenté llamar a setReuseAddress(true) en el socket con la esperanza de que su dirección sería reutilizable inmediatamente después de llamar a close() . Lamentablemente, este no parece ser el caso.

Mi código para la creación de socket es:

Socket socket = new Socket(); socket.setReuseAddress(true); socket.connect(new InetSocketAddress(m_host, m_port));

Pero sigo teniendo este error:

java.net.BindException: dirección que ya está en uso: conectarse después de un tiempo.

¿Hay alguna otra manera de lograr lo que estoy tratando de hacer? Me gustaría, por ejemplo, abrir 100 tomas, cerrarlas todas, abrir 200 tomas, cerrarlas todas, abrir 300, etc. hasta un máximo de 2000 tomas.

¡Cualquier ayuda sería muy apreciada!


Está agotando el espacio de los puertos de salida abriendo muchos sockets de salida dentro del período TIME_WAIT de dos minutos. La primera pregunta que debes hacerte es, ¿representa esto una prueba de carga realista? ¿Realmente un verdadero cliente va a hacer eso? Si no, solo necesita revisar su metodología de prueba.

BTW SO_LINGER es la cantidad de segundos que la aplicación esperará durante close () para que los datos se descarguen. Normalmente es cero. El puerto se mantendrá durante el intervalo TIME_WAIT de todos modos si este es el final que emitió el cierre. Esto no es lo mismo. Es posible abusar de la opción SO_LINGER para corregir el problema. Sin embargo, eso también causará un comportamiento excepcional en el par y, nuevamente, este no es el propósito de una prueba.


No usar bind () pero setReuseAddress (true) es simplemente extraño, espero que entiendas las implicaciones de setReuseAddress (y el punto de). 100-2000 no es una gran cantidad de sockets para abrir, sin embargo, el servidor al que está intentando conectarse (dado que tiene el mismo par de addr / puerto), puede soltarlos con una acumulación normal de 50.

Editar: si necesita abrir múltiples tomas rápidamente (¿escaneo de puerto ermm?), Recomiendo utilizar NIO y connect () / finishConnect () + Selector. La apertura de 1000 sockets en el mismo hilo es simplemente lenta. Olvidó que puede necesitar finishConnect () de cualquier manera en su código.