Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


LOS SOCKETS, Apuntes de Ingeniería Infórmatica

Asignatura: Lab. de Redes, Profesor: , Carrera: Ingeniería Informática, Universidad: UAX

Tipo: Apuntes

Antes del 2010

Subido el 22/05/2007

_vivayo_
_vivayo_ 🇪🇸

3.7

(117)

149 documentos

1 / 11

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
LOS SOCKETS
4.- Los Sockets.
4.1.- Tipos de sockets.
4.2.- El dominio de un socket.
4.3.- Folosofía Cliente-Servidor: el Servidor.
4.4.- El Cliente.
Comparación sockets-pipes.
Ejemplo de comunicación mediante Sockets UNIX ( en la misma máquina ).
Ejemplo de comunicación con sockets INET ( diferentes máquinas ).
4.- LOS SOCKETS.
Los sockets no son más que puntos o mecanismos de comunicación entre
procesos que permiten que un proceso hable ( emita o reciba información ) con
otro proceso incluso estando estos procesos en distintas máquinas. Esta
característica de interconectividad entre máquinas hace que el concepto de socket
nos sirva de gran utilidad. Esta interfaz de comunicaciones es una de las
distribuciones de Berkeley al sistema UNIX, implementándose las utilidades de
interconectividad de este Sistema Operativo ( rlogin, telnet, ftp, ... ) usando
sockets.
Un socket es al sistema de comunicación entre ordenadores lo que un buzón
o un teléfono es al sistema de comunicación entre personas: un punto de
comunicación entre dos agentes ( procesos o personas respectivamente ) por el
cual se puede emitir o recibir información. La forma de referenciar un socket por
los procesos implicados es mediante un descriptor del mismo tipo que el
utilizado para referenciar ficheros. Debido a esta característica, se podrá realizar
redirecciones de los archivos de E/S estándar (descriptores 0,1 y 2) a los sockets
y así combinar entre ellos aplicaciones de la red. Todo nuevo proceso creado
heredará, por tanto, los descriptores de sockets de su padre.
La comunicación entre procesos a través de sockets se basa en la filosofía
CLIENTE-SERVIDOR: un proceso en esta comunicación actuará de proceso
servidor creando un socket cuyo nombre conocerá el proceso cliente, el cual
podrá "hablar" con el proceso servidor a través de la conexión con dicho socket
pf3
pf4
pf5
pf8
pf9
pfa

Vista previa parcial del texto

¡Descarga LOS SOCKETS y más Apuntes en PDF de Ingeniería Infórmatica solo en Docsity!

LOS SOCKETS

4.- Los Sockets. 4.1.- Tipos de sockets. 4.2.- El dominio de un socket. 4.3.- Folosofía Cliente-Servidor: el Servidor. 4.4.- El Cliente.

Comparación sockets-pipes.

Ejemplo de comunicación mediante Sockets UNIX ( en la misma máquina ).

Ejemplo de comunicación con sockets INET ( diferentes máquinas ).

4.- LOS SOCKETS.

Los sockets no son más que puntos o mecanismos de comunicación entre

procesos que permiten que un proceso hable ( emita o reciba información ) con

otro proceso incluso estando estos procesos en distintas máquinas. Esta

característica de interconectividad entre máquinas hace que el concepto de socket

nos sirva de gran utilidad. Esta interfaz de comunicaciones es una de las

distribuciones de Berkeley al sistema UNIX, implementándose las utilidades de

interconectividad de este Sistema Operativo ( rlogin, telnet, ftp, ... ) usando

sockets.

Un socket es al sistema de comunicación entre ordenadores lo que un buzón

o un teléfono es al sistema de comunicación entre personas: un punto de

comunicación entre dos agentes ( procesos o personas respectivamente ) por el

cual se puede emitir o recibir información. La forma de referenciar un socket por

los procesos implicados es mediante un descriptor del mismo tipo que el

utilizado para referenciar ficheros. Debido a esta característica, se podrá realizar

redirecciones de los archivos de E/S estándar (descriptores 0,1 y 2) a los sockets

y así combinar entre ellos aplicaciones de la red. Todo nuevo proceso creado

heredará, por tanto, los descriptores de sockets de su padre.

La comunicación entre procesos a través de sockets se basa en la filosofía

CLIENTE-SERVIDOR : un proceso en esta comunicación actuará de proceso

servidor creando un socket cuyo nombre conocerá el proceso cliente , el cual

podrá "hablar" con el proceso servidor a través de la conexión con dicho socket

nombrado.

El proceso crea un socket sin nombre cuyo valor de vuelta es un descriptor

sobre el que se leerá o escribirá, permitiéndose una comunicación bidireccional ,

característica propia de los sockets y que los diferencia de los pipes , o canales de

comunicación unidireccional entre procesos de una misma máquina. El

mecanismo de comunicación vía sockets tiene los siguientes pasos:

1º) El proceso servidor crea un socket con nombre y espera la

conexión.

2º) El proceso cliente crea un socket sin nombre.

3º) El proceso cliente realiza una petición de conexión al socket

servidor.

4º) El cliente realiza la conexión a través de su socket mientras el

proceso servidor mantiene el socket servidor original con

nombre.

Es muy común en este tipo de comunicación lanzar un proceso hijo, una vez

realizada la conexión, que se ocupe del intercambio de información con el

proceso cliente mientras el proceso padre servidor sigue aceptando conexiones.

Para eliminar esta característica se cerrará el descriptor del socket servidor con

nombre en cuanto realice una conexión con un proceso socket cliente.

-> Todo socket viene definido por dos características fundamentales:

  • El tipo del socket, que indica la naturaleza del mismo, el tipo de

comunicación que puede generarse entre los sockets.

  • El dominio del socket especifica el conjunto de sockets que pueden

establecer una comunicación con el mismo.

Vamos a estudiar con más detalle estos dos aspectos:

4.1.- Tipos de sockets.

Define las propiedades de las comunicaciones en las que se ve envuelto un

socket, esto es, el tipo de comunicación que se puede dar entre cliente y servidor.

Estas pueden ser:

  • Fiabilidad de transmisión.
  • Mantenimiento del orden de los datos.
  • No duplicación de los datos.
  • El "Modo Conectado" en la comunicación.
  • Envío de mensajes urgentes.

Los tipos disponibles son los siguientes:

* Tipo SOCK_DGRAM : sockets para comunicaciones en modo no

u__short sin_port; /* numero del puerto */

struct in__addr sin__addr; /* direcc Internet */

char sin_zero[8]; /* campo de 8 ceros */

Estos dominios van a ser los utilizados en xshine. Pero existen otros como:

* Dominio AF_NS :

Servidor y cliente deben estar en una red XEROX.

* Dominio AF_CCITT :

Para protocolos CCITT, protocolos X25, ...

4.3.- FILOSOFIA CLIENTE-SERVIDOR: el Servidor.

Vamos a explicar el proceso de comunicación servidor-cliente en modo

conectado , modo utilizado por las aplicaciones estándar de Internet (telnet, ftp).

El servidor es el proceso que crea el socket no nombrado y acepta las conexiones

a él. El orden de las llamadas al sistema para la realización de esta función es:

1º) int socket ( int dominio , int tipo , int protocolo )

crea un socket sin nombre de un dominio, tipo y p

rotocolo específico

dominio : AF_INET, AF_UNIX

tipo : SOCK__DGRAM, SOCK__STREAM

protocolo : 0 ( protocolo por defecto )

2º) int bind ( int dfServer , struct sockaddr* direccServer , int longDirecc )

nombra un socket: asocia el socket no nombrado de descriptor dfServer con

la dirección del socket almacenado en direccServer. La dirección depende de si

estamos en un dominio AF_UNIX o AF_INET.

3º) int listen ( int dfServer , int longCola )

especifica el máximo número de peticiones de conexión pendientes.

4º) int accept ( int dfServer , struct sockaddr* direccCliente , int* longDireccCli )

escucha al socket nombrado servidor dfServer y espera hasta que se reciba

la petición de la conexión de un cliente. Al ocurrir esta incidencia, crea un socket

sin nombre con las mismas características que el socket servidor original, lo

conecta al socket cliente y devuelve

un descriptor de fichero que puede ser utilizado para la comunicación con el

cliente.

4.4.- El Cliente.

Es el proceso encargado de crear un socket sin nombre y posteriormente

enlazarlo con el socker servidor nombrado. O sea, es el proceso que demanda una

conexión al servidor. La secuencia de llamadas al sistema es:

1º) int socket ( int dominio , int tipo , int protocolo )

crea un socket sin nombre de un dominio, tipo y protocolo específico

dominio : AF_INET, AF_UNIX

tipo : SOCK__DGRAM, SOCK__STREAM

protocolo : 0 ( protocolo por defecto )

2º) int connect ( int dfCliente , struct sockaddr* direccServer , int longDirecc )

intenta conectar con un socket servidor cuya dirección se encuentra

incluida en la estructura apuntada por direccServer. El descriptor dfCliente se

utilizará para comunicar con el socket servidor. El tipo de estructura dependerá

del dominio en que nos encontremos.

Una vez establecida la comunicación, los descriptores de ficheros serán utilizados

para almacenar la información a leer o escribir.

SERVIDOR. CLIENTE

descrServer = socket ( dominio, SOCK_STREAM,PROTOCOLO)

descrClient = socket (dominio, SOCK_STREAM,PROTOCOLO)

bind (descrServer, PuntSockServer,longServer)

do {

listen (descrServer, longCola)

descrClient = accept (descrServer,PuntSockClient,longClient)

result = connect (descrClient, PuntSockServer,longserver)

[ close (descrServer) ] } while ( result == -1 )

< DIALOGO > < DIALOGO >

close (descrClient) close (descrClient)

COMPARACION SOCKETS-PIPES COMO MECANISMOS DE

COMUNICACION ENTRE PROCESOS

SOCKETS PIPES

refenciado por descriptores

referenciado por array de descriptores

admite comunicación entre procesos de distintas máquinas

sólo admite comunicación entre procesos de la misma máquina

comunicación bidireccional

comunicación unidireccional

/* acepta la conexion cliente / printf ("\n acepto la conexion \n"); if ( fork() == 0 ) / crea hijo y envia fichero / { escribeFichero ( dfClient ); close ( dfClient ); / cierra el socket / exit ( 0 ); } else close ( dfClient ); / cierra el descriptor cliente / } / en el padre */ }

/******** funcion escribeFichero( df ) ***************/ escribeFichero ( int df ) { static char* linea1 = "esta es la linea 1, "; static char* linea2 = "y esta la linea 2. ";

write ( df, linea1, strlen (linea1) + 1 ); write ( df, linea2, strlen (linea2) + 1 ); }

/****************** fin de servidor.c ***********************/

/************** cliente.c **********************/ /************************************************************/ /********* proceso cliente con sockets AF_UNIX **********/ /************************************************************/

#include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h>

#include <sys/un.h> /* para sockets UNIX */

#define PROTOCOLO_DEFECTO 0

main() { int dfClient, longServer, resultado; struct sockaddr_un dirUNIXServer; struct sockaddr* puntSockServer;

puntSockServer = ( struct sockaddr* ) &dirUNIXServer; longServer = sizeof ( dirUNIXServer );

dfClient = socket ( AF_UNIX, SOCK_STREAM, PROTOCOLO_DEFECTO ); /* se crea un socket UNIX, bidireccional */

dirUNIXServer.sun_family = AF_UNIX; /* tipo de dominio server / strcpy ( dirUNIXServer.sun_path, "fichero" ); / nombre server */

do { resultado = connect ( dfClient, puntSockServer, longServer ); if ( resultado == -1 ) sleep (1); /* reintento */ } while ( resultado == -1 );

leeFichero ( dfClient ); /* lee el fichero / close ( dfClient ); / cierra el socket / exit (0); / buen fin */

}

/************* leeFichero ( df ) *****************/

leeFichero ( int df ) { char cad[200]; while ( leeLinea ( df, cad ) ) /* lee hasta fin de la entrada / printf ("%s\n", cad ); / e imprime lo leido */

}

/************* leeLinea ( df, cad ) ******************/ leeLinea ( int df, char cad ) { int n; do { n = read ( df, cad, 1 ); / lectura de un caracter */ } while ( n > 0 && cad++ != NULL ); / lee hasta NULL o fin entrada */

return ( n > 0 ); /* devuelve falso si fin de entrada */

if (inetAddress == 0) break;

bzero ((char *)&serverINETAddress , sizeof(serverINETAddress)); serverINETAddress.sin_family = AF_INET; serverINETAddress.sin_addr.s_addr = inetAddress; serverINETAddress.sin_port = htons ( PUERTO_HORA );

clientFd = socket ( AF_INET, SOCK_STREAM, PROTOCOLO_DEFECTO );

do { result = connect( clientFd, serverSockAddrPtr, serverLen ); if (result == -1) sleep(1); } while (result == -1);

readTime(clientFd); close(clientFd); } exit(0); }

/****************** promptForINETAddress () **************************/ unsigned long promptForINETAddress () { char hostName [100]; unsigned long inetAddress;

do { printf ("Nombre maquina (q = salir, s = maquina propia): "); scanf("%s",hostName); if ( strcmp (hostName,"q") == 0 ) return(0); inetAddress = nameToAddr (hostName); if (inetAddress == 0 ) printf ("\n Maquina no encontrada\n"); } while ( inetAddress == 0 ); }

/******************* nameToAddr ( name ) *************************/ unsigned long nameToAddr (char name) { char hostName[100]; struct hostent hostStruct; struct in_addr* hostNode;

if (isdigit (name[0])) return (inet_addr (name)); if (strcmp (name,"s") == 0) { gethostname (hostName,100);

printf("Nombre de la propia maquina es %s\n",hostName); } else strcpy(hostName,name);

hostStruct = gethostbyname (hostName); if (hostStruct == NULL) return (0); /** maquina no encontrada **/

hostNode = (struct in_addr) hostStruct->h_addr; / saca la dir. IP de la struct / printf("Direccion IP = %s\n", inet_ntoa (hostNode)); return (hostNode->s_addr); /* devuelve la dir IP */ }

/******************** readTime ( fd ) **********************/

readTime (int fd) { char str[200];

printf("La hora en el puerto destino es ");

while (readLine (fd,str)) printf("%s\n",str); }

/************ readLine ( fd, str ) ******************************/ readLine (int fd,char* str) { int n; do { n = read(fd,str,1); } while (n>0 && *str++ != '\n'); return (n>0); }