inet_ntop: на устройстве не осталось места - PullRequest
2 голосов
/ 11 февраля 2012

Привет! Я создал функцию, которая принимает принятый sockFD в качестве входных данных и выводит IP-адрес в форме представления в строку. Функция работает нормально, пока я не собираюсь упаковывать строку с помощью вызова из inet_ntop, который возвращает нулевой указатель и, таким образом, выдает ошибку. Ошибка выглядит как «Нет места на устройстве», чего я не понимаю, так как у меня много оперативной памяти. В любом случае ниже я использую функцию.

void getTheirIp(int s, char *ipstr){ // int s is the incoming socketFD, ipstr points the the calling
                     // functions pointer.
    socklen_t len;
    struct sockaddr_storage addr;
    len = sizeof(addr);          //I want to store my address in addr which is sockaddr_storage type
    int stat;
    stat = getpeername(s, (struct sockaddr*)&addr, &len); // This stores addrinfo in addr
printf("getTheirIP:the value of getpeername %d\n",stat);
    // deal with both IPv4 and IPv6:
    if ((stat=addr.ss_family) == AF_INET) { // I get the size of the sock first
        printf("getTheirIP:the value of addr.ss_family is %d\n",stat);
        ipstr = malloc(INET_ADDRSTRLEN); // I allocate memory to store the string
        struct sockaddr_in *s = (struct sockaddr_in *)&addr; // I then create the struct sockaddr_in which
                                // is large enough to hold my address
       if(NULL == inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof(ipstr))){ // I then use inet_ntop to
        printf("getTheirIP:the value of inet_ntop is null\n");// retrieve the ip address and store
        perror("The problem was");              // at location ipstr
        }

    } else { // AF_INET6 this is the same as the above except it deals with IPv6 length
        ipstr = malloc(INET6_ADDRSTRLEN);
        struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
        inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof(ipstr));
    }
    printf("%s",ipstr);
}

Я не учел остальную часть программы, потому что она слишком велика, и я хочу сосредоточиться только на исправлении этой части. Однако ниже я покажу вам часть моего main (), который вызывает эту функцию.

newSock = accept(listenSock,(struct sockaddr *)&their_addr,&addr_size);
    char *someString;
    getTheirIp(newSock,someString);

Любая помощь будет великолепна. Спасибо!

Ответы [ 3 ]

7 голосов
/ 11 февраля 2012
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof(ipstr))

Что sizeof неверно, поскольку ipstr является указателем (он даст размер указателя, что-то вроде 4 или 8).Вам необходимо передать доступную длину буфера ipstr.

4 голосов
/ 11 февраля 2012

Как объяснено на man-странице, получение ENOSPC из inet_ntop означает:

Преобразованная строка адреса будет превышать размер, заданный размером.

В качестве аргумента размера вы указываете sizeof (ipstr), то есть объем памяти, который занимает указатель на символ ipstr . Вам нужно передать ему размер буфера.

1 голос
/ 11 февраля 2012

Для начала я бы использовал двойной указатель вместо:

void getTheirIp(int s, char **ipstr_pp)

Далее - это неправильно: ipstr - это 4-байтовый указатель:

inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof(ipstr)

Я думаювместо этого вы хотите "INET_ADDRSTRLEN".

Наконец, я бы посоветовал вам распечатать фактическую ошибку #.Или, по крайней мере, вырезать / вставить полный текст perror () (который, я считаю, должен содержать ошибку #).

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