2011-02-17 26 views
10

Mi aplicación de servidor utiliza TIdTCPServer, varias aplicaciones de cliente utilizan TIdTCPClients para conectarse al servidor (todas las computadoras están en la misma LAN).Práctica recomendada: ¿Mantener la conexión TCP/IP abierta o cerrada después de cada transferencia?

Algunos de los clientes solo necesitan ponerse en contacto con el servidor cada dos minutos, otros una vez por segundo y uno lo hará aproximadamente 20 veces por segundo.

Si mantengo abierta la conexión entre un Cliente y el Servidor, guardaré la reconexión, pero debo verificar si la conexión se pierde.

Si cierro la conexión después de cada transferencia, tiene que volver a conectarse todas las veces, pero no es necesario verificar si la conexión aún está allí.

¿Cuál es la mejor manera de hacerlo?

¿A qué frecuencia de transferencias de datos debo mantener la conexión abierta en general?

¿Cuáles son otras ventajas/desventajas para ambos escenarios?

+3

La sobrecarga de hacer una nueva conexión TCP es principalmente unas pocas vueltas. Y esos son bastante rápidos en LAN. Así que cerraría la conexión después de unos segundos de no usarla. – CodesInChaos

+3

Pero lo escribiría de la manera más simple (muy probablemente cierre instantáneo) primero y luego verificará si el rendimiento es satisfactorio. – CodesInChaos

+4

Ver mi respuesta a esta pregunta: http://stackoverflow.com/questions/4872800/socket-open-and-close-on-1-sec-or-to-hold-open/4873002#4873002 –

Respuesta

8

Sugeriría una mezcla de los dos. Cuando se abre una nueva conexión, inicie un temporizador de inactividad. Siempre que se intercambien datos, reinicie el temporizador. Si el temporizador transcurre, cierre la conexión. Si la conexión se ha cerrado cuando los datos deben enviarse, abra una nueva conexión y repita. De esta forma, las conexiones que se usan con menos frecuencia se pueden cerrar periódicamente, mientras que las conexiones más utilizadas suelen permanecer abiertas.

+0

Remy, buen trabajo en Indy en los últimos años ;-) Utilizo mucho los componentes TCP de Indy, y me refiero ampliamente, como parte intrínseca de mi marco de aplicaciones distribuidas. Es posible que desee echarle un vistazo. – Misha

6

Si bien puede estar bien conectar y desconectar para una aplicación que está activa una vez cada pocos minutos, la aplicación que se comunica varias veces por segundo verá un aumento de rendimiento al dejar la conexión abierta.

Además, su código será mucho más simple si no está tratando de abrir, cerrar o diagnosticar constantemente una conexión abierta. Con la lógica apropiada de apertura y cierre, y SEH alrededor de su lectura y escritura, no hay razón para probar si el socket todavía está conectado antes de usarlo, simplemente úselo. Te dirá cuando hay un problema.

Me inclino por mantener abierta una sola conexión en la mayoría de las aplicaciones empresariales. Generalmente conducirá a un código más limpio, que es más fácil de mantener.

/twocents

8

dos centavos del experimento ...

Mi primera TCP/aplicación cliente/servidor IP utilizaba una nueva conexión y un nuevo hilo para cada solicitud ... Hace años ...

Luego descubrí (usando ProcessExplorer) que consumió algunos recursos de red porque de hecho todas las conexiones cerradas no se destruyen, sino que permanecen en un estado particular durante un tiempo. Se crearon muchos hilos ...

Incluso tuve algunos problemas de conexión con muchas solicitudes de concurent: ¡No tenía suficientes puertos en mi servidor!

Entonces I rewrote it, siguiendo el esquema HTTP/1.1, y la característica KeepAlive. Es mucho más eficiente, utiliza una pequeña cantidad de subprocesos y ProcessExplorer le gusta a mi nuevo servidor. Y nunca me vuelvo a quedar sin puerto. :)

Si el cliente tiene que ser apagado, voy a utilizar un ThreadPool a, al menos, no cree un hilo por cliente ...

En pocas palabras: si se puede, mantener a su cliente conexiones vivas por algunos minutos.

3

Supongo que todo depende de su objetivo y la cantidad de solicitudes realizadas en el servidor en un momento dado sin mencionar el ancho de banda disponible y el hardware en el servidor.

También debe pensar para el futuro, ¿hay alguna posibilidad de que en el futuro necesite conexiones que se dejen abiertas? si es así, entonces has respondido tu propia pregunta.

He implementado un sistema de chat para un proyecto en el que ~ 50 personas (el número crece cada 2 meses) están siempre conectadas y además de conversar también incluye transferencia de datos, manipulación de bases de datos usando ciertos comandos, etc. la implementación mantiene la conexión con el servidor abierta desde el inicio de la aplicación hasta que se cierra la aplicación, sin problemas hasta el momento; sin embargo, si se pierde una conexión por algún motivo, se restablece automáticamente y todo continúa de manera impecable.

En general, le sugiero que intente ambos (manteniendo la conexión abierta y cerrándola después de que se esté utilizando) y vea cuál se ajusta mejor a sus necesidades.

3

A menos que esté escalando a muchos cientos de conexiones simultáneas, definitivamente lo mantendría abierto; esta es de lejos la mejor de las dos opciones. Una vez que haya escalado cientos de miles de conexiones simultáneas, es posible que tenga que desconectarse y volverse a conectar. He diseñado todo mi framework alrededor de esto (http://www.csinnovations.com/framework_overview.htm) ya que me permite "enviar" datos al cliente desde el servidor siempre que sea necesario. Necesita escribir un poco de código para asegurarse de que la conexión esté funcionando correctamente (interrupciones de la red, pings temporizados, etc.), pero si hace esto en su "marco", entonces su código de la aplicación se puede escribir en tal forma en que puede suponer que la conexión siempre está "activa".

0

El problema es el límite de subprocesos por aplicación, alrededor de 1400 subprocesos. Así, un máximo de 1300 clientes conectados al mismo tiempo + -.

+0

Aunque el grupo de subprocesos del sistema operativo preferiría ver implementado en los servidores de Indy (en lugar de hacerlo por subproceso del cliente), lo que usted reclama aquí no es correcto; consulte p. Ej. https://blogs.msdn.microsoft.com/oldnewthing/20050729-14/?p=34773 – Victoria

0

Al cerrar las conexiones como cliente, el puerto que utilizó no estará disponible por un tiempo. Por lo tanto, a un volumen alto, estás usando montones de puertos diferentes. Para cualquier cosa repetitiva lo mantendría abierto.

Cuestiones relacionadas