Нарушение сегмента розетка в C - PullRequest
0 голосов
/ 15 марта 2020

Я разрабатываю сокет, который является tcp-клиентом и tcp-сервером, но я получаю нарушение сегмента, не знаю почему, поскольку я понял, что это может быть ошибкой при назначении памяти.

Код клиента:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


struct Datos{
    char ciudad[30];
    char tipoSensor[30];
    int medida;
    char ip[16];
};

void inicializarSocket(struct sockaddr_in *servidor);

int main()
{

    struct Datos *d;
    int sockfd;
    struct sockaddr_in servidor;
    char mensaje[100];
    int tamMensaje;
    socklen_t tam = sizeof(struct sockaddr);
    sockfd = socket(AF_INET, SOCK_STREAM,0);

    printf("Introduce la ciudad:\n");
    fgets(d->ciudad, 30, stdin);
    fflush(stdin);
    printf("Introduce el tipo de sensor:\n");
    fgets(d->tipoSensor,30, stdin);
    fflush(stdin);
    printf("Intoduce el valor:\n");
    scanf("%d", &d->medida);


    if (sockfd == -1)
    {
        perror("Error en el socket. \n");
        exit(-1);
    }

    inicializarSocket(&servidor);


    if(connect(sockfd,(struct sockaddr*)&servidor, sizeof(struct sockaddr)) == -1)
    {
        perror("Error conexion. \n");
        exit(-1);
    }
    printf("Conexion aceptada. Enviando\n");
    if(send(sockfd, d, sizeof(struct Datos),0)==-1){
        perror("Error envio\n");
        exit(-1);
    }
    printf("Esperando confirmacion de llegada\n"); fflush(stdout);


    if( recv(sockfd,mensaje,100,0)  == -1)
    {
        perror("Error en la recepcion. \n");
        exit(-1);
    }

    printf("%s\n", mensaje); fflush(stdout);

    close(sockfd);

}

void inicializarSocket(struct sockaddr_in *servidor){
    servidor->sin_family = AF_INET;
    inet_aton("127.0.0.1", &servidor->sin_addr);
    servidor->sin_port = htons(20000);
    memset(&servidor->sin_zero, '\0', 8);
}

Это мой сервер:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

struct Datos{
    char ciudad[30];
    char tipoSensor[30];
    int medida;
    char ip[16];
};

const char* showError(int error);
int checkPolucion(int dato);
int checkHumedad(int dato);
int checkTemperatura(int dato);
int checkSensor(char sensor[30], int dato);
void setSocketServer(struct sockaddr_in *servidorEscucha);
void setClienteA(struct sockaddr_in *servidorEscucha);

int main()
{
    struct Datos *d;
    int sockfd, sockfdCliente;
    struct sockaddr_in servidorEscucha, cliente, clienteUDP;
    char mensaje[100];
    socklen_t tam = sizeof(struct sockaddr);
    int errorSensor;

    if ( (sockfd = socket(AF_INET, SOCK_STREAM,0)) == -1)
    {
        perror("Error al crear el socket. \n");
        exit(-1);
    }

    setSocketServer(&servidorEscucha);
    memset(&servidorEscucha.sin_zero, '\0', 8);

    if( bind(sockfd, (struct sockaddr *) &servidorEscucha, sizeof(struct sockaddr)) == -1 )
    {
        perror("Error en el bind. \n");
        exit(-1);
    }

    if(listen(sockfd, 10) == -1){
        perror("Error en el listen\n");
        exit(-1);
    }
    while(1)
    {
        printf("Esperando a un cliente \n");            

        if((sockfdCliente=accept(sockfd,(struct sockaddr *)&cliente, &tam))==-1){
            perror("Error en el accept");
            exit(-1);
        }

        else{
            printf("HOLA");
            if(recv(sockfdCliente,d, sizeof(struct Datos),0)==-1){
                perror("Error recibir mensaje");
            }       
            printf("Mensaje recibido");

            errorSensor = checkSensor(d->tipoSensor, d->medida);
            errorSensor = 0;            
            strcpy(mensaje, showError(errorSensor));
            printf("Enviando mensaje\n"); fflush(stdout);
            if( send(sockfdCliente,mensaje,100,0) == -1)
                {
                    perror("Error al enviar.\n");
                    exit(-1);
                }
        }
        close(sockfdCliente);
    }

    close(sockfd);

}



int checkSensor(char sensor[30], int dato){
    int error;
    printf("HE EsTADO AQUI");
    printf("%s", sensor);fflush(stdin);
    if(strcmp("polucion\n",sensor)==0){
        error = checkPolucion(dato);
    }
    else if(strcmp(sensor, "temperatura")==0){
        error = checkTemperatura(dato);
    }
    else if(strcmp(sensor,"humedad")==0){
        error = checkHumedad(dato);
    }
    else{
        error = -4;
    }
    return error;

}

int checkPolucion(int dato){
    printf("CHECKED");
    if(dato>=0 && dato <= 200){
        return 0;
    }
    return -1;
}

int checkTemperatura(int dato){
    if(dato>=-20 && dato <= 50){
        return 0;
    }
    return -2;
}
int checkHumedad(int dato){
    if(dato>=0 && dato <= 100){
        return 0;
    }
    return -3;
}

const char* showError(int error){
    switch(error){
        case -1:
            return("Dato no adecaudo para la polucion. Debe estar entre 0 y 200");
        case -2:
            return("Dato no adecaudo para la temperatura. Debe estar entre -20 y 50");
        case -3:
            return("Dato no adecaudo para la humedad. Debe estar entre 0 y 100");
        case -4:
            return("No existe dicho sensor");
    }
}

void setSocketServer(struct sockaddr_in *servidorEscucha){
    servidorEscucha->sin_family = AF_INET;
    inet_aton("127.0.0.1", &servidorEscucha->sin_addr);
    servidorEscucha->sin_port = htons(20000);
}

Но когда я пытаюсь подключить мой клиент и мой сервер это говорит сообщение заголовка и выхода.

1 Ответ

0 голосов
/ 16 марта 2020

Помимо выделения памяти для d перед использованием в recv(), проблема с функцией showError() вызывает ошибку.

В этой функции необходимо проверить значение по умолчанию для регистра переключателя.

Вот раздел решения проблем

d=malloc(sizeof *d);

if(d==NULL){
    printf("Memory allocation faild return\n");
    exit(1);
}

if(recv(sockfdCliente, d, sizeof(struct Datos), 0)==-1){
   perror("Error recibir mensaje");
}

showError ()

switch(error){
        case -1:
            return("Dato no adecaudo para la polucion. Debe estar entre 0 y 200");
        case -2:
            return("Dato no adecaudo para la temperatura. Debe estar entre -20 y 50");
        case -3:
            return("Dato no adecaudo para la humedad. Debe estar entre 0 y 100");
        case -4:
            return("No existe dicho sensor");
        default: return("Default ");
    }
...