2014-01-06 3 views
0

Я пытаюсь получить локальный IP-адрес, используемый для установления соединения. Однако по какой-то причине я не могу использовать getsockname, потому что он никогда не устанавливает какие-либо данные в моем sockaddr.getsockname() c не заданное значение

int fd = socket(/* params */); 
int len; 
struct sockaddr_in _self; 
/* Connection code, I know the connection succeeds and I've tested */ 
memset(&_self, 0, sizeof (struct sockaddr_in)); 
getsockname(fd, (struct sockaddr *) &_self, &len); 
printf("%s\n", inet_ntoa(_self.sin_addr); 

Однако, когда программа получает PRINTF, она всегда заканчивается из-за «ошибки Segmentation», который я думаю, когда он пытается получить доступ к памяти, что он не установил (я правильно в этом предположении ?) Если да, значит ли это, что getsockname терпит неудачу?

+1

вы можете проверить результат getsockanme (0: sucess, -1 error и errno). – mpromonet

+0

@mpromonet Я только что проверил, он возвращает 0 и errno также 0 – dreadiscool

+1

На странице man для getsockname говорится: Аргумент addrlen должен быть инициализирован, чтобы указать объем пространства (в байтах), на который указывает addr. Это не похоже, что len инициализируется в вашем коде. Не уверен, что это связано с вашей проблемой. – Quercus

ответ

2

Вы должны инициализирует len быть максимально допустимый размер перед тем вызова getsockname() (т.е. размер структуры). Это значение длины будет изменено по вызову, чтобы содержать фактическую длину.

Вы также должны убедиться, что дескриптор сокета связан. Кажется, что ваш тест указывает на установленный сеанс, но код неясен тем, что он содержит только вызов socket().

В качестве базовой линии, используют следующую программу:

#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

int main (void) { 
    int fd = socket (AF_INET, SOCK_STREAM, 0); 
    struct sockaddr_in _self; 
    int len = sizeof (_self); 

    memset (&_self, 0, len); 
    bind(fd, (struct sockaddr *) &_self, len); 

    memset (&_self, 42, len); 
    getsockname (fd, (struct sockaddr *) &_self, &len); 
    printf ("%s\n", inet_ntoa (_self.sin_addr)); 

    return 0; 
} 

Это выводит 0.0.0.0, как и ожидалось.

+0

Я изменил его, чтобы сказать int len ​​= sizeof (struct sockaddr_in) ;, и он все еще не работает, поэтому я предполагаю, что я сделал что-то неправильно. Что вы подразумеваете под максимальным разрешенным размером? – dreadiscool

+1

@ user1772510, вот что я имел в виду. Однако я бы предложил опубликовать более полный пример, поскольку тот, который вы указали, имеет синтаксические ошибки. Лучше всего было бы предоставить полный минимальный пример, демонстрирующий проблему. Нет смысла в насмехаться :-) – paxdiablo

+0

Спасибо за вашу помощь! Я получил его работу – dreadiscool

Смежные вопросы