lunes, 21 de noviembre de 2011

Sockets en C

Breve explicación de sockets en C:

Modelo cliente-servidor:
Ya todos sabemos que es el modelo mas usado. El cliente hace a petición de algún servicio al servidor.

Una analogía es una persona haciendo una llamada telefónica. Solo una de las partes en la comunicación debe saber el número al cual llamar (cliente), el otro no (servidor). Pero una vez que la conexión se ha hecho, ambos pueden mandar y recibir información.

LOS SOCKETS


Son la forma en que dos programas se transmitan datos, basados en el protocolo TCP/IP. Socket es un "canal de comunicación" entre dos programas.


EL SERVIDOR
Pasos que debe seguir un programa servidor:

  • socket(): crear el socket con esta llamada al sistema.
Esto nos devolverá un descriptor de fichero (file descriptor), tal como lo devolvería open(). Esta función no hace nada, solo devuelve y prepara el file descriptor que el sistema asociará a una conexión de red.
  • bind(): avisar al S.O. que se ha abierto un socket
Asociando nuestro programa con dicho socket. Aquí se indica el "número de servicio" al que se quiere atender. Aun no se atenderán las conexiones de clientes. 

  • listen(): Avisar al sistema de que comience a atender la conexión.
El S.O. anotará la conexión de cualquier cliente para pasárnosla cuando se lo pidamos. El S.O. hace una cola con los clientes y nos los pasa según los pidamos.

  • accept(): Pedir y aceptar las conexiones.
Esta función le indica al S.O. que nos dé al siguiente cliente de la cola. Si no hay, se bloquea hasta que algún cliente se conecte.

  • write() y read(): escribir y recibir datos del cliente.
  • close(): cierre de la comunicación y del socket.
EL CLIENTE
Pasos a seguir :

  • socket(): crear el socket.
  • connect(): solicitar conexión con el servidor.
  • write() y read(): escribir y recibir datos del servidor.
  • close(): cerrar la comnunicación
FICHROS UNIX/LINUX IMPLICADOS

/etc/hosts : Aquí hay una lista de nombres de ordenadores conectados en red y dirección IP de cada uno. Normalmente en esta carpeta, del lado del cliente, se suele colocar el nombre del servidor y su dirección IP. Luego desde el programa, se hace una llamada a la función gethostbyname(), que devuelve una estructura de datos entre los que está la dirección IP.

/etc/services : Este fichero es análogo a una agenda donde tenemos apuntados distintos números telefonicos de personas y demás datos. Desde el programa, cliente y servidor deben hacer una llamada a la función getservbyname(), que devuelve una estructura de datos entre los que está el número de servicio y tipo.


EJEMPLO EN CODIGO

Los siguientes códigos se pueden descargar desde http://www.linuxhowtos.org/C_C++/socket.htm de donde resumiré el funcionamento de los mismos. 

A) SERVIDOR
B)CLIENTE



Para correr estos programas, después de haberlos compilado con el gcc, haremos esto:
./server 31000

./cliente localhost 31000

31000 = número de puerto
localhost = el nombre del host donde se está ejecutando el SERVER, en este caso, se hará en una misma computadora.

El cliente te pedirá escribir un mensaje. Si funciona, el servidor desplegará tu mensaje, y le enviará un mensaje de respuesta al cliente y terminar el programa.


Una explicación detallada del código línea por línea se da en la siguiente página:
http://www.linuxhowtos.org/C_C++/socket.htm

También se explica como lograr, técnicamente, un chat. Puesto que en estos programas el servidor recibe el mensaje del cliente, y el programa termina. Pero con una modificación en la función main() se lograría que se puedan seguir mandando mensajes uno al otro, y resolver lo que en la misma página llaman "el problema del zombie".
En el main se debe agregar :  signal (SIGCHLD, SIG_IGN);
Lo cual le dice al cliente que ignore la señal SIGCHLD para que así el programa no se cierre.



PROGRAMA FUNCIONANDO

Compilación:
- Servidor

- Cliente


Ejecución:
- Servidor 
Aún no hace nada, espera a que el cliente envíe un mensaje


- Cliente 
Ingresa el mismo puerto y el nombre del host donde se encuentra el servidor.
Pide un mensaje.
La respuesta I GOT YOUR MESSAGE, es el mensaje del servidor.


Fuentes:
http://www.linuxhowtos.org/C_C++/socket.htm
http://www.chuidiang.com/clinux/sockets/sockets_simp.php


1 comentario: