Underc0de - La Casa de los Informáticos

Programación General => C / C++ => Mensaje iniciado por: loris24 en Enero 09, 2026, 11:52:47 AM

Título: servidor y cliente udp [simple]
Publicado por: loris24 en Enero 09, 2026, 11:52:47 AM
(https://i.postimg.cc/prTnQ6th/Server.png) (https://postimg.cc/R6kF4Gh4)

Buenas chicos.

Os traigo un cliente y servidor udp sencillos. El funcionamiento es simple. El cliente realiza una conexion
con el servidor enviandole datos recogidos por consola y el servidor los imprime por pantalla.

Si habeis seguido los hilos anteriores podreis notar la clasica diferencia de la conexion en ambos
protocolos. TCP es orientado a conexion pero UDP no. En estos codigos podeis ver exhibidos, a mi juicio, de manera sencilla lo anterior expuesto.
Proximamente os traere más.

¡Un saludo!


codigo del cliente:
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <iostream>
#include <sys/select.h>



#define IP_SERVER ("127.0.0.1")
#define PORT_SERVER ("9999")

int main(int argc, char **argv ){


    struct addrinfo base;
    memset(&base, 0, sizeof base);
    base.ai_socktype = SOCK_DGRAM;
    struct addrinfo *res;

    if(getaddrinfo(IP_SERVER, PORT_SERVER, &base, &res) < 0){
        std::cerr << "An error has ocurred in getaddrinfo" << std::endl;
        std::cerr << "exiting..." << std::endl;
        return -1;
    }

    int sock = socket(
        res -> ai_family,
        res -> ai_socktype,
        res -> ai_protocol
        );

    if(sock < 0){
        std::cerr << "An error has ocurred while creating socket" <<std::endl;
        return -1;
    }


    //ya podemos enviar y recibir con nuestro socket
    //a diferencia de tcp ya no es necesario establecer una conexion con el servidor


    bool terminado = false;
    while(!terminado){ //atencion, bucle infinito, parar con CTRL+C

        //manejamos entrada por stdin
        fd_set out;
        FD_ZERO(&out);
        FD_SET(1, &out);
        int max_fd = 1;

        int res_sel = select(max_fd + 1, &out, 0, 0, 0);

        if(res_sel  < 0){
            std::cerr << "An error has ocurred while doing select" << std::endl;
            return -1;
        }else{

            //aqui ya podemos recoger entrada por terminal
            char buff[1024];
            if(!fgets(buff, 1024, stdin)) break;

            int bytes_sent = sendto(
                sock,
                buff,
                1024,
                0,
                res -> ai_addr,
                res -> ai_addrlen
                );


            if(bytes_sent < 0){
                std::cerr << "An error has ocurred while sending bytes" << std::endl;
                break;
            }
           
            std::cout << "Bytes sent: "<< bytes_sent << std::endl;
        }
    }

    close(sock);
    return 0;
}

Codigo del servidor:
#include <netdb.h>
#include <iostream>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <cstring>
#include <cstdlib>


#define SERVER_IP NULL
/*
le digo que es null porque quiero que mi
sistema operativo me asigne la direccion de loopback
*/
#define PORT_SERVER ("9999")


int main(int argc, char **argv){



    struct addrinfo base;
    memset(&base, 0, sizeof base);
    base.ai_family = AF_INET;
    base.ai_socktype = SOCK_DGRAM;
    base.ai_flags = AI_PASSIVE;
    struct addrinfo *res;


    if(getaddrinfo(SERVER_IP, PORT_SERVER, &base, &res) < 0){
        std::cerr << "An error has ocurred with the getaddrinfo" << std::endl;
        std::cerr << "exiting..." << std::endl;
        return -1;
    }

    int sock = socket(
        res -> ai_family,
        res -> ai_socktype,
        res -> ai_protocol
        );

    if(sock < 0){
        std::cerr << "An error has ocurred while creating socket" << std::endl;
        return -1;
    }

    if(bind(sock, res -> ai_addr, res -> ai_addrlen) < 0){
        std::cerr << "An error has ocurred while binding ip to socket" << std::endl;
        return -1;
    }

    //ya podemos utilizar nuestro socket para recibir mensajes

    bool terminado = false;
   
    while(!terminado){ //atencion, bucle infinito, parar con CTRL+C

        struct sockaddr_storage client; //esta estructura sirve simplemente para almacenar informacion del cliente
        socklen_t client_size = sizeof client;
        char buff[1024]; //aqui recibimos los mensajes

        int bytes_received = recvfrom(
            sock,
            buff,
            1024,
            0,
            (struct sockaddr *)&client,
            &client_size
            );

        if(bytes_received == 0){
            std::cout << "Connection closed by peer" << std::endl;
            break;
        }

        if(bytes_received < 0){
            std::cerr << "An error has ocurred in recvfrom" << std::endl;
            return -1;
        }


        char client_buffer[128];
        char port_buffer[128];

        getnameinfo(
            (struct sockaddr *)&client,
            client_size,
            client_buffer,
            128,
            port_buffer,
            128,
            NI_NUMERICHOST | NI_NUMERICSERV
            );

        std::cout << "ip:" << client_buffer << std::endl;
        std::cout << "port:" << port_buffer << std::endl;
        printf("%.*s", bytes_received, buff);


    }

    close(sock);

    return 0;
}

Título: Re:servidor y cliente udp [simple]
Publicado por: ANTRAX en Enero 09, 2026, 02:20:46 PM
Muy buenooo!!

Muchas gracias por compartirlo!

Saludos,
ANTRAX