Aplicación cliente-servidor en un socket de flujo TCP

El siguiente ejemplo utiliza TCP para proporcionar flujos de bytes bidireccionales ordenados y confiables. Construyamos una aplicación completa que incluya un cliente y un servidor. Primero, demostramos cómo construir un servidor en sockets de flujo TCP y luego una aplicación cliente para probar nuestro servidor.

El siguiente programa crea un servidor que recibe solicitudes de conexión de los clientes. El servidor se construye de forma síncrona, por lo que la ejecución del subproceso se bloquea hasta que el servidor accede a conectarse con el cliente. Esta aplicación demuestra un servidor simple que responde a un cliente. El cliente finaliza la conexión enviando un mensaje al servidor. .

Servidor TCP

La creación de la estructura del servidor se muestra en el siguiente diagrama funcional:

Aquí está el código completo para el programa SocketServer.cs:

// SocketServer.cs utilizando el sistema; usando Sistema.Texto; utilizando System.Net; utilizando System.Net.Sockets; espacio de nombres SocketServer ( class Program ( static void Main(string args) ( // Establecer el punto final local para el socket IPHostEntry ipHost = Dns.GetHostEntry("localhost"); IPAddress ipAddr = ipHost.AddressList; IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000); // Crear un socket Tcp/Ip Socket sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Asignar socket al extremo local y escuchar los sockets entrantes try ( sListener.Bind(ipEndPoint) ;sListener.Listener(10); // Comenzar a escuchar conexiones mientras (verdadero) (Console.WriteLine("Esperando una conexión en el puerto (0)", ipEndPoint); // El programa se detiene, esperando una entrada conexión Socket handler = sListener.Accept(); string data = null; // Esperamos a que un cliente intentara conectarse con nosotros byte bytes = new byte; int bytesRec = handler.Receive(bytes); data += Encoding.UTF8. GetString(bytes, 0, bytesRec); // Mostrar datos en la consola Console.Write("Received texto: " + datos + "\n\n"); // Enviando una respuesta al cliente\ string answer = "Gracias por la solicitud en " + data.Length.ToString() + " caracteres"; byte msg = Codificación.UTF8.GetBytes(respuesta); controlador. Enviar (mensaje); if (datos.IndexOf(" ") > -1) ( Console.WriteLine("El servidor finalizó la conexión con el cliente."); break; ) handler.Shutdown(SocketShutdown.Both); handler.Close(); ) ) catch (Exception ex) ( Console.WriteLine (ej.ToString()); ) finalmente ( Console.ReadLine(); ) ) ) )

Veamos la estructura de este programa.

El primer paso es establecer el punto final local para el socket. Antes de abrir un socket para escuchar conexiones, debe preparar una dirección de punto final local para él. La dirección de servicio TCP/IP única se determina mediante la combinación de la dirección IP del host con el número de puerto de servicio que crea el extremo del servicio.

La clase Dns proporciona métodos que devuelven información sobre las direcciones de red admitidas por el dispositivo en red local. Si un dispositivo LAN tiene más de una dirección de red, la clase Dns devuelve información sobre todas las direcciones de red y la aplicación debe seleccionar la dirección adecuada para servir desde la matriz.

Cree un IPEndPoint para el servidor combinando la primera dirección IP del host obtenida del método Dns.Resolve() con el número de puerto:

IPHostEntry ipHost = Dns.GetHostEntry("localhost"); dirección IP ipAddr = ipHost.AddressList; IPEndPoint ipEndPoint = nuevo IPEndPoint(ipAddr, 11000);

Aquí, la clase IPEndPoint representa localhost en el puerto 11000. A continuación, creamos un socket de flujo con una nueva instancia de la clase Socket. Al configurar un punto final local para escuchar las conexiones, puede crear un socket:

Socket sListener = nuevo Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

Enumeración DirecciónFamilia especifica los esquemas de direccionamiento que una instancia de la clase Socket puede usar para resolver una dirección.

en parámetro Tipo de enchufe Los sockets TCP y UDP difieren. Puede incluir los siguientes valores:

dgrama

Soporta datagramas. El valor de Dgram requiere que especifique Udp para el tipo de protocolo e InterNetwork en el parámetro de familia de direcciones.

Crudo

Admite el acceso al protocolo de transporte subyacente.

Corriente

Admite tomas de corriente. El valor Stream requiere que se especifique Tcp para el tipo de protocolo.

El tercer y último parámetro especifica el tipo de protocolo requerido para el socket. en parámetro Tipo de protocolo puede especificar los siguientes valores más importantes: Tcp, Udp, Ip, Raw.

El siguiente paso debe ser asignar el socket con el método Unir(). Cuando un constructor abre un socket, no se le asigna un nombre, solo se reserva un identificador. Se llama al método Bind() para asignar un nombre al socket del servidor. Para que un socket de cliente pueda identificar un socket de flujo TCP, el programa del servidor debe nombrar su socket:

SListener.Bind(ipEndPoint);

El método Bind() vincula un socket a un punto final local. Debe llamar al método Bind() antes de intentar llamar a los métodos Listen() y Accept().

Ahora, habiendo creado un socket y asociado un nombre con él, puede escuchar los mensajes entrantes usando el método escuchar(). En el estado de escucha, el socket esperará los intentos de conexión entrantes:

SListener.Listen(10);

El parámetro define atraso (atraso) Valor que especifica el número máximo de conexiones que esperan ser procesadas en la cola. En el código anterior, el valor del parámetro permite acumular hasta diez conexiones en la cola.

En el estado de escucha, debe estar listo para aceptar conectarse con el cliente, para lo cual se utiliza el método aceptar(). Este método obtiene una conexión de cliente y completa la asociación entre los nombres de cliente y servidor. El método Accept() bloquea el hilo del programa que llama hasta que se recibe una conexión.

El método Accept() recupera la primera solicitud de conexión de la cola de solicitudes pendientes y crea un nuevo socket para manejarla. Mientras se crea el nuevo socket, el socket original continúa escuchando y se puede usar con subprocesos múltiples para aceptar múltiples solicitudes de conexión de los clientes. Ninguna aplicación de servidor debe cerrar el socket de escucha. Debe continuar funcionando junto con los sockets creados por el método Accept para procesar las solicitudes de los clientes entrantes.

Mientras (verdadero) (Console.WriteLine("Esperando una conexión en el puerto (0)", ipEndPoint); // El programa se detiene, esperando una conexión entrante. Socket handler = sListener.Accept();

Una vez que el cliente y el servidor hayan establecido una conexión entre ellos, puede enviar y recibir mensajes usando los métodos Enviar() y recibir() Clase de zócalo.

El método Send() escribe los datos salientes en el socket al que está conectado. El método Receive() lee los datos entrantes en el socket de flujo. Cuando se utiliza un sistema basado en TCP, se debe establecer una conexión entre los sockets antes de que se ejecuten los métodos Send() y Receive(). El protocolo exacto entre dos entidades que interactúan debe determinarse de antemano para que las aplicaciones cliente y servidor no se bloqueen entre sí, sin saber quién debe enviar sus datos primero.

Cuando se completa el intercambio de datos entre el servidor y el cliente, debe cerrar la conexión utilizando los métodos cerrar() y Cerca():

Controlador.Apagado(SocketShutdown.Ambos); controlador.Cerrar();

SocketShutdown es una enumeración que contiene tres valores para detener: Ambas cosas- deja de enviar y recibir datos en el socket, recibir- deja de recibir datos en el socket y enviar- evita que el socket envíe datos.

El socket se cierra cuando se llama al método Close(), que también establece la propiedad Connected del socket en falso.

Cliente en TCP

Las funciones que se utilizan para crear una aplicación de cliente son más o menos como una aplicación de servidor. En cuanto al servidor, se utilizan los mismos métodos para determinar el punto final, instanciar el socket, enviar y recibir datos y cerrar el socket.

Viaje a través de los protocolos de red.

TCP y UDP son protocolos de capa de transporte. UDP es un protocolo sin conexión con entrega de paquetes no garantizada. TCP (Protocolo de control de transmisión) es un protocolo orientado a conexión con entrega garantizada de paquetes. Primero, se produce un apretón de manos (Hola | Hola | ¿Chateemos? | Vamos.), Después de lo cual se considera establecida la conexión. Además, los paquetes se envían de un lado a otro a través de esta conexión (hay una conversación) y se verifica si el paquete ha llegado al destinatario. Si el paquete se pierde, o se alcanza, pero con un bate suma de control, luego se envía nuevamente ("repetir, no escuché"). Por lo tanto, TCP es más confiable, pero es más difícil en términos de implementación y, en consecuencia, requiere más ciclos/memoria, que no es lo último para los microcontroladores. Los ejemplos de protocolos de aplicación que usan TCP incluyen FTP, HTTP, SMTP y muchos otros.

TL;RD

HTTP (Protocolo de transferencia de hipertexto) es un protocolo de aplicación mediante el cual el servidor envía páginas a nuestro navegador. HTTP es ahora omnipresente en la World Wide Web para recuperar información de sitios web. En la imagen, la lámpara está en un microcontrolador con un sistema operativo integrado, en el que los colores se configuran a través de un navegador.

El protocolo HTTP está basado en texto y es bastante simple. En realidad, así es como se ve el método GET enviado por la utilidad netcat a la dirección IPv6 local del servidor con luces:

~$ nc fe80::200:e2ff:fe58:b66b%mazko 80<

El método HTTP suele ser una palabra corta en inglés escrita en mayúsculas, que distingue entre mayúsculas y minúsculas. Cada servidor debe admitir al menos los métodos GET y HEAD. Además de los métodos GET y HEAD, a menudo se utilizan los métodos POST, PUT y DELETE. El método GET se usa para solicitar el contenido del recurso especificado, en nuestro caso aquí GET /b HTTP/1.0 donde la ruta /b es responsable del color (azul). Respuesta del servidor:

HTTP/1.0 200 OK Servidor: Contiki/2.4 http://www.sics.se/contiki/ Conexión: cerrar Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0 Content- tipo: texto/html Contiki® RGB

El rojo está APAGADO

El verde está APAGADO

azul está encendido

El código de estado (tenemos 200) es parte de la primera línea de la respuesta del servidor. Es un número entero de tres dígitos. El primer dígito indica la clase de estado. El código de respuesta suele ir seguido de una frase explicativa separada por espacios en inglés, que explica a la persona el motivo de tal respuesta. En nuestro caso, el servidor funcionó sin errores, todo estaba en un montón (OK).

Tanto la solicitud como la respuesta contienen encabezados (cada línea es un campo de encabezado separado, el par nombre-valor está separado por dos puntos). Los encabezados terminan con una línea vacía, después de la cual pueden seguir los datos.

Mi navegador se niega a abrir una dirección IPv6 local, por lo que se registra una dirección adicional en el firmware del microcontrolador y también se debe asignar el mismo prefijo a la interfaz de red virtual del simulador:

~$ sudo ip addr add abcd::1/64 dev mazko # linux ~$ netsh interfaz ipv6 establecer dirección mazko abcd::1 # windows ~$ curl http://

Los servidores que implementan estos protocolos en una red corporativa proporcionan al cliente una dirección IP, una puerta de enlace, una máscara de red, servidores de nombres e incluso una impresora. Los usuarios no tienen que configurar manualmente sus hosts para usar la red.

El sistema operativo QNX Neutrino implementa otro protocolo de configuración automática llamado AutoIP, que es un proyecto del comité de configuración automática de IETF. Este protocolo se utiliza en redes pequeñas para asignar direcciones IP de enlace local (link-local) a hosts. El protocolo AutoIP determina la dirección IP del enlace local por sí solo mediante un esquema de negociación con otros hosts y sin acceder a un servidor central.

Uso del protocolo PPPoE

La abreviatura PPPoE significa "Protocolo punto a punto sobre Ethernet". Este protocolo encapsula datos para su transmisión a través de una red Ethernet con una topología en puente.

PPPoE es una especificación para conectar usuarios de Ethernet a Internet a través de una conexión de banda ancha, como una línea de suscriptor digital alquilada, un dispositivo inalámbrico o un módem por cable. El uso del protocolo PPPoE y un módem de banda ancha proporciona a los usuarios de la red informática local acceso autenticado individual a redes de transmisión de datos de alta velocidad.

El protocolo PPPoE combina la tecnología Ethernet con el protocolo PPP, lo que le permite crear efectivamente una conexión separada a un servidor remoto para cada usuario. El control de acceso, la contabilidad de conexiones y la selección del proveedor de servicios se definen para los usuarios, no para los hosts. La ventaja de este enfoque es que ni la compañía telefónica ni el ISP tienen que proporcionar ningún soporte especial para esto.

A diferencia de las conexiones de acceso telefónico, las conexiones de módem por cable y DSL siempre están activas. Debido a que varios usuarios comparten la conexión física con el proveedor de servicios remotos, se necesita un método de contabilidad que registre los remitentes y destinos del tráfico y cobre a los usuarios. El protocolo PPPoE permite que un usuario y un host remoto que participan en una sesión de comunicación aprendan las direcciones de red de cada uno durante un intercambio inicial llamado descubrimiento(descubrimiento). Una vez que se establece una sesión entre un usuario individual y un host remoto (por ejemplo, un proveedor de servicios de Internet), esa sesión se puede monitorear para realizar acumulaciones. Muchos hogares, hoteles y corporaciones comparten Internet a través de líneas de suscriptores digitales que utilizan tecnología Ethernet y el protocolo PPPoE.

Una conexión PPPoE consta de un cliente y un servidor. El cliente y el servidor funcionan utilizando cualquier interfaz que se acerque a las especificaciones de Ethernet. Esta interfaz se utiliza para emitir direcciones IP a los clientes y vincular esas direcciones IP a los usuarios y, opcionalmente, a las estaciones de trabajo, en lugar de la autenticación basada únicamente en la estación de trabajo. El servidor PPPoE crea una conexión punto a punto para cada cliente.

Configuración de una sesión PPPoE

Para crear una sesión PPPoE, utilice el serviciopppoed. Móduloio-paquete-*pProporciona servicios de protocolo PPPoE. Primero necesitas correrio-pkt-*Conconductor adecuado. Ejemplo:

TCP se integra de forma natural en el entorno cliente/servidor (consulte la Figura 10.1). Aplicación de servidor insectos(escuchar) solicitudes de conexión entrantes. Por ejemplo, los servicios WWW, de transferencia de archivos o de acceso a terminales escuchan las solicitudes de los clientes. Las comunicaciones en TCP son iniciadas por las subrutinas apropiadas que inician la conexión con el servidor (consulte el Capítulo 21 sobre la API de socket).

Arroz. 10.1. El cliente llama al servidor.

En realidad, el cliente puede ser otro servidor. Por ejemplo, los servidores de correo pueden conectarse a otros servidores de correo para enviar mensajes de correo electrónico entre computadoras.

10.2 Conceptos de TCP

¿En qué forma deben las aplicaciones enviar datos en TCP? ¿Cómo transfiere TCP datos a IP? ¿Cómo identifican los protocolos TCP de transmisión y recepción una conexión de aplicación a aplicación y los elementos de datos necesarios para implementarla? Todas estas preguntas se responden en las siguientes secciones, que describen los conceptos básicos de TCP.

10.2.1 Flujos de datos de entrada y salida

Conceptual el modelo de conexión asume que una aplicación envía un flujo de datos a una aplicación del mismo nivel. Al mismo tiempo, es capaz de recibir un flujo de datos de su socio de conexión. TCP proporciona duplex completo(dúplex completo) modo de funcionamiento en el que ambos dos corrientes datos (ver Figura 10.2).


Arroz. 10.2. Las aplicaciones intercambian flujos de datos.

10.2.2 Segmentos

TCP puede convertir el flujo de datos salientes de una aplicación en una forma adecuada para su colocación en datagramas. ¿Cómo?

La aplicación envía datos a TCP, y este protocolo los pone en búfer de salida(búfer de envío). A continuación, TCP corta fragmentos de datos del búfer y los envía, agregando un encabezado (en este caso, segmentos segmento). En la fig. 10.3 muestra cómo los datos de búfer de salida Los TCP se empaquetan en segmentos. TCP pasa el segmento a IP para su entrega como un solo datagrama. Empaquetar los datos en fragmentos de la longitud correcta garantiza un reenvío eficiente, por lo que TCP esperará hasta que la cantidad adecuada de datos esté en el búfer de salida antes de crear un segmento.


Arroz. 10.3 Creación de un segmento TCP

10.2.3 Empujar

Sin embargo, grandes cantidades de datos a menudo no son aplicables a aplicaciones reales. Por ejemplo, cuando el programa cliente de un usuario final inicia una sesión interactiva con un servidor remoto, el usuario solo ingresa comandos (seguidos de presionar el devolver).

El programa cliente del usuario necesita TCP para saber que los datos se envían al host remoto y realizar esta operación de inmediato. En este caso, se utiliza extrusión(empujar).

Si observa las operaciones en una sesión interactiva, puede encontrar muchos segmentos con pocos datos y, lo que es más, se pueden encontrar popping en casi todos los segmentos de datos. Sin embargo, no se debe utilizar popping durante las transferencias de archivos (excepto para el último segmento), y TCP podrá empaquetar datos en segmentos de manera más eficiente.

10.2.4 Datos urgentes

El modelo de reenvío de datos de la aplicación asume un flujo ordenado de bytes en su camino hacia el destino. Refiriéndose nuevamente al ejemplo de la sesión interactiva, suponga que el usuario presionó una tecla atención(atención) o descanso(interrumpir). La aplicación remota debe poder omitir los bytes que interfieren y responder a la pulsación de tecla lo antes posible.

Mecanismo datos urgentes(datos urgentes) marca información especial en el segmento como urgente. Con esto, TCP le dice a su par que el segmento contiene datos urgentes y puede indicar dónde está. El socio debe enviar esta información a la aplicación de destino lo antes posible.

10.2.5 Puertos de aplicación

El cliente debe identificar el servicio al que quiere acceder. Esto se hace mediante la especificación de la dirección IP del servicio de host y su número de puerto TCP. Al igual que con UDP, los números de puerto TCP van del 0 al 65535. Los puertos del 0 al 1023 se conocen como puertos conocidos y se utilizan para acceder a servicios estándar.

En la Tabla 10.1 se muestran algunos ejemplos de puertos conocidos y sus correspondientes aplicaciones. Servicios Desechar(puerto 9) y cargado(puerto 19) son versiones TCP de los servicios que ya conocemos de UDP. Tenga en cuenta que el tráfico en el puerto TCP 9 está completamente aislado del tráfico en el puerto UDP 9.


Tabla 10.1 Puertos TCP conocidos y sus aplicaciones correspondientes

Puerto Solicitud Descripción
9 Desechar Cancelar todos los datos entrantes
19 cargado Generador de personajes. Intercambio de flujo de caracteres
20 Datos FTP Puerto de reenvío FTP
21 FTP Cuadro de diálogo Puerto para FTP
23 TELNET Puerto para inicio de sesión remoto a través de Telnet
25 SMTP Puerto de protocolo SMTP
110 POP3 Servicio de muestreo de correo de computadora personal
119 NNTP Acceso a noticias en línea.

¿Qué pasa con los puertos utilizados por los clientes? En casos excepcionales, el cliente no se ejecuta en un puerto conocido. Pero en tales situaciones, al querer abrir una conexión, a menudo le pide al sistema operativo que le asigne un puerto no utilizado y no reservado. Al final de la conexión, el cliente debe devolver este puerto, después de lo cual otro cliente puede reutilizarlo. Debido a que hay más de 63 000 puertos TCP en el grupo de números no reservados, los límites de puerto del cliente se pueden ignorar.

10.2.6 direcciones de socket

Como ya sabemos, la combinación de dirección IP y puerto para la comunicación se llama dirección del zócalo. Una conexión TCP se identifica completamente mediante una dirección de socket en cada extremo de esa conexión. En la fig. La Figura 10.4 muestra una conexión entre un cliente con dirección de socket (128.36.1.24, puerto = 3358) y un servidor con dirección de socket (130.42.88.22, puerto = 21).

Arroz. 10.4. direcciones de socket

El encabezado de cada datagrama contiene las direcciones IP de origen y destino. A continuación, verá que los números de puerto de origen y destino se especifican en el encabezado del segmento TCP.

Por lo general, un servidor es capaz de administrar varios clientes al mismo tiempo. Las direcciones de socket únicas de un servidor se asignan simultáneamente a todos sus clientes (consulte la figura 10.5).


Arroz. 10.5. Múltiples clientes conectados a direcciones de socket de servidor

Dado que el datagrama contiene un segmento de conexión TCP identificado por direcciones IP y puertos, es muy fácil para un servidor realizar un seguimiento de múltiples conexiones a clientes.

10.3 Mecanismo de confiabilidad de TCP

En esta sección, veremos el mecanismo TCP utilizado para entregar datos de manera confiable mientras se preserva el orden de reenvío y se evitan pérdidas o duplicaciones.

10.3.1 Numeración y confirmación

TCP utiliza la numeración y el reconocimiento (ACK) para garantizar una transferencia de datos confiable. El esquema de numeración TCP es algo inusual: cada reenviado a través de la conexión octeto se considera que tiene un número de serie. El encabezado del segmento TCP contiene un número de secuencia el primer octeto de datos de este segmento.

El receptor está obligado a acusar recibo de los datos. Si no llega ningún ACK dentro del intervalo de tiempo de espera, los datos se retransmiten. Este método se llama reconocimiento positivo con relé(reconocimiento positivo con retransmisión).

El receptor de los datos TCP realiza una verificación estricta de los números de secuencia entrantes para verificar la secuencia en la que se recibieron los datos y que no haya partes perdidas. Dado que el ACK puede perderse o retrasarse aleatoriamente, pueden llegar segmentos duplicados al receptor. Los números de secuencia le permiten determinar la duplicación de datos, que luego se descarta.

En la fig. La figura 10.6 muestra una vista simplificada del tiempo de espera y la retransmisión en TCP.


Arroz. 10.6. Tiempo de espera y retransmisión en TCP

10.3.2 Campos de puerto, secuencia y ACK en el encabezado TCP

Como se muestra en la fig. 10.7, los primeros campos del encabezado TCP proporcionan espacio para los valores de los puertos de origen y destino, el número de secuencia del primer byte de los datos incrustados y un ACK igual al número de secuencia Siguiente byte esperado en el otro extremo. En otras palabras, si el TCP recibe todos los bytes hasta 30 de su par, este campo tendrá el valor 31, indicando el segmento que se reenviará a continuación.


Arroz. 10.7. Valores iniciales en campos de cabecera TCP

Cabe señalar un pequeño detalle. Suponga que TCP ha enviado los bytes 1 a 50 y no hay más datos para enviar. Si se reciben datos de un par, TCP debe acusar recibo enviando un encabezado sin datos adjuntos. Naturalmente, el valor ACK está presente en este encabezado. En el campo de secuencia - el valor 51, es decir siguiente número de byte pretende enviar TCP. Cuando TCP envíe los siguientes datos, el nuevo encabezado TCP también tendrá el valor 51 en el campo de secuencia.

10.4 Establecer una conexión

¿Cómo se conectan las dos aplicaciones? Antes de la comunicación, cada uno de ellos llama a una subrutina para formar un bloque de memoria que se utilizará para almacenar los parámetros TCP e IP de esta conexión, como direcciones de socket, número de secuencia actual, valor de vida inicial, etc.

La aplicación del servidor espera a que aparezca un cliente que, queriendo acceder al servidor, emite una solicitud para compuesto(conectar) identificando la dirección IP y el puerto del servidor.

Hay una característica técnica. Cada lado comienza a numerar cada byte no desde uno, sino desde número de serie aleatorio(Veremos por qué se hace esto más adelante). La especificación original aconseja generar el número de secuencia inicial basado en un temporizador externo de 32 bits que se incrementa aproximadamente cada 4 µs.

10.4.1 Guión de conexión

El procedimiento de conexión a menudo se denomina protocolo de enlace de tres vías, ya que se intercambian tres mensajes para establecer una conexión: SYN, SYN y ACK.

Durante el establecimiento de una conexión, los socios intercambian tres datos importantes:

1. La cantidad de espacio de búfer para recibir datos

2. La cantidad máxima de datos transportados en el segmento entrante

3. Número de secuencia inicial utilizado para los datos salientes

Tenga en cuenta que cada lado usa las operaciones 1 y 2 para indicar límites a los que actuará la otra parte. Una computadora personal puede tener un búfer de recepción pequeño, mientras que una supercomputadora puede tener un búfer enorme. La estructura de memoria de una computadora personal puede limitar las porciones entrantes de datos a 1 KB, y la supercomputadora se controla con grandes segmentos.

La capacidad de controlar cómo el otro lado envía datos es una característica importante que hace que TCP/IP sea escalable.

En la fig. La figura 10.8 muestra un script de conexión de ejemplo. Se proporcionan números de secuencia de inicio muy simples para no sobrecargar la figura. Tenga en cuenta que en esta figura, el cliente puede recibir segmentos más grandes que el servidor.


Arroz. 10.8. Estableciendo una conexión

Se realizan las siguientes operaciones:

1. El servidor se inicializa y está listo para conectarse con los clientes (este estado se denomina apertura pasiva - apertura pasiva).

2. El cliente solicita a TCP que abra una conexión con el servidor en la dirección IP y el puerto especificados (este estado se denomina apertura activa).

3. El cliente TCP recibe el número de secuencia inicial (1000 en este ejemplo) y envía segmento de tiempo(segmento de sincronización - SYN). En este segmento se envía el número de secuencia, el tamaño de la ventana de recepción (4K) y el tamaño del segmento más grande que puede recibir el cliente (1460 bytes).

4. Cuando llega un SYN, el servidor TCP recibe mía número de secuencia inicial (3000). Envía un segmento SYN que contiene el número de secuencia inicial (3000), ACK 1001 (lo que significa numerar el primer byte enviado por el cliente como 1001), el tamaño de la ventana de recepción (4K) y el tamaño del segmento más grande que el servidor puede recibir. (1024 bytes).

5. El cliente TCP, después de haber recibido un mensaje SYN/ACK del servidor, devuelve el ACK 3001 (el primer byte de los datos enviados por el servidor debe numerarse como 3001).

6. El cliente TCP le dice a su aplicación que abra una conexión.

7. El servidor TCP, al recibir un mensaje ACK del cliente TCP, informa a su aplicación que se ha abierto la conexión.

El cliente y el servidor anuncian sus reglas para los datos recibidos, sincronizan sus números de secuencia y están listos para intercambiar datos. La especificación TCP también permite otro escenario (no muy bueno) donde las aplicaciones del mismo nivel se abren activamente entre sí al mismo tiempo.

10.4.2 Configuración de valores de parámetros IP

La solicitud de una aplicación para establecer una conexión también puede especificar parámetros para los datagramas IP que transportarán los datos de la conexión. Si no se especifica un valor de parámetro específico, se utiliza el valor predeterminado.

Por ejemplo, una aplicación puede elegir el valor deseado para la prioridad de IP o el tipo de servicio. Dado que cada una de las partes conectadas establece de forma independiente su propia prioridad y tipo de servicio, en teoría, estos valores pueden diferir para las diferentes direcciones de los flujos de datos. Como regla general, en la práctica, se aplican los mismos valores para cada dirección de intercambio.

Cuando una aplicación usa opciones de seguridad gubernamentales o militares, cada extremo de la conexión debe usar los mismos niveles de seguridad o la conexión fallará.

10.5 Transmisión de datos

La transferencia de datos comienza después de la finalización de la confirmación de creación de conexión de tres pasos (consulte la Figura 10.9). El estándar TCP permite que se incluyan datos normales en los segmentos de reconocimiento, pero no se entregarán a la aplicación hasta que se complete la conexión. Para simplificar la numeración, se utilizan mensajes de 1000 bytes. Cada segmento de encabezado TCP tiene un campo ACK que identifica el número de secuencia de bytes que se espera recibir del socio de conexión..


Arroz. 10.9. Flujo de datos simple y ACK

El primer segmento enviado por el cliente contiene los bytes del 1001 al 2000. Su campo ACK debe contener el valor 3001, que indica el número de secuencia de bytes que se supone que debe recibir del servidor.

El servidor responde al cliente con un segmento que contiene 1000 bytes de datos (comenzando con el número 3001). Su campo ACK en el encabezado TCP indicará que los bytes 1001 a 2000 ya se recibieron con éxito, por lo que el siguiente número de secuencia de segmento esperado del cliente debería ser 2001.

Luego, el cliente envía segmentos que comienzan con los bytes 2001, 3001 y 4001 en ese orden. Tenga en cuenta que el cliente no espera un ACK después de cada segmento enviado. Los datos se envían al par hasta que su espacio de búfer está lleno (veremos a continuación que el receptor puede especificar con mucha precisión la cantidad de datos que se le enviarán).

El servidor ahorra ancho de banda de conexión mediante el uso de un solo ACK para indicar que todos los segmentos se reenviaron correctamente.

En la fig. La figura 10.10 muestra el envío de datos cuando se pierde el primer segmento. Cuando expira el tiempo de espera, el segmento se retransmite. Tenga en cuenta que al recibir un segmento perdido, el receptor envía un ACK reconociendo el reenvío de ambos segmentos.


Arroz. 10.10. Pérdida y retransmisión de datos

10.6 Cerrar una conexión

La finalización normal de una conexión se realiza utilizando el mismo procedimiento de triple reconocimiento que cuando se abre una conexión. Cada parte puede comenzar a cerrar la conexión en el siguiente escenario:

A:

B:"Bueno".

A:"También terminé el trabajo".

A:"Bueno".

El siguiente escenario también es aceptable (aunque se usa muy raramente):

A:"Terminé el trabajo. No hay más datos para enviar".

A:"Bien. Sin embargo, hay algunos datos..."

A:"También terminé el trabajo".

A:"Bueno".

En el ejemplo siguiente, la conexión cierra el servidor, como suele ser el caso de las comunicaciones cliente/servidor. En este caso, luego de que el usuario ingrese a la sesión telnet comando de cierre de sesión (cerrar sesión en el sistema) el servidor inicia una solicitud para cerrar la conexión. En la situación mostrada en la Fig. 10.11, se realizan las siguientes acciones:

1. La aplicación en el servidor le dice a TCP que cierre la conexión.

2. El servidor TCP envía un Segmento Final (FIN), informando a su par que no hay más datos para enviar.

3. El cliente TCP envía un ACK en el segmento FIN.

4. El TCP del cliente le dice a su aplicación que el servidor quiere cerrar la conexión.

5. La aplicación cliente informa a su TCP que la conexión está cerrada.

6. El cliente TCP envía un mensaje FIN.

7. El servidor TCP recibe el FIN del cliente y responde con un mensaje ACK.

8. El TCP del servidor le dice a su aplicación que cierre la conexión.


Arroz. 10.11. Cerrar una conexión

Ambas partes pueden comenzar a cerrar al mismo tiempo. En este caso, el cierre normal de la conexión se completa después de que cada uno de los pares envíe un mensaje ACK.

10.6.1 Terminación abrupta

Cualquiera de las partes puede solicitar la terminación abrupta de la conexión. Esto es aceptable cuando una aplicación desea finalizar una conexión o cuando TCP detecta un problema de comunicación grave que no puede resolver por sí solo. Se solicita una terminación abrupta enviando uno o más mensajes de reinicio al par, como lo indica una bandera en el encabezado TCP.

10.7 Control de flujo

El receptor TCP se carga con el flujo de datos entrantes y determina cuánta información puede aceptar. Esta restricción afecta al remitente TCP. La siguiente explicación de este mecanismo es conceptual y los desarrolladores pueden implementarla de manera diferente en sus productos.

Durante la configuración de la conexión, cada par asigna espacio para el búfer de entrada de la conexión y notifica esto a la otra parte. Normalmente, el tamaño del búfer se expresa como un número entero de tamaños máximos de segmento.

El flujo de datos ingresa al búfer de entrada y se almacena allí hasta que se reenvía a la aplicación (determinado por el puerto TCP). En la fig. La figura 10-12 muestra un búfer de entrada que puede ocupar 4 KB.


Arroz. 10.12. Ventana de recepción del búfer de entrada

El espacio del búfer se llena a medida que llegan los datos. Cuando la aplicación receptora extrae datos del búfer, el espacio liberado queda disponible para nuevos datos entrantes.

10.7.1 Ventana de recepción

ventana de recepción(ventana de recepción): cualquier espacio en el búfer de entrada que aún no esté ocupado por datos. Los datos permanecen en el búfer de entrada hasta que la aplicación de destino los utiliza. ¿Por qué la aplicación no recopila datos inmediatamente?

Un escenario simple ayudará a responder esta pregunta. Supongamos que un cliente ha subido un archivo a un servidor FTP que se ejecuta en una computadora multiusuario muy ocupada. Luego, el programa FTP debe leer los datos del búfer y escribirlos en el disco. Cuando el servidor realiza operaciones de E/S de disco, el programa espera a que se completen esas operaciones. En este momento, puede comenzar otro programa (por ejemplo, de acuerdo con un cronograma) y para cuando el programa FTP comience nuevamente, los siguientes datos ya estarán en el búfer.

La ventana de recepción se extiende desde el último byte reconocido hasta el final del búfer. En la fig. 10.12, todo el búfer está disponible primero y, por lo tanto, está disponible una ventana de recepción de 4K. Cuando llegue el primer KB, la ventana de recepción se reducirá a 3 KB (por simplicidad, supondremos que cada segmento tiene un tamaño de 1 KB, aunque en la práctica este valor varía según las necesidades de la aplicación). La llegada de los siguientes dos segmentos de 1K reducirá la ventana de recepción a 1K.

Cada ACK enviado por el receptor contiene información sobre el estado actual de la ventana de recepción, según la cual se regula el flujo de datos desde la fuente.

En su mayor parte, el tamaño del búfer de entrada se establece en el momento del inicio de la conexión, aunque el estándar TCP no especifica cómo administrar este búfer. El búfer de entrada puede crecer o reducirse para proporcionar información al remitente.

¿Qué sucede si un segmento entrante se puede colocar en la ventana de recepción, pero llega desordenado? En general, se considera que todas las implementaciones almacenan los datos entrantes en la ventana de recepción y envían un acuse de recibo (ACK) solo para un bloque completo contiguo de varios segmentos. Esta es la forma correcta, porque de lo contrario, descartar datos desordenados degradará significativamente el rendimiento.

10.7.2 Ventana de envío

Un sistema que transmite datos debe realizar un seguimiento de dos características: cuántos datos ya se han enviado y reconocido, y el tamaño actual de la ventana de recepción del receptor. Activo enviando espacio(espacio de envío) Se extiende desde el primer octeto no reconocido a la izquierda de la ventana de recepción actual. Parte ventana usó mandar, indica cuántos datos adicionales se pueden enviar al socio.

El número de secuencia inicial y el tamaño de la ventana de recepción inicial se establecen durante la configuración de la conexión. Arroz. 10.13 ilustra algunas de las características del mecanismo de transferencia de datos.

1. El remitente comienza con una ventana de envío de 4 KB.

2. El remitente envía 1 KB. Se conserva una copia de estos datos hasta que se recibe un acuse de recibo (ACK), ya que es posible que deba retransmitirse.

3. Llega un ACK para el primer KB y se envían los siguientes 2 KB de datos. El resultado se muestra en la tercera parte desde arriba de la Fig. 10.13. El almacenamiento de 2 KB continúa.

4. Finalmente, llega un ACK para todos los datos transmitidos (es decir, todos los recibidos por el receptor). ACK restaura el tamaño de la ventana de envío a 4 KB.

Arroz. 10.13. Enviar ventana

Cabe señalar varias características interesantes:

■ El remitente no espera un ACK para cada uno de los segmentos de datos que envía. La única limitación en la transferencia es el tamaño de la ventana de recepción (por ejemplo, el remitente solo debe transferir 4K segmentos de un byte).

■ Suponga que el remitente envía datos en varios segmentos muy cortos (por ejemplo, 80 bytes). En este caso, los datos se pueden reformatear para una transmisión más eficiente (por ejemplo, en un solo segmento).

10.8 Cabecera TCP

En la fig. La Figura 10.14 muestra el formato del segmento (encabezado TCP y datos). El encabezado comienza con los ID de puerto de origen y destino. siguiente campo número de serie(número de secuencia) indica la posición en el flujo de datos de salida que ocupa este segmento. Campo ACK(confirmación) contiene información sobre el próximo segmento esperado que debería aparecer en el flujo de datos de entrada.


Arroz. 10.14. segmento TCP

Hay seis banderas:

Campo compensaciones de datos(Compensación de datos) contiene el tamaño del encabezado TCP en palabras de 32 bits. El encabezado TCP debe terminar en un límite de 32 bits.

10.8.1 Opción de tamaño máximo de segmento

Parámetro "tamaño máximo de segmento"(tamaño máximo de segmento - MSS) se utiliza para declarar la mayor parte de los datos que puede recibir y procesar el sistema. Sin embargo, el título es algo inexacto. Generalmente en TCP segmento tratado como encabezado más datos. Sin embargo tamaño máximo de segmento definido como:

El tamaño del datagrama más grande que se puede recibir es 40

En otras palabras, el MSS refleja la mayor carga útil en el receptor cuando los encabezados TCP e IP tienen una longitud de 20 bytes. Si hay parámetros adicionales, su longitud debe restarse del tamaño total. Por lo tanto, la cantidad de datos que se pueden enviar en un segmento se define como:

Valor MSS declarado + 40 - (suma de longitudes de encabezado TCP e IP)

Por lo general, los pares intercambian valores MSS en los mensajes SYN iniciales cuando se abre una conexión. Si el sistema no anuncia el tamaño máximo del segmento, se utiliza el valor predeterminado de 536 bytes.

El tamaño máximo del segmento se codifica con un preámbulo de 2 bytes seguido de un valor de 2 bytes, es decir, el valor más grande sería 2 16 -1 (65 535 bytes).

MSS impone un límite estricto a los datos enviados a TCP: el receptor no podrá procesar valores grandes. Sin embargo, el remitente utiliza segmentos tamaño más pequeño ya que el tamaño de MTU a lo largo de la ruta también se determina para la conexión.

10.8.2 Uso de campos de encabezado en una solicitud de conexión

El primer segmento enviado para abrir una conexión tiene un indicador SYN de 1 y un indicador ACK de 0. El SYN inicial es el único un segmento que tiene un campo ACK de 0. Tenga en cuenta que la seguridad usa esta función para detectar solicitudes entrantes para una sesión TCP.

Campo número de serie contiene número de secuencia inicial(número de secuencia inicial), campo ventana - tamaño inicial ventana de recepción. La única configuración de TCP definida actualmente es el tamaño máximo del segmento (cuando no se especifica, se usa el valor predeterminado de 536 bytes) que se supone que debe recibir TCP. Este valor tiene una longitud de 32 bits y suele estar presente en la solicitud de conexión en el campo opciones(Opción). La longitud del encabezado TCP que contiene el valor MSS es de 24 bytes.

10.8.3 Uso de campos de encabezado en una respuesta de conexión

En una respuesta de permiso a una solicitud de conexión, ambos indicadores (SYN y ACK) se establecen en 1. El sistema que responde indica el número de secuencia inicial en el campo correspondiente y el tamaño de la ventana de recepción en el campo Ventana. El tamaño máximo de segmento que el destinatario desea utilizar se suele encontrar en la respuesta de conexión (en el opciones). Este valor puede diferir del valor de la parte que solicita la conexión, es decir. se pueden utilizar dos valores diferentes.

Se puede rechazar una solicitud de conexión especificando un indicador de reinicio (RST) con un valor de 1 en la respuesta.

10.8.4 Selección de un número de secuencia inicial

La especificación TCP asume que durante el establecimiento de una conexión, cada parte elige número de secuencia inicial(basado en el valor actual del temporizador interno de 32 bits). ¿Cómo se hace?

Imagina lo que sucede cuando el sistema falla. Supongamos que el usuario abrió una conexión justo antes del bloqueo y envió una pequeña cantidad de datos. Después de la recuperación, el sistema ya no recuerda nada de lo que se hizo antes del bloqueo, incluidas las conexiones que ya se estaban ejecutando y los números de puerto asignados. El usuario restablece la conexión. Los números de puerto no coinciden con las asignaciones originales y es posible que algunos de ellos ya estén en uso por otras conexiones establecidas unos segundos antes del bloqueo.

Por lo tanto, es posible que el otro lado al final de la conexión no se dé cuenta de que su compañero sufrió un bloqueo y luego se restableció. Todo esto dará lugar a graves interrupciones, especialmente cuando los datos antiguos tardan mucho en pasar a través de la red y se mezclan con los datos de la conexión recién creada. Seleccionar un temporizador de inicio con una actualización (nuevo inicio) elimina tales problemas. Los datos antiguos tendrán una numeración diferente al rango de números de secuencia de la nueva conexión. Los piratas informáticos, cuando falsifican una dirección IP de origen para un host confiable, intentan obtener acceso a las computadoras especificando un número de secuencia de inicio predecible en el mensaje. Una función hash criptográfica basada en claves internas es la mejor manera de seleccionar números semilla seguros.

10.8.5 Uso común de campos

Al preparar el encabezado TCP para la transmisión, el número de secuencia del primer octeto de los datos transmitidos se indica en el campo número de serie(Secuencia de números).

En el campo se introduce el número del siguiente octeto que se espera del socio de conexión. confirmación(Número de reconocimiento) cuando el bit ACK se establece en 1. Campo ventana(Ventana) es para el tamaño de la ventana de recepción actual. Este campo contiene el número de bytes del número de acuse de recibo que se puede aceptar. Tenga en cuenta que este valor permite un control preciso del flujo de datos. Con este valor, el par indica el estado real de la ventana de recepción durante la sesión de intercambio.

Si una aplicación indica una operación push de TCP, entonces el indicador PUSH se establece en 1. El TCP receptor DEBE responder a este indicador entregando rápidamente datos a la aplicación tan pronto como el remitente desee reenviarlos.

La bandera URGENTE, si se establece en 1, implica una transferencia de datos urgente, y el puntero correspondiente debe apuntar al último octeto de los datos urgentes. Un uso típico de los datos urgentes es enviar señales desde el terminal para cancelar o abortar.

Los datos urgentes a menudo se denominan información fuera de banda(fuera de banda). Sin embargo, este término es inexacto. Los datos urgentes se envían en un flujo TCP regular, aunque las implementaciones individuales pueden tener mecanismos especiales para indicar a una aplicación que han llegado datos urgentes, y la aplicación debe examinar el contenido de los datos urgentes antes de que lleguen todos los bytes del mensaje.

El indicador RESET se establece en 1 cuando se debe cancelar una conexión. El mismo indicador se establece en la respuesta cuando se recibe un segmento que no está asociado con ninguna de las conexiones TCP actuales.

El indicador FIN se establece en 1 para los mensajes de cierre de conexión.


10.8.6 Suma de verificación

La suma de verificación de IP es solo para el encabezado de IP, mientras que la suma de verificación de TCP se calcula para todo el segmento, así como para el pseudoencabezado generado a partir del encabezado de IP. Durante el cálculo de la suma de verificación TCP, el campo correspondiente se establece en 0. En la fig. La figura 10-15 muestra un pseudoencabezado muy similar al que se usa en la suma de verificación UDP.


Arroz. 10.15. Campo de pseudoencabezado incluido en la suma de comprobación de TCP

La longitud de TCP se calcula sumando la longitud del encabezado TCP a la longitud de los datos. La suma de comprobación de TCP es obligatorio, no como en UDP. El receptor calcula primero la suma de verificación del segmento entrante y luego la compara con el contenido del campo de suma de verificación del encabezado TCP. Si los valores no coinciden, el segmento se descarta.

10.9 Ejemplo de segmento TCP

Arroz. 10.16, protocolo del analizador Oledor por Network General, es una secuencia de segmentos TCP. Los tres primeros segmentos establecen la conexión entre el cliente y el servidor. telnet. El último segmento lleva 12 bytes de datos.


Arroz. 10.16. Visualización de encabezado TCP por Sniffer Parser

Analizador Oledor traduce la mayoría de los valores a decimal. Sin embargo, los valores de las banderas se emiten como hexadecimales. El indicador con valor 12 es 010010. La suma de comprobación también se emite en formato hexadecimal.

10.10 Soporte para operación de sesión

10.10.1 Sondeo de ventana

Un remitente rápido y un receptor lento pueden formar una ventana de recepción de 0 bytes. Este resultado se llama cierre de ventana(Cerrar ventana). Cuando hay espacio libre para actualizar el tamaño de la ventana de recepción, se utiliza ACK. Sin embargo, si se pierde dicho mensaje, ambas partes tendrán que esperar indefinidamente.

Para evitar esta situación, el remitente establece guardar temporizador(temporizador persistente) al cerrar una ventana premium. El valor del temporizador es el tiempo de espera de retransmisión. Al final del temporizador, se envía un segmento al socio ventana de detección(sonda de ventana; algunas implementaciones incluyen datos). La sonda hace que el par envíe un ACK que informa el estado actual de la ventana.

Si la ventana sigue siendo de tamaño cero, el valor del temporizador persistente se duplica. Este proceso se repite hasta que el valor del temporizador alcanza un máximo de 60 s. TCP seguirá enviando mensajes de sondeo cada 60 segundos hasta que se abra una ventana, hasta que el usuario finalice el proceso o hasta que se agote el tiempo de espera de la aplicación.

10.11 Terminar una sesión

10.11.1 Tiempo de espera

El socio de conexión puede bloquearse o interrumpirse por completo debido a una falla en la puerta de enlace o en el enlace. Para evitar la retransmisión de datos en TCP, existen varios mecanismos.

Al alcanzar el umbral de la primera retransmisión (retransmisión), TCP le dice a IP que busque el enrutador fallido y al mismo tiempo informa a la aplicación del problema. TCP continúa enviando datos hasta que se alcanza el segundo valor límite y solo entonces cierra la conexión.

Por supuesto, antes de que esto suceda, puede haber un mensaje ICMP que indique que el destino es inalcanzable por algún motivo. En algunas implementaciones, incluso después de esto, TCP continuará intentando acceder al destino hasta que expire el intervalo de tiempo de espera (momento en el cual el problema puede solucionarse). A continuación, se informa a la aplicación de que el destino es inalcanzable.

Una aplicación puede establecer su propio tiempo de espera de entrega y realizar sus propias operaciones cuando vence este intervalo. Por lo general, la conexión se termina.

10.11.2 Mantener una conexión

Cuando una conexión inconclusa tiene datos para enviar durante mucho tiempo, obtiene el estado inactivo. Durante un período de inactividad, puede ocurrir un bloqueo de la red o una falla del enlace físico. Tan pronto como la red vuelva a estar operativa, los socios continuarán intercambiando datos sin interrumpir la sesión de comunicación. Esta estrategia cumplió con los requisitos del Ministerio de Defensa.

Sin embargo, cualquier conexión, activa o inactiva, ocupa mucha memoria de la computadora. Algunos administradores necesitan devolver los recursos no utilizados a los sistemas. Por lo tanto, muchas implementaciones de TCP son capaces de enviar un mensaje sobre mantener una conexión(keep-alive) que prueba las conexiones inactivas. Dichos mensajes se envían periódicamente al socio para verificar su existencia en la red. La respuesta debe ser un mensaje ACK. El uso de mensajes keep-alive es opcional. Si el sistema tiene esta capacidad, la aplicación puede anularla por sus propios medios. Período estimado defecto porque el tiempo de espera de mantenimiento de la conexión es de dos horas completas.

Recuerde que la aplicación puede configurar su propio temporizador, según el cual, en su nivel, decidirá sobre la terminación de la conexión.

10.12 Actuación

¿Qué tan eficiente es TCP? El rendimiento de los recursos se ve afectado por muchos factores, siendo los principales la memoria y el ancho de banda (consulte la figura 10.17).


Arroz. 10.17. Factores de rendimiento de TCP

El ancho de banda y los retrasos en la red física en uso limitan severamente el rendimiento. La mala calidad de la transferencia de datos da como resultado un gran volumen de datagramas descartados, lo que provoca retransmisiones y, en consecuencia, reduce la eficiencia del ancho de banda.

El lado receptor debe proporcionar suficiente espacio de búfer para permitir que el remitente transfiera datos sin pausas en la operación. Esto es especialmente importante para redes con alta latencia, donde hay mucho tiempo entre el envío de datos y la recepción de ACK (y también cuando se negocia el tamaño de la ventana). Para mantener un flujo constante de datos desde la fuente, el lado receptor debe tener una ventana no menor que el producto del ancho de banda y la demora.

Por ejemplo, si la fuente puede enviar datos a una velocidad de 10 000 bytes/s y tarda 2 segundos en devolver un ACK, entonces la ventana de recepción del otro lado debe tener un tamaño de al menos 20 000 bytes, de lo contrario, el flujo de datos no ser continuo. Un búfer de recepción de 10.000 bytes reducirá el rendimiento a la mitad.

Otro factor importante para el rendimiento es la capacidad del anfitrión para responder a eventos de alta prioridad y ejecutar rápidamente cambio de contexto, es decir. completar una operación y cambiar a otra. El host puede admitir de forma interactiva múltiples usuarios locales, procesos en segundo plano por lotes y docenas de conexiones de comunicación simultáneas. El cambio de contexto le permite atender todas estas operaciones, ocultando la carga en el sistema. Las implementaciones que integran TCP/IP con el kernel del sistema operativo pueden reducir significativamente la carga del uso del cambio de contexto.

Los recursos de CPU de la computadora son necesarios para las operaciones de procesamiento de encabezado TCP. Si el procesador no puede calcular rápidamente las sumas de verificación, esto conduce a una disminución en la velocidad de transferencia de datos a través de la red.

Además, los desarrolladores deben buscar simplificar la configuración de los parámetros de TCP para que un administrador de red pueda personalizarlos para adaptarlos a sus requisitos locales. Por ejemplo, la capacidad de ajustar el tamaño del búfer para el ancho de banda y la latencia de la red mejorará en gran medida el rendimiento. Desafortunadamente, muchas implementaciones no prestan suficiente atención a este problema y codifican los parámetros de comunicación.

Supongamos que el entorno de red es perfecto: hay suficientes recursos y el cambio de contexto es más rápido que los vaqueros que sacan sus armas. ¿Se obtendrá un rendimiento excelente?

No siempre. La calidad del desarrollo del software TCP también es importante. A lo largo de los años, se han diagnosticado y resuelto muchos problemas de rendimiento en varias implementaciones de TCP. Se puede considerar que el mejor software será el que cumpla con RFC 1122, que define los requisitos para la capa de comunicación de los hosts de Internet.

Una excepción igualmente importante y la aplicación de los algoritmos de Jacobson, Kern y Partridge (estos interesantes algoritmos se discutirán más adelante).

Los desarrolladores de software pueden obtener importantes beneficios mediante la creación de programas que eliminen las transferencias de datos pequeños e innecesarios y tengan temporizadores incorporados para liberar recursos de red que no están actualmente en uso.

10.13 Algoritmos para mejorar el rendimiento

Pasando a una introducción a la parte bastante compleja de TCP, veremos los mecanismos para mejorar el rendimiento y lidiar con las degradaciones del rendimiento. En esta sección se tratan los siguientes temas:

comienzo lento(inicio lento) evita que se utilice una gran cantidad de tráfico de red para una nueva sesión, lo que puede generar una sobrecarga.

■ Curación de Síndrome de la ventana desorientada(síndrome de la ventana tonta) evita que las aplicaciones mal diseñadas inunden la red con mensajes.

ACK retrasado(ACK retrasado) reduce la congestión al reducir la cantidad de mensajes de reconocimiento de transferencia de datos independientes.

Tiempo de espera de retransmisión calculado(cómputo del tiempo de espera de retransmisión) se basa en la negociación de sesiones en tiempo real, lo que reduce las retransmisiones innecesarias y no causa grandes retrasos en los intercambios de datos realmente necesarios.

■ El reenvío TCP se detiene cuando sobrecargas en la red permite que los enrutadores regresen a su modo original y compartan recursos de red para todas las sesiones.

■ Envío ACK duplicados(ACK duplicado) al recibir un segmento fuera de secuencia, permite a los pares retransmitir antes de que se agote el tiempo de espera.

10.13.1 Arranque lento

Si en casa se encienden todos los electrodomésticos a la vez, la red eléctrica se sobrecargará. En redes informáticas comienzo lento evita que se fundan los fusibles de red.

Una nueva conexión que instantáneamente comienza a enviar una gran cantidad de datos en una red que ya está ocupada puede generar problemas. La idea de un inicio lento es garantizar que la nueva conexión se inicie correctamente con un aumento lento en la tasa de transferencia de datos de acuerdo con la carga real de la red. El remitente está limitado por el tamaño de la ventana de carga, no por la ventana de recepción más grande.

ventana de carga(ventana de congestión) comienza con un tamaño de 1 segmento. Para cada segmento con un ACK recibido con éxito, el tamaño de la ventana de carga aumenta en 1 segmento, siempre que sea más pequeño que la ventana de recepción. Si la red no está congestionada, la ventana de carga alcanzará gradualmente el tamaño de la ventana de recepción. En un estado de reenvío normal, estas ventanas tendrán el mismo tamaño.

Tenga en cuenta que un comienzo lento no es tan lento. Después del primer ACK, el tamaño de la ventana de carga es de 2 segmentos, y después de un ACK exitoso de dos segmentos, el tamaño puede aumentar a 8 segmentos. En otras palabras, el tamaño de la ventana aumenta exponencialmente.

Supongamos que en lugar de recibir un ACK, se ha producido una situación de tiempo de espera. El comportamiento de la ventana de carga en este caso se analiza a continuación.

10.13.2 Síndrome de la ventana desorientada

En las primeras implementaciones de TCP/IP, los desarrolladores se encontraron con el fenómeno Síndrome de la ventana desorientada(Síndrome de la ventana tonta - SWS), que se manifestaba con bastante frecuencia. Para comprender lo que está sucediendo, considere el siguiente escenario, que conduce a consecuencias indeseables, pero es muy posible:

1. La aplicación de envío envía datos rápidamente.

2. La aplicación receptora lee 1 byte de datos del búfer de entrada (es decir, lentamente).

3. El búfer de entrada se llena rápidamente después de la lectura.

4. La aplicación receptora lee 1 byte y el TCP envía un ACK que significa "Tengo espacio libre para 1 byte de datos".

5. La aplicación transmisora ​​envía un paquete TCP de 1 byte a través de la red.

6. El TCP receptor envía un ACK que significa "Gracias. Recibí el paquete y no tengo más espacio libre".

7. La aplicación receptora vuelve a leer 1 byte y envía un ACK, y se repite todo el proceso.

Una aplicación de recepción lenta espera mucho tiempo a que lleguen los datos y empuja constantemente la información recibida hacia el borde izquierdo de la ventana, realizando una operación completamente inútil que genera tráfico adicional en la red.

Las situaciones reales, por supuesto, no son tan extremas. Un emisor rápido y un receptor lento intercambiarán pequeños fragmentos de datos (en relación con el tamaño máximo del segmento) y alternarán una ventana de recepción casi completa. En la fig. 10.18 muestra las condiciones para la aparición del síndrome de la "ventana estúpida".


Arroz. 10.18. Recibir búfer de ventana con muy poco espacio libre

Resolver este problema es fácil. Tan pronto como la ventana de recepción se reduce en una longitud menor que el tamaño de destino dado, TCP comienza a engañar al remitente. En esta situación, TCP no debe apuntar al remitente a adicional espacio en la ventana cuando la aplicación receptora lee datos del búfer en pequeños fragmentos. En cambio, los recursos liberados deben mantenerse en secreto para el remitente hasta que haya suficientes. Se recomienda un tamaño de segmento único, a menos que todo el búfer de entrada almacene un solo segmento (en este último caso, se utiliza un tamaño igual a la mitad del búfer). El tamaño de destino que debe informar TCP se puede expresar como:

mínimo (1/2 búfer de entrada, tamaño máximo de segmento)

TCP comienza a hacer trampa cuando el tamaño de la ventana es menor que este tamaño y dirá la verdad cuando el tamaño de la ventana no sea menor que el valor dado por la fórmula. Tenga en cuenta que no hay daño para el remitente, ya que la aplicación receptora aún no podría procesar gran parte de los datos que espera.

La solución propuesta es fácil de comprobar en el caso comentado anteriormente con la salida de ACK por cada uno de los bytes recibidos. El mismo método también es adecuado para el caso en que el búfer de entrada puede almacenar varios segmentos (como sucede a menudo en la práctica). El remitente rápido llenará el búfer de entrada, pero el receptor indicará que no tiene espacio libre para almacenar información y no abrirá este recurso hasta que su tamaño alcance todo el segmento.

10.13.3 Algoritmo de Nagle

El remitente debe, independientemente del destinatario, evitar el envío de segmentos muy cortos acumulando datos antes del envío. El algoritmo de Nagle implementa una idea muy simple para reducir la cantidad de datagramas cortos enviados a través de la red.

El algoritmo recomienda retrasar la transferencia de datos (y hacer estallar) mientras espera un ACK de los datos transmitidos anteriormente. Los datos acumulados se envían después de recibir un ACK a una información enviada previamente, o después de recibir para enviar datos en el tamaño de un segmento completo, o al completar un tiempo de espera. Este algoritmo no debe usarse para aplicaciones en tiempo real que necesitan enviar datos lo más rápido posible.

10.13.4 ACK retrasado

Otro mecanismo de mejora del rendimiento es la forma en que se retrasa el ACK. Reducir la cantidad de ACK reduce la cantidad de ancho de banda que se puede usar para enviar otro tráfico. Si el socio TCP retrasa un poco el envío del ACK, entonces:

■ Se pueden reconocer múltiples segmentos con un solo ACK.

■ La aplicación receptora puede recibir cierta cantidad de datos dentro del intervalo de tiempo de espera, es decir. el encabezado de salida puede incluirse en el ACK y no es necesario generar ningún mensaje por separado.

Para evitar retrasos al reenviar un flujo de segmentos completos (por ejemplo, al intercambiar archivos), se debe enviar un ACK al menos cada segundo segmento completo.

Muchas implementaciones utilizan un tiempo de espera de 200 ms. Pero un ACK retrasado no reduce el tipo de cambio. Cuando llega un segmento corto, todavía hay suficiente espacio libre en el búfer de entrada para recibir nuevos datos y el remitente puede continuar con la transferencia (además, la retransmisión suele ser mucho más lenta). Si llega un segmento completo, debe responderlo con un mensaje ACK en el mismo segundo.

10.13.5 Tiempo de espera de retransmisión

Después de enviar el segmento, TCP establece un temporizador y supervisa la llegada de un ACK. Si no se recibe un ACK dentro del período de tiempo de espera, TCP retransmite el segmento (retransmisión). Sin embargo, ¿cuál debería ser el período de tiempo de espera?

Si es demasiado corto, el remitente inundará la red con segmentos innecesarios que duplican la información ya enviada. Un tiempo de espera demasiado largo evitará que los segmentos que realmente se dañan durante la transferencia se reparen rápidamente, lo que reducirá el rendimiento.

¿Cómo elegir el intervalo correcto para el tiempo de espera? Un valor adecuado para una LAN de alta velocidad no lo será para una conexión remota con muchos accesos. Por lo tanto, el principio de "un valor para cualquier condición" es claramente inadecuado. Además, incluso para una conexión específica existente, las condiciones de la red pueden cambiar y los retrasos pueden aumentar o disminuir.

Algoritmos de Jacobson, Kern y Partridge (descritos en artículos , Van Jacobson y Mejora de las estimaciones de tiempo de ida y vuelta en protocolos de transporte fiables, Karn y Partridge) permiten que TCP se adapte a las condiciones cambiantes de la red. Estos algoritmos se recomiendan para su uso en nuevas implementaciones. Los revisaremos brevemente a continuación.

El sentido común dicta que la mejor base para estimar el tiempo de espera correcto para una conexión en particular podría ser rastrear Tiempo del ciclo(tiempo de ida y vuelta) como el intervalo entre el envío de datos y la recepción de la confirmación de su recepción.

Se pueden obtener buenas soluciones para los siguientes valores en base a estadísticas elementales (consulte la Figura 10.19) que ayudarán a calcular el tiempo de espera. Sin embargo, no confíe en los promedios, ya que más de la mitad de los puntajes serán mayores que el promedio estadístico. Al considerar un par de varianzas, se pueden obtener mejores estimaciones que tengan en cuenta la distribución normal y reduzcan la latencia de retransmisión demasiado larga.


Arroz. 10.19. Distribución de tiempos de ciclo

No hay necesidad de una gran cantidad de cálculos para obtener estimaciones matemáticas formales de las desviaciones. Puede usar estimaciones bastante aproximadas basadas en el valor absoluto de la diferencia entre el último valor y la estimación promedio:

Última desviación = | Último Ciclo - Promedio |

Para calcular el valor de tiempo de espera correcto, otro factor a considerar es el cambio en el tiempo de ciclo debido a las condiciones actuales de la red. Lo que sucedió en línea en el último minuto es más importante que lo que sucedió hace una hora.

Suponga que está calculando el promedio del ciclo para una sesión muy larga. Supongamos que al principio la red estaba ligeramente cargada y determinamos 1000 valores pequeños, pero luego hubo un aumento en el tráfico con un aumento significativo en el tiempo de demora.

Por ejemplo, si 1000 valores dieron un valor promedio de 170 unidades, pero luego se midieron 50 valores con un promedio de 282, entonces el promedio actual sería:

170x1000/1050 + 282x50/1050 = 175

Más razonable sería tiempo de ciclo suavizado(Smoothed Round-Trip Time - SRTT), que tiene en cuenta la prioridad de los valores posteriores:

Nuevo SRTT = (1 – α)×(antiguo SRTT) + α×Valor del último ciclo

El valor de α está entre 0 y 1. aumentar un da como resultado una mayor influencia del tiempo de ciclo actual en el promedio suavizado. Debido a que las computadoras pueden dividir rápidamente por potencias de 2 desplazando los números binarios a la derecha, el valor de α siempre es (1/2) n (normalmente 1/8), por lo que:

SRTT nuevo = 7/8 × SRTT anterior + 1/8 × Tiempo del último ciclo

La Tabla 10.2 muestra cómo la fórmula para SRTT se ajusta al valor actual de SRTT de 230 unidades cuando un cambio en las condiciones de la red da como resultado un aumento secuencial en el tiempo del ciclo (suponiendo que no se agote el tiempo). Los valores de la columna 3 se utilizan como los valores de la columna 1 para la siguiente fila de la tabla (es decir, el antiguo SRTT).


Tabla 10.2 Cálculo del tiempo de ciclo suavizado

Antiguo SRTT RTT más reciente (7/8)×(antiguo SRTT) + (1/8)×(RTT)
230.00 294 238.00
238.00 264 241.25
241.25 340 253.59
253.59 246 252.64
252.64 201 246.19
246.19 340 257.92
257.92 272 259.68
259.68 311 266.10
266.10 282 268.09
268.09 246 265.33
265.33 304 270.16
270.16 308 274.89
274.89 230 269.28
269.28 328 276.62
276.62 266 275.29
275.29 257 273.00
273.00 305 277.00

Ahora surge la cuestión de elegir un valor para el tiempo de espera de retransmisión. Un análisis de los tiempos de ciclo muestra una desviación significativa de estos valores del promedio actual. Tiene sentido establecer un límite para la magnitud de las desviaciones (desviaciones). Los buenos valores para el tiempo de espera de retransmisión (llamado Retransmission TimeOut - RTO en los estándares RFC) vienen dados por la siguiente fórmula con una varianza suavizada restringida (SDEV):

T = Tiempo de espera de retransmisión = SRTT + 2×SDEV

T = SRTT + 4×SDEV

Para calcular SDEV, primero determine el valor absoluto de la desviación actual:

DEV = | Tiempo del último ciclo: antiguo SRTT |

Luego se usa una fórmula de suavizado para tener en cuenta el último valor:

SDEV nuevo = 3/4×SDEV antiguo + 1/4×DEV

Queda una pregunta: ¿qué valores iniciales tomar? Recomendado:

Tiempo de espera inicial = 3 s

SRTT inicial = 0

SDEV inicial = 1,5 s

Van Jacobson ha definido un algoritmo rápido que calcula el tiempo de espera de retransmisión de manera muy eficiente.

10.13.6 Ejemplo de estadísticas

¿Qué tan bien funcionará el tiempo de espera calculado anteriormente? Al implementar el valor obtenido, se observaron mejoras significativas en el rendimiento. Un ejemplo serían las estadísticas de comandos. netstat recibido en el sistema Tigre- un servidor de Internet al que acceden muchos hosts de todo el mundo.


1510769 paquetes (314955304 bytes) recibidos en secuencia

sistema Tigre se retransmitieron menos del 2,5 % de los segmentos de datos TCP. Para un millón y medio de segmentos de datos entrantes (el resto son ACK puros), solo se duplicó el 0,6 %. En este caso, se debe tener en cuenta que el nivel de pérdidas en los datos de entrada corresponde aproximadamente al nivel de los segmentos de salida. Así, el tráfico de retransmisión inútil es aproximadamente el 0,6% del tráfico total.

10.13.7 Cálculos después de volver a enviar

Las fórmulas anteriores utilizan el valor del tiempo de ciclo como el intervalo entre el envío de un segmento y la recepción de un acuse de recibo. Sin embargo, suponga que no se recibe ningún reconocimiento durante el período de tiempo de espera y los datos deben volver a enviarse.

El algoritmo de Kern supone que, en este caso, no se debe cambiar el tiempo de ciclo. El valor suavizado actual del tiempo de ciclo y desviación suavizada conservan sus valores hasta que se recibe un acuse de recibo para enviar algún segmento sin reenviarlo. A partir de este momento se reanudan los cálculos en base a los valores almacenados y nuevas medidas.

10.13.8 Acciones después de la retransmisión

Pero, ¿qué sucede antes de que se reciba la confirmación? Después de una retransmisión, el comportamiento de TCP cambia drásticamente, principalmente debido a la pérdida de datos por la congestión de la red. Por tanto, la respuesta al reenvío de datos será:

■ Tasa de retransmisión reducida

■ Combatir la congestión de la red reduciendo el tráfico general

10.13.9 Frenado exponencial

Después de una retransmisión, el intervalo de tiempo de espera se duplica. Sin embargo, ¿qué sucede cuando el temporizador se desborda nuevamente? Los datos se volverán a enviar y el plazo de retransmisión se duplicará de nuevo. Este proceso se llama frenado exponencial(retroceso exponencial).

Si la falla de la red continúa, el período de tiempo de espera se duplicará hasta que alcance un valor máximo preestablecido (generalmente 1 minuto). Después del tiempo de espera, solo se puede enviar un segmento. El tiempo de espera también ocurre cuando se excede el valor preestablecido para el número de transferencias de datos sin recibir un ACK.

10.13.10 Reducción de la congestión al reducir los datos enviados a través de la red

Reducir la cantidad de datos enviados es algo más complicado que los mecanismos discutidos anteriormente. Comienza a funcionar, como el inicio lento ya mencionado. Pero, dado que se establece un límite para el nivel de tráfico, lo que inicialmente puede generar problemas, el tipo de cambio en realidad se ralentizará debido al aumento en el tamaño de la ventana de carga para un segmento. Debe establecer los valores de borde para una reducción real en la velocidad de envío. En primer lugar, se calcula el umbral de peligro:

Límite: 1/2 mínimo (ventana de carga actual, ventana de recepción del socio)

Si el valor resultante es más de dos segmentos, se utiliza como límite. De lo contrario, el tamaño del borde se establece en dos segmentos. El algoritmo de recuperación completo requiere:

■ Establezca el tamaño de la ventana de carga en un segmento.

■ Por cada ACK recibido, aumente el tamaño de la ventana de carga en un segmento hasta que se alcance el límite (muy parecido al mecanismo de inicio lento).

■ A partir de entonces, con cada ACK recibido, agregue un valor más pequeño a la ventana de carga, que se elige en función de la tasa de aumento por segmento para el tiempo de ciclo (el aumento se calcula como MSS/N, donde N es el tamaño de la carga). ventana en segmentos).

El escenario para el caso ideal puede ser una representación simplista de cómo funciona el mecanismo de recuperación. Suponga que la ventana de recepción del par (y la ventana de carga actual) era de 8 segmentos antes de que se detectara el tiempo de espera, y el límite se define en 4 segmentos. Si la aplicación receptora lee instantáneamente datos del búfer, el tamaño de la ventana de recepción permanecerá en 8 segmentos.

■ Se envía 1 segmento (ventana de carga = 1 segmento).

■ ACK recibido: se envían 2 segmentos.

■ ACK recibido para 2 segmentos: se envían 4 segmentos (límite alcanzado).

■ ACK recibido para 4 segmentos. Se envían 5 segmentos.

■ ACK recibido para 5 segmentos. Se envían 6 segmentos.

■ ACK recibido para 6 segmentos. Se envían 7 segmentos.

■ ACK recibido para 7 segmentos. Se envían 8 segmentos (la ventana de carga vuelve a tener el mismo tamaño que la ventana de recepción).

Debido a que todos los datos enviados deben reconocerse durante el tiempo de espera de retransmisión, el proceso continúa hasta que la ventana de carga alcanza el tamaño de la ventana de recepción. Los eventos que ocurren se muestran en la fig. 10.20. El tamaño de la ventana aumenta exponencialmente, duplicándose durante el período de inicio lento y, una vez que se alcanza el límite, el aumento es lineal.


Arroz. 10.20. Límite de velocidad de reenvío durante la congestión

10.13.11 ACK duplicados

En algunas implementaciones, se usa una función opcional, la llamada reenvío rápido(retransmisión rápida) - para acelerar la retransmisión de datos bajo ciertas condiciones. Su idea principal está relacionada con que el destinatario envíe ACK adicionales que indiquen una brecha en los datos recibidos.

Al recibir un segmento fuera de servicio, el receptor devuelve un ACK que apunta al primer byte. perdió datos (ver Figura 10.21).


Arroz. 21.10. ACK duplicados

El remitente no realiza una retransmisión instantánea de datos porque IP normalmente puede entregar datos al destinatario sin una secuencia de envío. Pero cuando se reciben varios ACK adicionales para la duplicación de datos (por ejemplo, tres), el segmento faltante se enviará sin esperar a que se complete el tiempo de espera.

Tenga en cuenta que cada ACK duplicado indica la recepción de un segmento de datos. Varios ACK duplicados dejan en claro que la red es capaz de entregar suficientes datos y, por lo tanto, no está demasiado cargada. Como parte del algoritmo general, se realiza una pequeña reducción en el tamaño de la ventana de carga con un aumento real en el tráfico de red. En este caso, no se aplica el proceso de cambio de tamaño drástico al restaurar la obra.

Según la norma Requisitos del anfitrión(requisitos del host) TCP debe realizar el mismo inicio lento que se describe anteriormente cuando se apaga la fuente. Sin embargo, informar esto no es específico ni eficiente, ya que es posible que la conexión que recibió el mensaje no genere demasiado tráfico. Especificación actual Requisitos del enrutador(requisitos del enrutador) especifica que los enrutadores no debe enviar mensajes de supresión de fuente.

10.13.13 Estadísticas TCP

Finalmente, echemos un vistazo a los mensajes de estadísticas del comando. netstat, para ver muchos de los mecanismos descritos anteriormente en acción.

Los segmentos se denominan paquetes.
879137 paquetes de datos (226966295 bytes)
21815 paquetes de datos (8100927 bytes) retransmitidos
Reenvío.
132957 paquetes de solo reconocimiento (104216 retrasados)
Tenga en cuenta el gran número

ACK retrasados.

Sonido de apertura de ventana

tamaño cero.

Estos son mensajes SYN y FIN.
762469 acuses de recibo (para 226904227 bytes)
señal de llegada de paquetes

fuera de secuencia.

1510769 paquetes (314955304 bytes)
9006 paquetes completamente duplicados (867042 bytes)
El resultado de un tiempo de espera con un real

entrega de datos.

74 paquetes con algunos dup. datos (12193 bytes duplicados)
Para ser más eficiente

algunos datos se volvieron a empaquetar para incluir bytes adicionales cuando se reenvían.

13452 paquetes desordenados (2515087 bytes)
530 paquetes (8551 bytes) de datos después de la ventana
Quizás este dato fue

incluidos en los mensajes sonoros.

402 paquetes recibidos después del cierre
Estas son repeticiones posteriores.

enviando.

108 descartado por malas sumas de verificación
Suma de comprobación de TCP no válida.
0 descartado para campos de compensación de encabezado incorrectos
7 descartados porque el paquete es demasiado corto
14677 conexiones establecidas (incluyendo aceptaciones)
18929 conexiones cerradas (incluidas 643 caídas)
4100 conexiones embrionarias caídas
572187 segmentos actualizados rtt (de 587397 intentos)
Intentos de cambio fallidos

tiempo de ciclo, porque el ACK no llegó antes de que expirara el tiempo de espera,

26 conexiones caídas por tiempo de espera de rexmit
Intentos fallidos posteriores

reenviar, lo que indica una conexión perdida.

Tiempos de espera de sondeo

ventana cero

Comprobar tiempos de espera

conexión inactiva.

472 conexiones caídas por keepalive

10.14 Cumplimiento de los requisitos del desarrollador

El estándar TCP actual requiere que las implementaciones se adhieran estrictamente al procedimiento de inicio lento al inicializar una conexión y usen los algoritmos de Kern y Jacobson para estimar el tiempo de espera de reenvío y controlar la carga. Las pruebas han demostrado que estos mecanismos conducen a mejoras significativas en el rendimiento.

¿Qué sucede cuando instala un sistema que no se adhiere estrictamente a estos estándares? No proporcionará un rendimiento adecuado para sus propios usuarios y será un mal vecino para otros sistemas en la red, lo que impedirá que se restablezca el funcionamiento normal después de una sobrecarga temporal y generará un tráfico excesivo que provocará la caída de datagramas.

10.15 Barreras al desempeño

TCP ha demostrado su flexibilidad al operar en redes con velocidades de transmisión de cientos o millones de bits por segundo. Este protocolo ha logrado buenos resultados en redes de área local modernas con topologías Ethernet, Token-Ring y Fiber Distributed Data Interface (FDDI), así como para enlaces de baja velocidad o conexiones de larga distancia (como enlaces satelitales).

TCP está diseñado para responder a condiciones extremas, como la congestión de la red. Sin embargo, la versión actual del protocolo tiene características que limitan el rendimiento en tecnologías emergentes que ofrecen cientos y miles de megabytes de ancho de banda. Para comprender los problemas que surgen, considere un ejemplo simple (aunque poco realista).

Supongamos que cuando mueve un archivo entre dos sistemas, desea intercambiar un flujo continuo de la manera más eficiente posible. Supongamos que:

■ El tamaño máximo del segmento de destino es de 1 KB.

■ Ventana de recepción - 4 KB.

El ancho de banda le permite enviar dos segmentos por 1 s.

■ La aplicación receptora consume datos a medida que llegan.

■ Los mensajes ACK llegan después de 2 segundos.

El remitente es capaz de enviar datos continuamente. Después de todo, cuando el volumen asignado para la ventana está lleno, llega un ACK que permite enviar otro segmento:

Después de 2 s:

RECIBE ACK DEL SEGMENTO 1, PUEDE ENVIAR EL SEGMENTO 5.
RECIBE ACK DEL SEGMENTO 2, PUEDE ENVIAR EL SEGMENTO 6.
RECIBE ACK DEL SEGMENTO 3, PUEDE ENVIAR EL SEGMENTO 7.
RECIBE ACUSE DE SEGMENTO 4, PUEDE ENVIAR SEGMENTO 8.

Después de 2 s más:

RECIBE ACK DEL SEGMENTO 5, PUEDE ENVIAR EL SEGMENTO 9.

Si la ventana de recepción fuera solo de 2K, el remitente tendría que esperar un segundo de cada dos antes de enviar los siguientes datos. De hecho, para mantener un flujo continuo de datos, la ventana de recepción debe ser al menos:

Ventana = Ancho de banda × Tiempo de ciclo

Aunque el ejemplo es algo exagerado (para proporcionar números más simples), una ventana pequeña puede generar problemas con conexiones satelitales de alta latencia.

Ahora veamos qué sucede con las conexiones de alta velocidad. Por ejemplo, si el ancho de banda y la tasa de transferencia se miden a 10 Mbps, pero el tiempo de ciclo es de 100 ms (1/10 de segundo), entonces para un flujo continuo, la ventana de recepción debe almacenar al menos 1 000 000 de bits, es decir, . 125.000 bytes. Pero el número más grande que se puede escribir en el campo de encabezado de una ventana de recepción de TCP es 65.536.

Otro problema surge a velocidades de transmisión altas, porque los números de secuencia se agotan muy rápidamente. Si la conexión puede enviar datos a una velocidad de 4 GB/s, los números de secuencia deben actualizarse cada segundo. No habrá forma de distinguir entre datagramas duplicados antiguos que se retrasaron más de un segundo mientras viajaban por Internet y datos nuevos y frescos.

Se están realizando nuevas investigaciones para mejorar TCP/IP y eliminar los obstáculos mencionados anteriormente.

10.16 Funciones TCP

Este capítulo cubre las muchas características de TCP. Los principales se enumeran a continuación:

■ Asociación de puertos con conexiones

■ Inicialización de conexiones mediante confirmación en tres pasos

■ Realizar un inicio lento para evitar la congestión de la red

■ Segmentación de datos en tránsito

■ Numeración de datos

■ Manejo de segmentos duplicados entrantes

■ Cálculo de la suma de comprobación

■ Regulación del flujo de datos a través de la ventana de recepción y la ventana de envío

■ Terminar la conexión de la manera prescrita

■ Terminar la conexión

■ Reenvío de datos urgentes

■ Confirmación de reenvío positivo

■ Cálculo del tiempo de espera de retransmisión

■ Reducción del tráfico inverso durante la congestión de la red

■ Señalización de segmentos fuera de servicio

■ Sondeo del cierre de la ventana receptora

10.17 Estados TCP

Una conexión TCP pasa por varias etapas: se establece una conexión a través de un intercambio de mensajes, luego se envían datos y luego se cierra la conexión mediante un intercambio de mensajes especiales. Cada paso en el funcionamiento de la conexión corresponde a un cierto condición esta conexión. El software TCP en cada extremo de la conexión monitorea constantemente el estado actual del otro lado de la conexión.

A continuación, consideraremos brevemente un cambio típico en el estado de un servidor y un cliente ubicados en diferentes extremos de la conexión. No pretendemos dar una descripción exhaustiva de todos los estados posibles al transferir datos. Se da en RFC 793 y documento Requisitos del anfitrión.

Durante el establecimiento de conexiones, el servidor y el cliente pasan por secuencias de estados similares. Los estados del servidor se muestran en la Tabla 10.3 y los estados del cliente se muestran en la Tabla 10.4.


Tabla 10.3 Secuencia de estado del servidor

El estado del servidor Evento Descripción
CERRADO El estado ficticio antes de iniciar la configuración de la conexión.
Apertura pasiva por aplicación de servidor.
ESCUCHAR (seguimiento) El servidor está esperando una conexión del cliente.
El servidor TCP recibe el SYN y envía el SYN/ACK. El servidor recibió un SYN y envió un SYN/ACK. Va a esperar ACK.
SYN RECIBIDO El servidor TCP recibe un ACK.
ESTABLECIDO (instalado) ACK recibido, conexión abierta.

Tabla 10.4 Secuencia de estado del cliente

Si los pares intentaran establecer una conexión entre ellos al mismo tiempo (lo cual es extremadamente raro), cada uno pasaría por los estados CERRADO, SYN-SENT, SYN-RECEIVED y ESTABLECIDO.

Las partes finales de la conexión permanecen en el estado ESTABLECIDO hasta que una de las partes procede a clausura conexión mediante el envío de un segmento FIN. Durante un cierre normal, la parte que inicia ese cierre pasa por los estados que se muestran en la Tabla 10.5. Su pareja pasa por los estados que se muestran en la tabla 10.6.


Tabla 10.5 La secuencia de estados del lado que cierra la conexión.

Estados laterales de cierre Evento Descripción
ESTABLECIDO La aplicación local solicita que se cierre la conexión.
TCP envía FIN/ACK.
FIN-ESPERA-1 La fiesta de cierre espera la respuesta del socio. Recuerde que aún pueden llegar nuevos datos del socio.
TCP recibe un ACK.
FIN-ESPERA-2 La parte de cierre ha recibido un ACK del par, pero aún no ha recibido un FIN. El lado de cierre espera FIN mientras acepta los datos entrantes.
TCP recibe FIN/ACK.
Envía un ACK.
TIEMPO DE ESPERA La conexión se mantiene en un estado indeterminado para permitir la llegada o el descarte de los datos duplicados o el FIN duplicado aún existente en la red. El período de espera es el doble de la estimación de duración máxima del segmento.
CERRADO

Tabla 10.6 Secuencia de estado de socio cercano de conexión

Estado de socio Evento Descripción
ESTABLECIDO TCP recibe FIN/ACK.
CERRAR-ESPERAR FIN ha llegado.
TCP envía ACK.
TCP espera a que su aplicación cierre la conexión. En este punto, la aplicación puede enviar una cantidad de datos bastante grande.
La aplicación local inicia el cierre de la conexión.
TCP envía FIN/ACK.
ÚLTIMO ACK TCP está esperando un ACK final.
TCP recibe un ACK.
CERRADO Eliminada toda la información de conexión.

10.17.1 Análisis de estados de conexión TCP

Equipo netstat-an le permite comprobar el estado actual de la conexión. A continuación se muestran las conexiones en los estados escuchar, inicio, establecido, cierre y Tiempo de espera.

Tenga en cuenta que el número de puerto de conexión aparece al final de cada dirección local y externa. Puede ver que hay tráfico TCP para las colas de entrada y salida.

Pro Recv-Q Send-Q Dirección local Dirección extranjera (estado)
TCP 0 0 128.121.50.145.25 128.252.223.5.1526 SYN_RCVD
Tcp 0 0 128.121.50.145.25 148.79.160.65.3368 ESTABLECIDO
Tcp 0 0 127.0.0.1.1339 127.0.0.1.111 TIEMPO_ESPERA
Tcp 0 438 128.121.50.145.23 130.132.57.246.2219 ESTABLECIDO
Tcp 0 0 128.121.50.145.25 192.5.5.1.4022 TIEMPO_ESPERA
Tcp 0 0 128.121.50.145.25 141.218.1.100.3968 TIEMPO_ESPERA
Tcp 0 848 128.121.50.145.23 192.67.236.10.1050 ESTABLECIDO
Tcp 0 0 128.121.50.145.1082 128.121.50.141.6000 ESTABLECIDO
TCP 0 0 128.121.50.145.1022 128.121.50.141.1017 ESTABLECIDO
Tcp 0 0 128.121.50.145.514 128.121.50.141.1020 CERRAR_ESPERAR
Tcp 0 1152 128.121.50.145.119 192.67.239.23.3572 ESTABLECIDO
Tcp 0 0 128.121.50.145.1070 192.41.171.5.119 TIEMPO_ESPERA
Tcp 579 4096 128.121.50.145.119 204.143.19.30.1884 ESTABLECIDO
Tcp 0 0 128.121.50.145.119 192.67.243.13.3704 ESTABLECIDO
TCP 0 53 128.121.50.145.119 192.67.236.218.2018 FIN_WAIT_1
Tcp 0 0 128.121.50.145.119 192.67.239.14.1545 ESTABLECIDO

10.18 Notas de implementación

Desde el principio, el protocolo TCP ha sido diseñado para la interoperabilidad de equipos de red de diferentes fabricantes. La especificación TCP no especifica exactamente cómo deberían funcionar las estructuras internas de la implementación. Estas preguntas se dejan a los desarrolladores, quienes están llamados a encontrar los mejores mecanismos para cada implementación en particular.

Incluso RFC 1122 (documento Requisitos del anfitrión- requisitos del anfitrión) deja mucho espacio para la variación. Cada una de las funciones implementadas está marcada con un cierto nivel de compatibilidad:

■ MAYO (Permitido)

■ NO DEBE

Desafortunadamente, a veces hay productos que no implementan los requisitos MUST. Como resultado, los usuarios experimentan el inconveniente de un rendimiento reducido.

Algunas buenas prácticas de implementación no están cubiertas por los estándares. Por ejemplo, la seguridad se puede mejorar limitando el uso de puertos conocidos a procesos privilegiados en el sistema, si este método es compatible con el sistema operativo local. Para mejorar el rendimiento, las implementaciones deben hacer la menor copia y movimiento posible de los datos enviados o recuperados.

Interfaz de programación de aplicaciones estándar no determinado(así como la política de seguridad), por lo que existe un campo libre de actividad para experimentar con diferentes conjuntos de herramientas de software. Sin embargo, esto puede resultar en diferentes API en cada plataforma y evitar que el software de la aplicación se mueva entre plataformas.

De hecho, los desarrolladores basan sus juegos de herramientas en la API de Socket, tomada de Berkeley. La importancia de la interfaz de programación aumentó con la llegada de WINSock (Windows Socket), lo que condujo a una proliferación de nuevas aplicaciones de escritorio que podían ejecutarse sobre cualquier interfaz WINSock compatible con la pila TCP/IP.

10.19 Lectura adicional

El estándar TCP original se define en RFC 793. Las actualizaciones, las correcciones y los requisitos de compatibilidad se tratan en RFC 1122. Kern (Kash) y Partridge (Partridge) publicaron un artículo Mejora de las estimaciones de ida y vuelta en protocolos de transporte fiables en la revista Actas del ACM SIGCOMM 1987. artículo de jacobson Prevención y control de la congestión apareció en Actas del Taller ACM SIGCOMM 1988. Jacobson también publicó varios algoritmos de revisión de RFC para mejorar el rendimiento.


cerca