【问题标题】:Segment Violation socket in CC中的段冲突套接字
【发布时间】:2020-06-27 00:57:09
【问题描述】:

我正在开发一个套接字,它是一个 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);
}

但是当我尝试连接我的客户端和我的服务器时,它会显示标题消息并退出。

【问题讨论】:

  • 你从未为d分配内存。
  • 为什么d 需要是指针?使用struct Datos d; 构建结构。
  • fflush(stdin); 具有未指定的行为,在 fgets() 之后不需要。
  • 通常的嫌疑人。未能正确和完整地处理来自系统调用的结果,调用需要 NUL 终止字符数组且没有保证终止符的 lib 函数,滥用 TCP 流。

标签: c sockets tcp tcpclient


【解决方案1】:

除了在recv()中使用之前为d分配内存之外,showError()函数问题也会导致错误。

在这个函数中,你必须检查 switch case 的默认值。

这里是问题解决部分

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 ");
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2010-12-12
    • 1970-01-01
    相关资源
    最近更新 更多