2011-01-14 17 views
8

Citando this socket tutorial:tomas pasivas y activas

enchufes son de dos tipos primarios. Un socket activo está conectado a una toma de corriente activa a distancia a través de un conjunto de datos abiertos conexión ... Un socket pasivo se no están conectados, sino que espera una conexión entrante, que generar un nuevo socket activo una vez que una conexión es establecida ...

cada puerto puede tener una sola toma pasiva enganchan a ella, a la espera conexiones entrantes, y tomas múltiples activos, cada uno correspondientes a una conexión abierta en el puerto. Es como si el trabajador de la fábrica está a la espera de nuevas mensajes para llegar (que representa la toma pasiva), y cuando uno mensaje llega de un nuevo emisor, que inicia una correspondencia (una conexión ) con ellos por delegante alguien más (un socket activo ) para leer realmente el paquete y responder de nuevo al remitente si es necesario . Esto permite que el trabajador de fábrica sea libre de recibir nuevos paquetes . ...

Entonces el tutorial explica que, después de que se establece una conexión, el socket activo continúa la recepción de datos hasta que no hay bytes restantes, y luego se cierra la conexión.

Lo que no entendí es esto: supongamos que hay una conexión entrante al puerto y el remitente desea enviar algunos datos pequeños cada 20 minutos. Si el socket activo cierra la conexión cuando no hay bytes restantes, ¿el remitente tiene que volver a conectarse al puerto cada vez que desea enviar datos? ¿Cómo persistimos una conexión establecida una vez por un tiempo más largo? ¿Puedes decirme qué me falta aquí?

Mi segunda pregunta es, ¿quién determina el límite de los enchufes activos que funcionan simultáneamente?

+1

Está parafraseando ese artículo y tomando partes de diferentes secciones del artículo. Los contextos son diferentes. En la última sección, el autor está explicando su programa. Los zócalos no actúan así por defecto, de hecho, si se olvida de cerrar el zócalo, pueden suceder cosas malas. El socket no cierra automágicamente cuando se recibe el último byte. – SRM

+0

OK, pensé que esa era la convención y simplemente me preguntaron qué me falta aquí. Soy nuevo en los conceptos y es por eso que quiero cuestionar todo lo que encuentro difícil de entender. – aslisabanci

+0

No hay problema, solo quería asegurarme de que entendiera que debe cerrar el socket explícitamente. Podría ahorrarte algunos dolores de cabeza cuando estés rascándote la cabeza tratando de descubrir por qué el zócalo no se cerró :). – SRM

Respuesta

6

El remitente debe enviar un paquete KEEPALIVE a intervalos regulares para mantener la conexión activa. El formato de KEEPALIVE depende del protocolo. Podría ser tan pequeño como un único NULL en el segmento de datos TCP.

En cuanto a la segunda pregunta ... depende de la E/S. Si está bloqueando la E/S, entonces solo quiere que se ejecute una cierta cantidad de subprocesos en su computadora, por lo que no podrá tener muchos clientes. Si no es bloqueante, puede tener muchos más clientes. Los lenguajes de programación deben tener soporte para E/S bloqueantes y no bloqueantes. (Sé con certeza que Java lo hace).

También depende de cosas como el ancho de banda, la transferencia de datos para cada cliente, memoria, velocidad del reloj, etc. Pero no bloquear vs. bloquear puede hacer una gran diferencia en la cantidad de clientes que puedes aceptar Probablemente no puedas tener más de 5-10 clientes bloqueando sin que tu servidor se cuelgue ... pero puedes tener miles si no estás bloqueando.

+0

¿Continuamente enviando estos paquetes de keepalive por 20 minutos una operación más barata que restablecer la conexión cada vez? ¿Cuáles serían las ventajas de mantener viva la conexión, además de evitar la sobrecarga de la reconexión? – aslisabanci

+1

En realidad, si tiene una gran cantidad de clientes conectados y cada solicitud será rápida (20 segundos como usted dijo), entonces es mejor utilizar un patrón de tipo de solicitud/respuesta. Solo tiene 64k puertos disponibles, lo que significa que solo se pueden aceptar los sockets de 64k en una IP antes de que se agote el puerto a menos que dichos sockets estén cerrados. Sin embargo, realmente depende de tu aplicación. Si está escribiendo un MMO por ejemplo, necesita conexiones persistentes. Si está escribiendo un servidor web, no necesitará (y tratará de evitar) conexiones persistentes (a menos que esté utilizando HTML5, pero esa es una historia difícil). – SRM

+2

Desde la perspectiva del cliente, un simple keepalive a un solo servidor no es mucho trabajo. Probablemente ya esté enviando media docena de keepalives regularmente cuando esté conectado a internet. Desde la perspectiva del servidor, puede ser ventajoso mantener el número de sockets en su lista de sockets al mínimo, para mejorar el rendimiento de E/S. Si es tan larga como una espera de 20 minutos entre transferencias de datos, crearía una nueva conexión cada vez. Es insignificante para el cliente, pero no para el servidor. – ktm5124

0

Primera pregunta: Sí, una vez que se cierra una toma, debe hacer un abrir para reiniciar la comunicación.

Segunda pregunta: Usted hace.Si lo desea, puede crear 64k conexiones a su servidor y sufrir el agotamiento del puerto (no lo recomiendo). Como dijo ktm5124, todo depende de su aplicación. Hay varias maneras diferentes de hacer que su servidor sea escalable, incluido el uso de E/S asincrónicas y/o un grupo de subprocesos para manejar las solicitudes de los clientes.

+0

Consulte la respuesta de Will http://stackoverflow.com/a/2332756/1418457 tal vez malinterprete algo sobre TCP – onmyway133

+0

Bien, si el agotamiento del puerto tcp/ip es algo del lado del cliente solamente (como lo indica el límite de 64k por cliente) por puerto de servidor), entonces ¿por qué hay un problema real de agotamiento de puertos en los servidores? Aún puede usar todos los valores de la tupla; tal vez mi número de 64k sea incorrecto, pero hay un límite estricto para la cantidad de combinaciones que puede contener la tupla. Cuando se quede sin combinaciones, a menos que esté reutilizando la dirección, se quedará sin direcciones (una tupla única realmente) para asignar la conexión entrante y se rechazará la conexión. – SRM

3

No confunda los paquetes reales enviados por la implementación de TCP/IP a través de la red y la interacción entre su programa y una biblioteca que implemente TCP/IP.

El socket es solo una abstracción que se presenta a su programa mediante la implementación de TCP/IP (biblioteca o kernel OS). Puede visualizar el socket como conexión a la tubería (localIP: puerto-remoteIP: puerto). Su programa abre el zócalo, comunica los datos a través del zócalo y puede cerrar el zócalo si ya no es necesario para ayudar a liberar recursos. Esto es flujo normal. Sin embargo, la implementación de TCP/IP puede cerrar el socket por sus propios motivos válidos. Algunas de estas razones: desconexión del cable de acceso a la red, errores de enrutamiento de la red, caída del servidor, etc. Por lo tanto, su programa puede encontrar el zócalo tcp/ip cerrado incluso si no lo cerró.

Ahora su primera pregunta, ¿qué hago si mi programa envía segmentos de datos pequeños con una larga pausa entre ellos. La respuesta es: depende de cuánto tiempo es la pausa y qué programa te escucha en el otro lado. La mayoría de las implementaciones TCP/IP tienen una noción de tiempo de conexión para proporcionar abstracciones de conexión confiable sobre redes reales no confiables. Por lo tanto, si su programa pausará por más tiempo que tcp/ip, verá que la biblioteca ha cerrado su socket y deberá volver a abrir el socket. Eso también puede hacer que reinicie la comunicación de nuevo, depende de un programa que lo escuche al otro lado del conducto de conexión tcp/ip.

Existen formas de aumentar el tiempo de espera de tcp/ip y mantenerlo activo. Esos pueden hacerse como parte de la configuración de la red, la configuración del software del servidor en el otro extremo o si usted explícitamente pide mantener el socket abierto configurando los parámetros KEEPALIVE en su llamada a la biblioteca tcp/ip. ¿Seguiría abierto o no? Los detalles completos de cómo tcp/ip mantendría el socket abierto no deberían confundirte, ya que no tienen nada que ver con tu código. TCP/IP tiene muchas configuraciones y diferentes tiempos de espera para proporcionar a su programa la ilusión de una conexión estable y confiable. Lo bueno es que todo está oculto de su código de programa, siempre y cuando no lo abuse. Mantenga su pausa en unos pocos segundos :) Un conjunto de configuraciones de tiempo de espera puede funcionar bien para aplicaciones pequeñas en redes locales confiables y no funcionará para aplicaciones de carga elevada o conectividad entre continentes. Cada situación específica tiene su propia solución, a menudo más que una sola.

En esta pregunta específica "para enviar algunos datos poco cada 20 minutos", le aconsejo que cierre y abra la conexión de socket para cada comunicación. El tiempo para abrir uno es menos de un segundo y no debe afectar su comunicación. A cambio, obtiene menos complejidad en su protocolo de comunicación. El receptor siempre comienza con una nueva conexión de socket y ambos sistemas pueden disfrutar de recursos gratuitos en comunicación tcp/ip durante los 20 minutos cuando no los necesite.

Cuestiones relacionadas