Конвертировать NSData в NSString - PullRequest
1 голос
/ 31 января 2010

Я получаю успешное соединение с сервером и выполняю функцию обратного вызова:

Я пытаюсь получить имя хоста и распечатать его на моей консоли:

if(theType == kCFSocketConnectCallBack){
        NSLog(@"Connection is accepted");
        CFSocketNativeHandle nativeSocket = CFSocketGetNative(theSocket);
        uint8_t name[SOCK_MAXADDRLEN];
        socklen_t namelen = sizeof(name);
        NSData *peer = nil;
        if (getpeername(nativeSocket, (struct sockaddr *)name, &namelen) == 0) {
            peer = [NSData dataWithBytes:name length:namelen];
            NSString *string = [[NSString alloc] initWithData:peer encoding:NSUTF8StringEncoding];
            NSLog(@"IP adress of connected peer: %@", string);
        } 

Когда я запускаю приложение в режиме отладки, я вижу значение IP-адреса, назначенное для имени, поэтому оно успешно получает имя, каждое значение равно uint8_t .. Длина сверстника показывает мне 16; Моя проблема, преобразовывая это в NSData тогда NSString ...

Выход: 2010-01-31 13: 57: 58.671 IP-адрес подключенного узла: (ноль)

Моя строка выводится как NULL,

Любой совет приветствуется, спасибо ....

Ответы [ 3 ]

2 голосов
/ 31 января 2010

getpeername () не возвращает имя хоста удаленной стороны; возвращает адрес:

$ man getpeername

...

DESCRIPTION
     The getpeername() function returns the address of the peer connected to
     the specified socket.

Вы хотите getnameinfo ():

$ man getnameinfo

...

DESCRIPTION
     The getnameinfo() function is used to convert a sockaddr structure to a
     pair of host name and service strings.  It is a replacement for and pro-
     vides more flexibility than the gethostbyaddr(3) and getservbyport(3)
     functions and is the converse of the getaddrinfo(3) function.

или gethostbyaddr ():

$ man gethostbyaddr

...

DESCRIPTION
     The getaddrinfo(3) and getnameinfo(3) functions are preferred over the
     gethostbyname(), gethostbyname2(), and gethostbyaddr() functions.

     The gethostbyname(), gethostbyname2() and gethostbyaddr() functions each
     return a pointer to an object with the following structure describing an
     internet host referenced by name or by address, respectively.
2 голосов
/ 01 февраля 2010

sockaddr - это структура, а не просто определение типа для массива символов. Вам нужно передать getpeername адрес фактической sockaddr структуре, а затем построить строку из поля sa_data этой структуры - и это предполагает, что sa_data на самом деле строка для вашего типа адреса, документация не предполагает, что вы действительно можете рассчитывать. Как говорит другой ответ, это не тот вызов, который вам нужен, если ваша цель - получить строковое представление для распечатки.

(Кроме того, вам вообще не нужны NSData для перехода от массива символов к строке NSSt; вы можете просто использовать -[NSString initWithBytes:length:encoding:])

1 голос
/ 31 января 2010

Сначала убедитесь, что peer содержит экземпляр NSData, который имеет ненулевую длину.

Если это так, то наиболее вероятная проблема состоит в том, что данные не соответствуют указанной кодировке, что приводит к сбою кодировки NSString и возвращению нулевой строки. Если это проблема с кодировкой, на NSString есть API для выполнения кодирования с потерями. Даже если потери не приемлемы в вашем окончательном решении, этот путь может быть очень полезен для выяснения того, что идет не так.

Это предполагает, что NULL вы действительно имеете в виду nil. Было бы полезно вставить точный вывод строки журнала.

...