Я получаю сообщение «Ошибка сегментации (дамп ядра)» при запуске программы, связанной с сокетом - PullRequest
0 голосов
/ 11 июля 2019

Я погуглил, когда произошла ошибка сегментации, но я не могу исправить ошибку в своем коде. Я использую функцию выбора, чтобы узнать, какие файловые дескрипторы доступны для чтения. Я довольно нов в программировании сокетов вc и я не могу понять назначение структуры socklen_t, когда у нас есть макросы для длины адреса ipv4.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>

#define PORT "9034"

int main()
{
    fd_set master,read_fds;
    int file_descriptor,new_fd,server,yes=1,error,fd_max,i;
    char ip[INET_ADDRSTRLEN],data[1024];
    struct addrinfo hints,*p;
    struct sockaddr_in addr;
    socklen_t addrlen; //?
    memset(&hints,0,sizeof(struct addrinfo));
    FD_ZERO(&master);
    FD_ZERO(&read_fds);
    hints.ai_family=AF_INET;
    hints.ai_socktype=SOCK_STREAM;
    hints.ai_protocol=AI_PASSIVE;
    file_descriptor=getaddrinfo(NULL,PORT,&hints,&p);
    printf("%s",inet_ntop(AF_INET,p->ai_addr,ip,addrlen));
    server=socket(p->ai_family,p->ai_socktype,p->ai_protocol);
    setsockopt(server,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int));
    listen(server,5);
    FD_SET(server,&master);
    fd_max=server;
    while (1)
    {
        read_fds=master;
        select(fd_max+1,&read_fds,NULL,NULL,NULL);
        for(i=0;i<fd_max;i++)
        {
            if(i==server)
            {
                new_fd=accept(server,(struct sockaddr *)&addr,&addrlen);
                FD_SET(new_fd,&master);
                printf("Connected to the client %s on socket %d",inet_ntop(AF_INET,(struct sockaddr *)&addr,ip,INET_ADDRSTRLEN),new_fd);
                if(new_fd>fd_max)
                fd_max=new_fd;
            }
            else
            {
                recv(i,data,sizeof(data),0);
                printf("%s",data);                
            }   
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 11 июля 2019

Здесь происходит сбой:

file_descriptor=getaddrinfo(NULL,PORT,&hints,&p);
printf("%s",inet_ntop(AF_INET,p->ai_addr,ip,addrlen));

Обратите внимание, что во второй строке вы разыменовываете указатель p - но p равен NULL, поскольку getaddrinfo() не выполнен и не установленэто допустимый адрес, поэтому попытка разыменования вызывает неопределенное поведение, и в этом случае вызывает сбой.

Кстати, я смог отладить это, вставив временные операторы printf() в различных точках программы ивидя, что (или не) было напечатано.В частности:

 printf("k1\n");
     file_descriptor=getaddrinfo(NULL,PORT,&hints,&p);
 printf("k2 file_descriptor=%i p=%p\n", file_descriptor, p);
     printf("%s",inet_ntop(AF_INET,p->ai_addr,ip,addrlen));
 printf("k3\n");

... когда я бегал с таким кодом, я видел такой вывод:

 k1
 k2 file_descriptor=12 p=0x0
 Segmentation fault: 11

... что делает проблему очевидной - p былоNULL (он же 0x0) в строке "k2", и сбой произошел до того, как была напечатана строка "k3", так что сбой был определенно в вашем вызове printf() и из-за разыменования NULL-указателя.

Чтобы исправить сбой, вам нужно проверить возвращаемое значение getaddrinfo(), чтобы убедиться, что он вернул ноль / успех, и обработать его корректно, когда он возвращает ненулевое значение / ошибка, вместо того, чтобы просто предполагать, что он всегда будет успешным,(как правило, это нужно делать со всеми вызовами функций, которые возвращают значение успеха / сбоя)

0 голосов
/ 11 июля 2019

Согласно вашему комментарию, некоторые из используемых вами утилит могут быть определены неправильно.Для каких библиотек вы тянете в свой проект, убедитесь, что вы используете правильные (и соответствующие) заголовочные файлы.то есть для разработки POSIX предлагается следующее:

/* According to POSIX.1-2001 */
#include <sys/select.h>

( Подробнее об этом )

Я не вижу select.hфайл, упомянутый в ваших #include заявлениях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...