logo

Programación de sockets en C

¿Qué es la programación de sockets?

La programación de sockets es una forma de conectar dos nodos en una red para comunicarse entre sí. Un socket (nodo) escucha en un puerto particular en una IP, mientras que el otro socket se acerca al otro para formar una conexión. El servidor forma el socket de escucha mientras el cliente se comunica con el servidor.

Diagrama de estado para el modelo de servidor y cliente

Diagrama de estado para el modelo de servidor y cliente de Socket

Etapas para el servidor

El servidor se crea siguiendo los siguientes pasos:



matriz de bytes a cadena

1. Creación de zócalos

int sockfd = socket(domain, type, protocol)>
    sockfd: descriptor de socket, un número entero (como un identificador de archivo) dominio: número entero, especifica el dominio de comunicación. Usamos AF_LOCAL como se define en el estándar POSIX para la comunicación entre procesos en el mismo host. Para comunicarnos entre procesos en diferentes hosts conectados por IPV4, utilizamos AF_INET y AF_I NET 6 para procesos conectados por IPV6. tipo: tipo de comunicación
    SOCK_STREAM: TCP (confiable, orientado a la conexión)
    SOCK_DGRAM: Protocolo UDP (no confiable, sin conexión): valor de protocolo para el Protocolo de Internet (IP), que es 0. Este es el mismo número que aparece en el campo de protocolo en el encabezado IP de un paquete (protocolos man para más detalles).

2. Conjuntosockopt

Esto ayuda a manipular las opciones para el socket al que hace referencia el descriptor de archivo sockfd. Esto es completamente opcional, pero ayuda a reutilizar la dirección y el puerto. Previene errores como: dirección ya en uso.

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);>

3. Atar

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);>

Después de la creación del socket, la función de vinculación vincula el socket a la dirección y el número de puerto especificados en addr (estructura de datos personalizada). En el código de ejemplo, vinculamos el servidor al host local, por lo tanto usamos INADDR_ANY para especificar la dirección IP.

4. Escuche

int listen(int sockfd, int backlog);>

Pone el socket del servidor en modo pasivo, donde espera a que el cliente se acerque al servidor para establecer una conexión. El backlog define la longitud máxima a la que puede crecer la cola de conexiones pendientes para sockfd. Si llega una solicitud de conexión cuando la cola está llena, el cliente puede recibir un error con una indicación de ECONNREFUSED.

5. Aceptar

int new_socket= accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);>

Extrae la primera solicitud de conexión en la cola de conexiones pendientes para el socket de escucha, sockfd, crea un nuevo socket conectado y devuelve un nuevo descriptor de archivo que hace referencia a ese socket. En este punto, se establece la conexión entre el cliente y el servidor y están listos para transferir datos.

Etapas para el cliente

1. Conexión de enchufe: Exactamente igual que el de la creación del socket del servidor.

2. Conectar: La llamada al sistema connect() conecta el socket al que hace referencia el descriptor de archivo sockfd a la dirección especificada por addr. La dirección y el puerto del servidor se especifican en addr.

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);>

Implementación

Aquí estamos intercambiando un mensaje de saludo entre el servidor y el cliente para demostrar el modelo cliente/servidor.

Programa C para crear servidor

Servidor.c

C




// Server side C program to demonstrate Socket> // programming> #include> #include> #include> #include> #include> #include> #define PORT 8080> int> main(>int> argc,>char> const>* argv[])> {> >int> server_fd, new_socket;> >ssize_t valread;> >struct> sockaddr_in address;> >int> opt = 1;> >socklen_t addrlen =>sizeof>(address);> >char> buffer[1024] = { 0 };> >char>* hello =>'Hello from server'>;> >// Creating socket file descriptor> >if> ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) <0) {> >perror>(>'socket failed'>);> >exit>(EXIT_FAILURE);> >}> >// Forcefully attaching socket to the port 8080> >if> (setsockopt(server_fd, SOL_SOCKET,> >SO_REUSEADDR | SO_REUSEPORT, &opt,> >sizeof>(opt))) {> >perror>(>'setsockopt'>);> >exit>(EXIT_FAILURE);> >}> >address.sin_family = AF_INET;> >address.sin_addr.s_addr = INADDR_ANY;> >address.sin_port = htons(PORT);> >// Forcefully attaching socket to the port 8080> >if> (bind(server_fd, (>struct> sockaddr*)&address,> >sizeof>(address))> ><0) {> >perror>(>'bind failed'>);> >exit>(EXIT_FAILURE);> >}> >if> (listen(server_fd, 3) <0) {> >perror>(>'listen'>);> >exit>(EXIT_FAILURE);> >}> >if> ((new_socket> >= accept(server_fd, (>struct> sockaddr*)&address,> >&addrlen))> ><0) {> >perror>(>'accept'>);> >exit>(EXIT_FAILURE);> >}> >valread = read(new_socket, buffer,> >1024 - 1);>// subtract 1 for the null> >// terminator at the end> >printf>(>'%s '>, buffer);> >send(new_socket, hello,>strlen>(hello), 0);> >printf>(>'Hello message sent '>);> >// closing the connected socket> >close(new_socket);> >// closing the listening socket> >close(server_fd);> >return> 0;> }>

gimp cómo anular la selección
>

>

Programa C para crear cliente

cliente.c

C




fusionar ordenar java

// Client side C program to demonstrate Socket> // programming> #include> #include> #include> #include> #include> #define PORT 8080> int> main(>int> argc,>char> const>* argv[])> {> >int> status, valread, client_fd;> >struct> sockaddr_in serv_addr;> >char>* hello =>'Hello from client'>;> >char> buffer[1024] = { 0 };> >if> ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) <0) {> >printf>(>' Socket creation error '>);> >return> -1;> >}> >serv_addr.sin_family = AF_INET;> >serv_addr.sin_port = htons(PORT);> >// Convert IPv4 and IPv6 addresses from text to binary> >// form> >if> (inet_pton(AF_INET,>'127.0.0.1'>, &serv_addr.sin_addr)> ><= 0) {> >printf>(> >' Invalid address/ Address not supported '>);> >return> -1;> >}> >if> ((status> >= connect(client_fd, (>struct> sockaddr*)&serv_addr,> >sizeof>(serv_addr)))> ><0) {> >printf>(>' Connection Failed '>);> >return> -1;> >}> >send(client_fd, hello,>strlen>(hello), 0);> >printf>(>'Hello message sent '>);> >valread = read(client_fd, buffer,> >1024 - 1);>// subtract 1 for the null> >// terminator at the end> >printf>(>'%s '>, buffer);> >// closing the connected socket> >close(client_fd);> >return> 0;> }>

>

>

Producción

Client:Hello message sent Hello from server Server:Hello from client Hello message sent>

Compilando

gcc client.c -o client gcc server.c -o server>

Siguiente: Programación de sockets en C/C++: manejo de múltiples clientes en el servidor sin subprocesos múltiples