2009-02-06 9 views
7

Actualmente estoy traduciendo una API de C# a Java que tiene un componente de red.Programación de red: ¿para mantener los enchufes o no?

La versión C# parece mantener las secuencias de entrada y salida y el socket abierto durante la duración de sus clases.

¿Es esto correcto?

Teniendo en cuenta que la aplicación envía comandos y recibe eventos en función de la entrada del usuario, ¿es más sensato abrir una nueva secuencia de socket para cada "mensaje"?

Estoy manteniendo un ServerSocket para escuchar el servidor lanzando eventos, pero no estoy tan seguro de que mantener una fuente de salida y Socket para las comunicaciones salientes sea una buena idea.

No estoy acostumbrado a la programación de Socket. Al igual que con muchos desarrolladores, suelo trabajar en la capa de aplicaciones cuando necesito hacer networking y no en la capa de socket, y han pasado 5 o 6 años desde que hice esto en la universidad.

¡Saludos por la ayuda. Supongo que esto es más pedir consejo que una respuesta definitiva.

+0

Oh, espera, veo ... – Svante

+0

Estoy confundido, ¿ves qué? –

+1

Sé que esta pregunta tiene 2,5 años, pero diría esto (como creo que vale la pena decir): grupos de conexión. Eso es lo que desea usar (o implementar si su aplicación no tiene acceso a una ya creada). –

Respuesta

14

Existe una compensación entre el costo de mantener las conexiones abiertas y el costo de crear esas conexiones.

Crear conexiones cuesta tiempo y ancho de banda. Tienes que hacer el handshake de 3 vías TCP, iniciar una nueva cadena de servidor, ...

Mantener conexiones abiertas cuesta principalmente la memoria y las conexiones. Las conexiones de red son un recurso limitado por el sistema operativo. Si tiene demasiados clientes conectados, es posible que se quede sin conexiones disponibles. Costará memoria ya que tendrá un hilo abierto para cada conexión, con su estado asociado.

El equilibrio correcto será diferente según el uso que espere. Si tiene una gran cantidad de clientes conectados por un período corto de tiempo, probablemente sea más eficiente cerrar las conexiones. Si tiene pocos clientes conectados durante un período prolongado de tiempo, probablemente debería mantener las conexiones abiertas ...

2

Depende de la frecuencia con la que esperas que el usuario escriba los comandos. Si sucede con poca frecuencia, quizás podría cerrar los enchufes. Si es frecuente, crear sockets repetidamente puede ser una operación costosa.

Dicho esto, ¿qué tan caro es, en términos de recursos de máquina, tener una conexión de socket abierta para datos infrecuentes? ¿Por qué crees exactamente que "mantener un zócalo y un flujo de salida para las comunicaciones salientes no es una buena idea" (a pesar de que parece lo correcto)? Por otro lado, esto es diferente para las secuencias de archivos si espera que otros procesos quieran usar el mismo archivo. Cerrar el flujo de archivos rápidamente en este caso sería el camino a seguir.

¿Cuán probable es que se quede sin la cantidad de conexiones TCP que puede crear, que otros procesos que realizan conexiones salientes podrían querer usar? ¿O espera tener una gran cantidad de clientes conectados a su servidor a la vez?

+0

Te quedarás sin conexiones mucho antes de que te quedes sin números de puerto. – paxdiablo

+0

one server one client Así que no se quedará sin conexiones. puerto se especifica como la API es un contenedor alrededor de un protocolo basado en TCP. –

+0

Malo, creo que también olvidé mi programación de red – Mystic

3

Si solo tiene un socket único en el cliente y el servidor, debe mantenerlo abierto durante tanto tiempo como sea posible.

3

Si su aplicación y el servidor al que se refiere están cerca, en red, PUEDE ser sensato cerrar la conexión, pero si están distantes, en red, probablemente sea mejor dejar el socket en vivo para la duración.

Guillaume mencionó el handshake de 3 vías y eso básicamente significa que abrir un socket tomará un mínimo de 3 veces el tiempo de tránsito del paquete más corto. Eso se puede aproximar mediante "la mitad del ping de ida y vuelta" y puede alcanzar fácilmente entre 60 y 100 ms para distancias largas. Si termina con una espera adicional de 300 ms, para cada comando, ¿afectará eso la experiencia del usuario?

Personalmente, dejaría el socket abierto, es más fácil y no cuesta tiempo para cada instancia de "necesidad de enviar algo", el costo relativo es pequeño (un descriptor de archivo, un poco de memoria para las estructuras de datos en espacio de usuario y algo de almacenamiento adicional en el kernel).

0

También puede consultar DatagramSocket y DatagramPacket. La ventaja es menor por encima de la cabeza, la desventaja es el over-head que ofrece Socket regular.

+0

No tengo la opción de cambiar el protocolo, me estoy conectando a una aplicación de proveedor. –

+0

¿Y requiere la fiabilidad para ser implementado por el desarrollador? ¡No señor! – hexafraction

0

Le sugiero que consulte el uso de una solución de mensajería existente como ActiveMQ o Netty. Esto manejará muchos de los problemas que puede encontrar con los mensajes.

0

Llego un poco tarde, pero no vi a nadie sugerir eso.

Creo que sería conveniente considerar agrupar sus conexiones (no importa si Socket o TCP), poder mantener abiertas las conexiones de par y reutilizarlas rápidamente en su base de código sería óptimo en caso de rendimiento.

De hecho, el compilador de Roslyn utiliza ampliamente esta técnica en muchos lugares. https://github.com/dotnet/roslyn/search?l=C%23&q=pooled&type=&utf8=%E2%9C%93

Cuestiones relacionadas