Subsecciones

23. Sockets

Los sockets proporcionan una comunicación de dos vías, punto a punto entre dos procesos. Los sockets son muy versátiles y son un componente básico de comunicación entre interprocesos e intersistemas. Un socket es un punto final de comunicación al cual se puede asociar un nombre. Este tiene un tipo y uno o más procesos asociados.

Los sockets existen en los dominios de comunicación. Un socket de dominio es una representación que da una estructura de direccionamiento y un conjunto de protocolos. Los sockets se conectan solamente con sockets en el mismo dominio. Veintitrés dominios de sockets son identificados (ver <sys/socket.h>), de los cuales solamente los dominios de UNIX e Internet son normalmente sockets de Linux usados para comunicarse entre procesos en un sólo sistema, como otras formas de comunicación entre procesos.

El dominio de UNIX da un espacio de direcciones de socket en un sistema. Los sockets de dominio de UNIX son nombrados con las rutas de UNIX. Los sockets pueden también ser usados para comunicar procesos entre diferentes sistemas. El espacio de direcciones del socket entre los sistemas conectados es llamado el dominio de Internet.

La comunicación del dominio de Internet usa la suite del protocolo de Internet TCP/IP.

Los tipos de socket definen las propiedades de comunicación visibles para la aplicación. Los procesos se comunican solamente entre los sockets del mismo tipo. Existen cinco tipos de sockets.

Socket de flujo
da un flujo de datos de dos vías, confiable, y sin duplicados sin límites de grabación. El flujo opera en forma parecida a una conversación telefónica. El tipo del socket es SOCK_STREAM, el cual en el dominio de Internet usa TCP (Transmission Control Protocol).

Socket de datagrama
soporta un flujo de mensajes de dos vías. En un socket de datagrama podría recibir mensajes en diferente orden de la secuencia de la cual los mensajes fueron envíados. Los límites de grabación en los datos son preservados. Los sockets de datagrama operan parecidos a pasar cartas hacia adelante y hacia atrás en el correo. El tipo de socket es SOCK_DGRAM, el cual en el dominio de internet usa UDP (User Datagram Protocol).

Socket de paquete secuencial
da una conexión de dos vías, secuencial y confiable para datagramas de una longitud fija máxima. El tipo de socket es SOCK_SEQPACKET. No hay protocolo implementado para este tipo de cualquier familia de protocolos.

raw socket
da acceso a los protocolos de comunicación subyacente.

Los sockets son usualmente datagramas orientados, pero sus características exactas dependen de la interfaz dada por el protocolo.

23.1 Creación y nombrado de sockets

Se llama a la función int socket(int dominio, int tipo, int protocolo); para crear un extremo de una comunicación (socket) en el dominio especificado y del tipo indicado. Si un protocolo no es especificado. el sistema usa uno predefinido que soporte el tipo de socket especificado. El manejador del socket (un descriptor) es devuelto. Un proceso remoto no tiene forma de identificar un socket hasta que una dirección se ligada a este. Los procesos de comunicación se conectan a través de direcciones. En el dominio de UNIX, una conexión esta compuesta usualmente de uno o dos nombres de rutas. En el dominio de Internet, una conexión esta compuesta de direcciones locales y remotas y partes locales y remotas. En muchos dominios, las conexiones deben ser únicas.

Se llama a la función int bind(int sockfd, struct sockaddr *nomb, socklen_t longdir) para enlazar un camino o una dirección de Interne a un conector (socket). Hay tres formas diferentes de llamar a bind(), dependiendo del dominio del socket.

En el dominio de UNIX, el enlazado de nombres crea un socket con nombre en el sistema de archivos. Usar unlink() or rm() para eliminar el socket.

23.2 Conectando sockets de flujo

La conexión de sockets es usualmente asimétrica. Un proceso usualmente actúa como un servidor y el otro proceso es el cliente. El servidor enlaza su socket a un camino o dirección previamente acordada, y entonces bloquea el socket. Para un conetor SOCK_STREAM, el servidor llama a la función int listen(int s, int backlog), para indicar cuantas peticiones de conexión serán puestas en la cola. Un cliente inicia la conexión al socket del servidor mediante una llamada a la función int connect(inst s, struct sockaddr *nomb_serv, int longdirec). Una llamada en el dominio de UNIX es como la siguiente:

struct sockaddr_un server;
...
connect ( sd, (struc sockaddr_un *)&server, long);

mientras en el dominio de Internet la llamada podría ser:

struct sockaddr_in server;
...
connect ( sd, (struc sockaddr_un *)&server, long);

Si el socket del cliente no esta enlazado al momento de hacer la llamada para la conexión, el sistema automáticamente selecciona y liga un nombre al socket. Para un socket SOCK_STREAM, el servidor llama a la función accept() para completar la conexión.

La función int accept(int s, struct sockaddr *addr, int *longdirec) regresa un conector nuevo el cual es válido solamente para la conexión particular. Un servidor puede tener múltiples conexiones SOCK_STREAM activas al mismo tiempo.

23.2.1 Transferencia de datos en un flujo y cerrado

Se emplean varias funciones para enviar y recibir datos de un socket SOCK_STREAM. Estas son write(), read(), int send(int s, const void *msg, size_t lon, int flags), y int recv(int s, void *buf, size_t lon, int flags). Las funciones send() y recv() son parecidas a read() y write(), pero tienen algunas banderas operacionales adicionales.

El argumento flags de una llamada a recv se forma aplicando el operador de bits O-lógico a uno o más de los valores siguientes:

MSG_OOB
Pide la recepción de datos fuera-de-banda que no se recibiran en el flujo de datos normal. Algunos protocolos ponen datos despachados con prontitud en la cabeza de la cola de datos normales, y así, esta opción no puede emplearse con tales protocolos.

MSG_PEEK
Hace que la operacin de recepción devuelva datos del principio de la cola de recepción sin quitarlos de allí. Así, una próxima llamada de recepción devolverá los mismos datos.

MSG_WAITALL
Esta opción hace que la operación se bloquee hasta que se sat- isfaga la petición completamente. Sin embargo, la llamada puede aun devolver menos datos de los pedidos si se captura una señal, si ocurre un error o una desconexión, o si los próximos datos que se van a recibir son de un tipo diferente del que se ha devuelto.

MSG_NOSIGNAL
Esta opcin desactiva el que se produzca una señal SIGPIPE sobre los conectores orientados a conexión cuando el otro extremo desaparece.

MSG_ERRQUEUE
Esta opción indica que los errores encolados deben recibirse desde la cola de errores de conectores. El error se pasa en un mensaje auxiliar con un tipo dependiente del protocolo (para IPv4 ste es IP_RECVERR). El usuario debe proporciona un buffer de tamaño suficiente. Vea cmsg(3) para obtener ms información sobre mensajes auxiliares.