分段错误(核心转储)错误 C linux 套接字

Posted

技术标签:

【中文标题】分段错误(核心转储)错误 C linux 套接字【英文标题】:Segmentation fault (core dumped) error C linux sockets 【发布时间】:2014-04-22 04:04:20 【问题描述】:

请帮助我这个程序应该通过套接字发送文件,但是当我运行它时它显示错误分段错误。 服务器使用线程来实现多个客户端。 谢谢!这是我的最后一个项目!

这是服务器代码:

#include<stdio.h>
#include<string.h>    
#include<stdlib.h>    
#include<sys/socket.h>
#include<arpa/inet.h> 
#include<unistd.h>    
#include<pthread.h> 
static const int BUFFER_SIZE = 1024;
//CREAR HILO
void *connection_handler(void *);

int main(int argc , char *argv[])

    int socket_desc , client_sock , c , *new_sock;
    struct sockaddr_in server , client;


    //CREAR SOCKET
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1) //ERROR AL CREAR EL SOCKET
    
    printf("ERROR AL CREAR EL SOCKET");
    
    puts("SOCKET CREADO"); //SOCKET CREADO

    //VALORES DEL SOCKET
    server.sin_family = AF_INET; //SOCKET IP
    server.sin_addr.s_addr = INADDR_ANY; // EJECUTAR CON LA IP DE LA MAQUINA ACTUAL
    server.sin_port = htons(9999);//PUERTO

    //ASOCIAR SOCKET A UN PUERTO
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    
    // ERROR EN LA ASOCIACION
    perror("ERROR AL ASOCIAR EL SOCKET AL PUERTO DEL SERVER");
    return 1;
    
    puts("PUERTO CREADO EN EL SERVER CORRECTAMENTE");

    //MODO ESCUCHA CONEXIONES ENTRANTES
    listen(socket_desc , 3); // TRES CONEXIONES PERMITIDAS

    //ACEPTA CONEXIONES ENTRANTES
    puts("A LA ESPERA DE CONEXIONES ENTRANTES");
    c = sizeof(struct sockaddr_in);
    while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) // CONEXION ACEPTADA 
    
    puts("CONEXION ACEPTADA");

    pthread_t sniffer_thread;
    new_sock = malloc(1);
    *new_sock = client_sock;

    if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) new_sock) < 0)
    
        perror("NO SE PUDO CREAR EL THREAD");
        return 1;
    


    

    if (client_sock < 0)
    
    perror("FALLO");
    return 1;
    

    return 0;


/*
 * HABILITAR VARIAS CONEXIONES
 * */
void *connection_handler(void *socket_desc)

    //SOCKET
    int sock = *(int*)socket_desc;     
        char buf[BUFFER_SIZE];

        while(1)
         

       FILE * fpIn = fopen("/mnt/SHARED/La.Lista.De.Schindler.Latino.avi", "r"); //ARCHIVO A ENVIAR
           ssize_t bytesRead = fread(buf, 1, sizeof(buf), fpIn);
           if (bytesRead <= 0) break;  // EOF

           printf("Se han leido %i bytes del archivo, enviandolos ...\n", (int)bytesRead);
           if (send(sock, buf, bytesRead, 0) != bytesRead) // ENVIAR EN EL SOCKET
           
              perror("AL ENVIAR!!");
              break;
           
        

    //LIBERAR EL SOCKET
    free(socket_desc);

    return 0;

这是客户端代码

#include<stdio.h> //printf
#include<string.h>    //strlen
#include<sys/socket.h>    //socket
#include<arpa/inet.h> //inet_addr

static const int BUFFER_SIZE = 16*1024;

int main(int argc , char *argv[])

    int sock;
    struct sockaddr_in server;

    //CREAR SOCKET
    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1)
    
        printf("NO SE PUDO CREAR EL SOCKET");
    
    puts("EL SOCKET FUE CREADO");

    server.sin_addr.s_addr = inet_addr("127.0.0.1"); // IP SERVER
    server.sin_family = AF_INET;//SOCKET IP
    server.sin_port = htons(9999); //PUERTO

    //CONECTAR AL SERVER
    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
    
        perror("LA CONEXION FALLO");
        return 1;
    

    puts("CONEXION ESTABLECIDA\n");

            FILE * fpIn = fopen("/home/soporte/PELI", "w");//ARCHIVO RECIBIDO
            if (fpIn)
            
               char buf[BUFFER_SIZE];
               while(1)
               
                  ssize_t bytesReceived = recv(sock, buf, sizeof(buf), 0);
                  if (bytesReceived < 0) perror("RECEPCION");  //ERROR AL RECIBIR
                  if (bytesReceived == 0) break;   //SE CIERRA LA CONEXION AL FINAL DEL ARCHIVO

                  printf("Se han recibido %i bytes desde la red, escribiendo a un archivo...\n", (int) bytesReceived);
                  if (fwrite(buf, 1, bytesReceived, fpIn) != (size_t) bytesReceived)
                  
                     perror("fwrite");
                     break;
                  
               

               fclose(fpIn);
            
            else printf("Error, no se pudo abrir el archivo [%s]\n", "/home/soporte/ESTEBAN");

    close(sock);
    return 0;

【问题讨论】:

Seg 故障在哪里?您尝试过使用 GDB 吗? Segmentation fault 在服务器端还是客户端在哪里? 如果bytesReceived &lt; 0 你不应该继续fwrite 仔细阅读 recv()/send() 的手册页并了解这两个函数不一定接收/发送尽可能多的字节,但很少。因此,循环计算此类调用,直到所有预期的数据都已接收/发送是一个好主意,而不是说必要的必要性。 【参考方案1】:

在您的服务器代码中,您在while....loop 中不断打开您的文件。有什么目的吗?

您在服务器中的处理程序如下所示

/*
 * HABILITAR VARIAS CONEXIONES
 * */
void *connection_handler(void *socket_desc)

       //SOCKET
        int sock = *(int*)socket_desc;     
        char buf[BUFFER_SIZE];
        FILE * fpIn = fopen("/mnt/SHARED/La.Lista.De.Schindler.Latino.avi", "r"); 
        while(1)
         

          //ARCHIVO A ENVIAR
           ssize_t bytesRead = fread(buf, 1, sizeof(buf), fpIn);
           if (bytesRead <= 0) break;  // EOF

           printf("Se han leido %i bytes del archivo, enviandolos ...\n", (int)bytesRead);
           if (send(sock, buf, bytesRead, 0) != bytesRead) // ENVIAR EN EL SOCKET
           
              perror("AL ENVIAR!!");
              break;
           
        

    //LIBERAR EL SOCKET
    free(socket_desc);
    fclose(fpIn);
    return 0;

【讨论】:

【参考方案2】:

改变

new_sock = malloc(1);

new_sock = malloc(sizeof(*new_sock));

并确保在 connection_handler 函数中,当您尝试打开文件时,您确实做到了。 (fpIn > 0) 否则,你应该打破while。

【讨论】:

以上是关于分段错误(核心转储)错误 C linux 套接字的主要内容,如果未能解决你的问题,请参考以下文章

recvfrom 中的分段错误(已创建核心转储)

在Linux机器上运行C代码时出现分段错误(核心转储)[关闭]

使用 C (Ubuntu) 进行套接字编程中的分段错误

分段错误(核心转储)向 linux 发出窗口

为啥我在 C 中收到警告“分段错误,核心转储”

分析分段错误核心转储 (gdb)