Guía Beej de programación en redes

Anterior


Siguiente


2. ¿Qué es un socket?

Continuamente oyes hablar de los "sockets", y tal vez te estás preguntando qué es lo que son exactamente. Bien, esto es lo que son: una forma de comunicarse con otros programas usando descriptores de fichero estándar de Unix.

¿Qué?

Vale--puede que hayas oído a algún hacker de Unix decir: "¡Hey, todo en Unix es un fichero!" A lo que esta persona se estaba refiriendo es al hecho de que cuando los programas de Unix hacen cualquier tipo de E/S, lo hacen escribiendo o leyendo un descriptor de fichero. Un descriptor de fichero no es más que un entero asociado a un archivo abierto. Pero (y aquí está el quid de la cuestión) ese fichero puede ser una conexión de red, una cola FIFO, un tubo [pipe], un terminal, un fichero real de disco, o cualquier otra cosa. ¡Todo en Unix es un fichero! Por eso, si quieres comunicarte con otro programa a través de Internet vas a tener que hacerlo con un descriptor de fichero, es mejor que lo creas.

"¿De dónde saco yo este descriptor de fichero para comunicar a través de la red, señor sabelotodo?" Esta es probablemente la última pregunta en la que piensas ahora, pero voy a contestarla de todas maneras: usas la llamada al sistema socket(). Te devuelve un descriptor de fichero y tú te comunicas con él usando las llamadas al sistema especializadas send() y recv() ( man send , man recv ).

"¡Pero, oye!" puede que exclames ahora. "Si es un descriptor de fichero, por qué, en el nombre de Neptuno, no puedo usar las llamadas normales read() y write() para comunicarme a través de un socket ." La respuesta corta es, "¡Sí que puedes!" La respuesta larga es, "Puedes usarlas, pero send() y write() te ofrecen mucho más control sobre la transmisión de datos."

¿Y ahora qué? Qué tal esto: hay muchos tipos de sockets. Existen las direcciones de Internet DARPA (sockets de internet), rutas sobre nodos locales (sockets de Unix), direcciones X.25 del CCITT ( sockets éstos de X.25 que puedes ignorar perfectamente) y probablemente muchos más en función de la modalidad de Unix que estés ejecutando. Este docuemento se ocupa únicamente de los primeros: los sockets de Internet.

2.1. Dos tipos de sockets de internet

¿Qué es esto? ¿Hay dos tipos de sockets de internet? Sí. Bueno no, estoy mintiendo. En realidad hay más pero no quería asustarte. Aquí sólo voy a hablar de dos tipos. A excepción de esta frase, en la que voy a mencionar que los sockets puros [Raw Sockets] son también muy potentes y quizás quieras buscarlos más adelante.

Muy bien. ¿Cuáles son estos dos tipos? El primer tipo de sockets lo definen los sockets de flujo [Stream sockets]; El otro, los sockets de datagramas [Datagram sockets], a los que en adelante me referiré, respectivamente como "SOCK_STREAM" y " SOCK_DGRAM ". En ocasiones, a los sockets de datagramas se les llama también "sockets sin conexión". (Aunque se puede usar connect() con ellos, si se quiere. Consulta connect() , más abajo.)

Los sockets de flujo definen flujos de comunicación en dos direcciones, fiables y con conexión. Si envías dos ítems a través del socket en el orden "1, 2" llegarán al otro extremo en el orden "1, 2", y llegarán sin errores. Cualquier error que encuentres es producto de tu extraviada mente, y no lo vamos a discutir aquí.

¿Qué aplicación tienen los sockets de flujo? Bueno, quizás has oído hablar del programa telnet. ¿Sí? telnet usa sockets de flujo. Todos los carácteres que tecleas tienen que llegar en el mismo orden en que tú los tecleas, ¿no? También los navegadores, que usan el protocolo HTTP , usan sockets de flujo para obtener las páginas. De hecho, si haces telnet a un sitio de la web sobre el puerto 80, y escribes " GET / ", recibirás como respuesta el código HTML.

¿Cómo consiguen los sockets de flujo este alto nivel de calidad en la transmisión de datos? Usan un protocolo llamado "Protocolo de Control de Transmisión", más conocido como "TCP" (consulta el RFC-793 para información extremadamente detallada acerca de TCP). TCP asegura que tu información llega secuencialmente y sin errores. Puede que hayas oído antes "TCP" como parte del acrónimo " TCP/IP ", donde "IP" significa "Protocolo de Internet" (consulta el RFC-791 .) IP se encarga básicamente del encaminamiento a través de Internet y en general no es responsable de la integridad de los datos.

Estupendo. ¿Qué hay de los sockets de datagramas? ¿Por qué se les llama sockets sin conexión? ¿De qué va esto, en definitiva, y por qué no son fiables? Bueno, estos son los hechos: si envías un datagrama, puede que llegue. Puede que llegue fuera de secuencia. Si llega, los datos que contiene el paquete no tendrán errores.

Los sockets de datagramas también usan IP para el encaminamiento, pero no usan TCP; usan el "Protocolo de Datagramas de Usuario" o "UDP" (consulta el RFC-768 .)

¿Por qué son sin conexión? Bueno, básicamente porque no tienes que mantener una conexión abierta como harías con los sockets de flujo. Simplemente montas un paquete, le metes una cabecera IP con la información de destino y lo envías. No se necesita conexión. Generalmente se usan para transferencias de información por paquetes. Aplicaciones que usan este tipo de sockets son, por ejemplo, tftp y bootp.

"¡Basta!" puede que grites. "¿Cómo pueden siquiera funcionar estos programas si los datagramas podrían llegar a perderse?". Bien, mi amigo humano, cada uno tiene su propio protocolo encima de UDP. Por ejemplo, el protocolo tftp establece que, para cada paquete enviado, el receptor tiene que devolver un paquete que diga, "¡Lo tengo!" (un paquete "ACK"). Si el emisor del paquete original no obtiene ninguna respuesta en, vamos a decir, cinco segundos, retransmitirá el paquete hasta que finalmente reciba un ACK . Este procedimiento de confirmaciones es muy importante si se implementan aplicaciones basadas en SOCK_DGRAM.

2.2. Tonterías de bajo nivel y teoría de redes

Puesto que acabo de mencionar la disposición en capas de los protocolos, es el momento de hablar acerca de como las redes funcionan realmente, y de mostrar algunos ejemplos de como se construyen los paquetes SOCK_DGRAM . Probablemente, en la práctica puedes saltarte esta sección. Sin embargo no está mal como culturilla.

Figura 1. Encapsulación de datos.

[Encapsulated Protocols Diagram]

¡Eh tíos, es hora de aprender algo sobre Encapsulación de datos ! Esto es muy, muy importante. Tan importante que podrías aprenderlo si te matricularas en el curso de redes aquí, en el estado de Chico ;-). Básicamente consiste en esto: un paquete de datos nace, el paquete se envuelve (se "encapsula") con una cabecera (y raramente con un pie) por el primer protocolo (por ejemplo el protocolo TFTP), entonces todo ello (cabecera de TFTP incluida) se encapsula otra vez por el siguiente protocolo (por ejemplo UDP), y otra vez por el siguiente (IP) y otra vez por el protocolo final o nivel (físico) del hardware (por ejemplo, Ethernet)

Cuando otro ordenador recibe el paquete, el hardware retira la cabecera Ethernet, el núcleo [kernel] retira las cabeceras IP y UDP, el programa TFTP retira la cabecera TFTP , y finalmente obtiene los datos.

Ahora puedo finalmente hablar del conocido Modelo de redes en niveles [Layered Network Model]. Este modelo de red describe un sistema de funcionalidades de red que tiene muchas ventajas sobre otros modelos. Por ejemplo, puedes escribir programas de sockets sin preocuparte de cómo los datos se transmiten físicamente (serie, thin ethernet, AUI, lo que sea) porque los programas en los niveles más bajos se ocupan de eso por ti. El hardware y la topología real de la red son transparentes para el programador de sockets.

Sin más preámbulos, te presento los niveles del modelo completo. Recuerda esto para tus exámenes de redes:

El nivel físico es el hardware (serie, Ethernet, etc.) El nivel de aplicación está tan lejos del nivel físico como puedas imaginar--es el lugar donde los usarios interactúan con la red.

Sin embargo, este modelo es tan general que si quisieras podrías usarlo como una guía para reparar coches. Un modelo de niveles más consistente con Unix podría ser:

En este momento, probablemente puedes ver como esos niveles se corresponden con la encapsulación de los datos originales.

¿Ves cuánto trabajo se necesita para construir un solo paquete? ¡Dios! ¡Y tienes que teclear la cabecera de los paquetes tu mismo, usando " cat"! Sólo bromeaba. Todo lo que tienes que hacer con los sockets de flujo es usar send() para enviar tus datos. Para los sockets de datagramas tienes que encapsular el paquete según el método de tu elección y enviarlo usando sendto(). El núcleo implementa los niveles de Internet y de Transporte por ti, y el hardware el nivel de acceso a la red. Ah, tecnología moderna.

Así finaliza nuestra breve incursión en la teoría de redes. Ah, olvidaba contarte todo lo que quería decir acerca del encaminamiento: ¡nada! Exacto, no voy a hablar de él en absoluto. el encaminador retira la información de la cabecera IP, consulta su tabla de encaminamiento, bla, bla, bla. Consulta el RFC sobre IP si de verdad te importa. Si nunca aprendes nada de eso probablemente sobrevivirás.


Anterior

Inicio

Siguiente

Introducción


struct s y manipulación de datos