Arquitecturas Cliente/Servidor Integrantes: Arellano Santiago Víctor Manuel Girón Capistrán Aldo Iván Guerrero Ramirez Eduardo Daniel Rosas Peña Ramiro
SOCKETS EN C.
LLAMADAS PARA EL MANEJO DE SOCKETS Basada en el uso de descriptores de sockets de manera análoga a la escritura y lectura de archivos. Cabeceras a utilizar de forma general: types.h, socket.h, uio.h
Creación de un socket: socket( ) Para que una persona pueda recibir llamadas debe tener instalado un teléfono, para poder realizar una conexión se debe crear un socket. Los sockets se crean llamando a la función socket(), esta función retorna un descritpor de socket, que es tipo int. Si hubo algún error, socket() retorna -1 y la variable global errno se establece con un valor que indica el error que se produjo sockf= socket ( int dominio, int tipo, int protocolo );
SOCKET int socket(int af, int type, int protocol); Función: abre un canal bidireccional de comunicaciones, devuelve un descriptor. af: especifica la familia de sockets a emplear. Las principales son AF_UNIX y AF_INET. type: Tipo de socket ya sea orientado a la conexión SOCK_STREAM y no orientado a la conexión: SOCK_DGRAM protocol: Protocolo a utilizar. Si es cero, se deja en manos del sistema la elección.
BIND Función: Une un socket a un dirección de red determinada. Cabeceras: un.h para familia AF_UNIX y netinet.h para familia AF_INET. int bind(int sfd,const void *addr,int addrlen); sfd: descriptor devuelto por la función socket. addr:dirección del socket addrlen: longitud de la dirección, se calcula con el operador sizeof.
LISTEN Función: utilizada para sockets TCP, indica disponibilidad para recibir peticiones. int listen(int sfd, int backlog); sfd: descriptor del socket. backlog:longitud de la cola asociada al socket descrito.
CONNECT, ACCEPT. Función connect: permite que el cliente inicie la conexión con el servidor. int connect(int sfd, void *addr, int addrlen); Función: Los procesos servidores leen peticiones de servicio. int accept(int sfd, void *addr, int addrlen); sfd: descriptor del socket. addr: apuntador a la estructura de dirección del socket. addrlen: Tamaño en bytes de la dirección.
Pasos para establecer la comunicación: En sockets orientados a conexión Cliente y servidor, deben crean un socket mediante la función socket(), para poder comunicarse. El servidor llama a bind() para darle un nombre al socket, para luego poder recibir conexiones, es decir establece por cual número de puerto escuchará. El servidor hablilita su socket para poder recibir conexiones, llamando a la función listen(). El servidor ejecuta la f unción accept() y queda en estado de espera, la función accept() no retorna hasta que intenten conectarse.
El cliente usa la función connect() para realizar el intento de conexión, en ese momento la función accept() del servidor retorna con un parámetro que es un nuevo descriptor de socket. Una vez establecida la conexión se utilizan las funciones send() y recv() con el descriptor de socket del paso anterior para realizar la transferencia de datos. Para finalizar la conexión se utilizan las funciones close() o shutdown().
En sockets no orientados a conexión. Ambos, cliente y servidor, crean un socket mediante la función socket( ). El servidor debe establecer por qué número de puerto recibirá los datos, en este caso no existe la conexión, los datos se envían como si fueran mensajes.
Para realizar transferencia de datos, utilizan las funciones sendto( ) y recvfrom( ). No es necesario que el servidor llame a la función listen( ), ni tampoco el paso connect( ) o accept( ).
LECTURA/RECEPCIÓN DE MENSAJES. Lectura de datos de un socket: read, readv. Solo para sockets son: recv, recvfrom, recvmsg. ssize_t readv(int fildes, const struct iovec *iov, size_t iovcnt); int recv(int sfd, void *buf, int len, int flags); int recvfrom(int sfd, void *buf, int len, int flags, void *from, int fromlen); int recvmsg(int sfd, struct msghdr msg[], int flags);
ESCRITURA/ENVIO DE MENSAJES A UN SOCKET. Escritura de datos: write, writev. Solo para sockets: send, sendto, sendmsg. ssize_t writev(int fildes, const struct iovec *iov, size_t iovcnt); int send(int sfd, void *buf, int len, int flags); int sendto(int sfd, void *buf, int len, int flags, void *to, int tolen); int sendmsg(int sfd,struct msghdr msg[], int flags);