Ejemplos de Sockets AF_INET en C: Stream (TCP) y Datagrama (UDP)

Otras materias6,15 KB

Ejemplo de programa cliente TCP (AF_INET, SOCK_STREAM)

Programa cliente de la familia AF_INET y del tipo stream que envía mensajes a un programa servidor. Las funciones leer_linea y escribir_linea están en el fichero comun.c.

void escribir_mensaje(int s);

main(){
    int sd;
    struct sockaddr_in dirser;

    if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
        perror("Error en la creación del socket");
        return 1;
    }

    dirser.sin_family = AF_INET;
    dirser.sin_port = htons(7000);
    dirser.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (connect(sd, (struct sockaddr*)&dirser, sizeof(dirser)) == -1)
        perror("");
    else
        escribir_mensaje(sd);

    close(sd);
}

void escribir_mensaje(int s){
    char mens[80], mensa[80];
    int nbytes;

    puts("Dame un mensaje");
    if ((nbytes = read(0, mens, sizeof(mens))) == -1){
        perror("Error al leer mensaje de teclado");
    }
    else {
        mens[nbytes - 1] = '\0';
        write(s, mens, strlen(mens) + 1);
        printf("Mensaje enviado %s\n", mens);
        read(s, mensa, sizeof(mensa));
        printf("Mensaje recibido %s\n", mensa);
    }
}

Ejemplo de programa servidor concurrente TCP (AF_INET, SOCK_STREAM)

Programa servidor concurrente de la familia AF_INET y del tipo stream que recibe mensajes de programas clientes, los visualiza y los vuelve a enviar al cliente junto con su PID. Las funciones leer_linea y escribir_linea están en el fichero comun.c. Para terminar el programa.

void recibir_mensaje(int s);

main(){
    struct sockaddr_in dirser, dircli; // dirección servidor, cliente
    int sd, nsd, longcli, ret, cont = 0, s; // descriptor de socket

    longcli = sizeof(dircli);

    if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
        perror("Error en la creación del socket");
        return 1;
    }

    dirser.sin_family = AF_INET;
    dirser.sin_port = htons(7000);
    dirser.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (bind(sd, (struct sockaddr *)&dirser, sizeof(dirser)) == -1){
        perror("Error al publicar la dirección del servidor");
        return 1;
    }

    if (listen(sd, s) == -1){
        perror("Error al crear la cola de atención al cliente");
        return 1;
    }

    while (1){
        printf("En espera de conexión PID %d\n", getpid());
        if ((nsd = accept(sd, (struct sockaddr*)&dircli, &longcli)) == -1){
            perror("Error al recibir la petición del cliente");
        }
        else {
            printf("Conexión aceptada\n");
            if ((ret = fork()) == -1){
                perror("Error al duplicar proceso");
            }
            else {
                if (ret == 0) {
                    close(1);
                    recibir_mensaje(nsd);
                    printf("Cliente %d atendido\n", cont + 1);
                    close(nsd);
                    exit(0);
                }
                else {
                    close(nsd);
                    cont++;
                }
            }
        }
    }
}

void recibir_mensaje(int s){
    char mens[80], mensa[80];
    int nbytes;

    if ((nbytes = read(s, mens, sizeof(mens))) == -1){
        perror("Error al leer mensaje del cliente");
    }
    else {
        mens[nbytes - 1] = '\0';
        printf("Mensaje recibido %s\n", mens);
        sprintf(mensa, "%s%d", mens, getpid());
        write(s, mensa, strlen(mensa) + 1);
    }
}

Servidor no orientado a conexión (AF_INET, SOCK_DGRAM)

Servidor interactivo de la familia AF_INET y de tipo datagrama que recibe mensajes de un cliente, los visualiza y los vuelve a enviar junto con el PID del servidor que le atendió (serudp).

main(){
    int sd;
    struct sockaddr_in dirser, dircli;
    char mens[80], mensa[80];
    int nb, longd = sizeof(dircli); // longitud dirección

    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
        perror("Error en la creación del socket");
        return 1;
    }

    dirser.sin_family = AF_INET;
    dirser.sin_port = htons(7000);
    dirser.sin_addr.s_addr = inet_addr("127.0.0.1");

    if (bind(sd, (struct sockaddr *)&dirser, sizeof(dirser)) == -1){
        perror("Error al publicar la dirección del servidor");
        return 1;
    }

    if ((nb = recvfrom(sd, mens, sizeof(mens), 0, (struct sockaddr*)&dircli, &longd)) == -1){
        perror("Error al recibir");
    }
    else {
        mens[nb - 1] = '\0';
        printf("Mensaje recibido %s\n", mens);
        sprintf(mensa, "PID servidor %d %s", getpid(), mens);
        sendto(sd, mensa, strlen(mensa) + 1, 0, (struct sockaddr *)&dircli, sizeof(dircli));
    }
}

Cliente UDP (AF_INET, SOCK_DGRAM)

main(){
    int sd;
    struct sockaddr_in dirser, dircli;
    char mens[80], mensa[80];
    int nb, longd = sizeof(dircli);

    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1){
        perror("Error en la creación del socket");
        return 1;
    }

    dircli.sin_family = AF_INET;
    dircli.sin_port = htons(0);
    dircli.sin_addr.s_addr = INADDR_ANY; // inet_addr("127.0.0.1");

    if (bind(sd, (struct sockaddr *)&dircli, sizeof(dircli)) == -1){
        perror("Error al adquirir la dirección del cliente");
        return 1;
    }

    dirser.sin_family = AF_INET;
    dirser.sin_port = htons(7000);
    dirser.sin_addr.s_addr = inet_addr("127.0.0.1");

    puts("Dame mensaje: ");
    if ((nb = read(0, mens, sizeof(mens))) == -1){
        perror("");
    }
    else {
        mens[nb - 1] = '\0';
        sendto(sd, mens, strlen(mens) + 1, 0, (struct sockaddr *)&dirser, sizeof(dirser));
        printf("Mensaje enviado %s\n", mens);
        if ((nb = recvfrom(sd, mensa, sizeof(mensa), 0, (struct sockaddr*)&dirser, &longd)) == -1){
            perror("Error al recibir");
        }
        else {
            mensa[nb - 1] = '\0';
            printf("Mensaje recibido del servidor %s\n", mensa);
        }
    }
}

Descargar

PDF Word HTML