Bienvenidos sean a este post, hoy veremos al lado del servidor.
En este post no solo hablamos sobre los socket sino tambien como se crean para un codigo, de manera simple, Esta se encuentra definida en la libreria socket.h de parte de sys, tambien podemos utilizar a accept y bind que son otras funciones para conectarnos a la red. Igualmente no solamente se utiliza a esta libreria sino que usaremos varias mas. Vamos a implementar un ejemplo de servidor clasico TCP.
Una cosa que no mencionamos directamente es que el desarrollo del lado del servidor difiere del lado del cliente y su conducta. Si bien ambos lados operan con sockets, el servidor esta principalmente «escuchando» las conexiones entrantes. Mientras que el cliente se encarga de iniciar las conexiones con el servidor. Pasemos a analizar el siguiente codigo:
server.cpp
#include <iostream>
#include <cstring>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
int main()
{
int socketServer = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in direcServer;
direcServer.sin_family = AF_INET;
direcServer.sin_port = htons(8080);
direcServer.sin_addr.s_addr = INADDR_ANY;
bind(socketServer, (struct sockaddr*) &direcServer,
sizeof(direcServer));
listen(socketServer, 5);
int socketCliente = accept(socketServer, nullptr, nullptr);
char buffer[1024] = {0};
recv(socketCliente, buffer, sizeof(buffer), 0);
std::cout << "Mensaje del cliente: " << buffer << std::endl;
close(socketServer);
return 0;
}
Como mencionamos anteriormente, vamos a necesitar mas que la libreria socket.h para conectarnos a la red. La primera que tenemos es netinet/in.h, la cual se encarga de manejar algunos miembros de datos para conectarnos a internet pero de eso hablaremos en un momento. Luego tenemos a socket para crearla, y una ultima para permitir acceder a constantes y tipos simbolicos estandard.
Yendo al main, lo primero que haremos sera crear a nuestro socket y establecemos como sera. En este caso, de tipo IPv4, uno de conexion establecida y no por datagrama, y el ultimo sera el protocolo y para este caso TCP. Pero este es solo un socket y todavia nos falta establecer los parametros para establecer la conexion como es la direccion IP y el puerto. Para ello, creamos un objeto del tipo sockaddr_in (de netinet/in.h) y a este le asignamos unos valores para algunas propiedades de esta clase. El primer parametro es para establecer como sera la direccion IP, al igual que el caso anterior es de IPv4. Luego establecemos el puerto que usaremos para conectarnos, La funcion que usamos para establecerlo es para que ese valor se almacene en memoria en el orden correcto para que pueda ser interpretado correctamente. La ultima opcion es para indicar que no unamos este socket a ninguna direccion IP especifica y que pueda ser escuchada por cualquiera de las disponibles. Con la direccion del servidor creada procedesmos a unirla al socket anterior mediante bind. Donde primero pasaremos primero al socket, luego la direccion IP del servidor (previo casteo para que pueda ser aceptado) y finalmente el tamaño de este.
Por ultimo, tenemos un listen que comenzara a escuchar en el socket que creamos. El segundo parametro es para informar cuantas conexiones podemos aceptar antes de invocar a la funcion accept pero no se confundan, esto no establece la cantidad de conexiones que acepta listen.
La siguiente variable se encarga de recibir el valor devuelto por accept. Le pasamos como parametro al socket creado y dos valores nulos porque no son necesarios para esta ocasion. Estos dos parametros son del mismo tipo que bind. Establecemos un buffer para poder almacenar los valores recibidos desde el cliente. Para poder recibir los datos usamos a recv, donde primero pasaremos el socket que devuelve la informacion., el siguiente sera el buffer que establecimos anteriormente para recibir los valores del socket, el tercero es para establecer el tamaño disponible para almacenar, y el ultimo es para establecer como se manejaran por eso la dejaremos en 0. Luego mostraremos el valor recibido desde el cliente y con un mensaje indicando esto. Para finalizar, cerramos al socket mediante la funcion close y que no siga escuchando o quede perdida en memoria.
Si lo compilan y ejecutan, notaran que no devolvera nada y se quedara esperando una respuesta pero como el cliente no existe no finalizara nunca. Pero este proyecto lo concluiremos en el proximo post, hoy solo cubrimos la parte encargada de recibir los valores.
En resumen, hoy hemos visto a la aplicacion servidor, como se establece el socket, sus parametros para permitir unirlos, una vez unidos prepararlo para escuchar las conexiones y por ultimo como aceptar el valor y procesarlo, en este caso mostrarlo en pantalla, pero todavia de forma incompleta En el proximo post, lo completaremos. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
