Технические вопросы и ответы QA1298

Решения могут возвратить адрес IPv6 у Пантеры

Q: Запускаясь в Mac OS X 10.3, моя функция обратного вызова Решения иногда возвращает sockaddr с IP-адресом 0.0.0.0. Что продолжается?

A: Запускаясь в Mac OS X 10.3, моя функция обратного вызова Решения иногда возвращает sockaddr с IP-адресом 0.0.0.0. Что продолжается?

Добрый день записи адреса IPv6 поддержек в Mac OS X 10.3 и позже, таким образом, эти 0.0.0.0 адреса являются фактически результатом парсинга sockaddr, как будто это был IPv4, когда фактически это - вероятно, IPv6. Так как Ваша распространенная служба может не поддерживать IPv6, Вы наиболее вероятно захотите проигнорировать все адреса IPv6. Вот некоторый код, демонстрирующий, как проигнорировать адреса IPv6 и для CFNetServices и для NSNetServices.

  Пример перечисления 1 функция обратного вызова Решения CFNetServices.

#include <CoreServices/CoreServices.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>


static void
MyResolveCallback(CFNetServiceRef service, CFStreamError* error, void* info)
{
  struct sockaddr * socketAddress;
  CFArrayRef addresses;
  char buffer[256];
  uint16_t port;
  int count;

  addresses = CFNetServiceGetAddressing(service);

  /* Search for the IPv4 addresses in the array. */
  for (count = 0; count < CFArrayGetCount(addresses); count++) {

    socketAddress = (struct sockaddr *)CFDataGetBytePtr(CFArrayGetValueAtIndex(addresses, count));

    /* Only continue if this is an IPv4 address. */
    if (socketAddress && socketAddress->sa_family == AF_INET) {

      if (inet_ntop(AF_INET, &((struct sockaddr_in *)
          socketAddress)->sin_addr, buffer, sizeof(buffer))) {

        port = ntohs(((struct sockaddr_in *)socketAddress)->sin_port);

        printf("IP Address = %s\n", buffer);
        printf("Port Number = %d\n", port);

        /* Now that you know the IP address and port number, you
        should attempt to connect to the service. If the connection
        succeeds, then cancel the Resolve operation. If the connection
        fails, keep the Resolve running just in case your Resolve
        callback gets called again with another IPv4 address, and then
        try connecting to the new address. */
      }
    }
  }

  return;
}

  Метод NSNetServices netServiceDidResolveAddress перечисления 2 В качестве примера.

#import <Foundation/Foundation.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <sys/types.h>
#import <sys/socket.h>


- (void)netServiceDidResolveAddress:(NSNetService *)sender {

  NSArray * addresses;
  struct sockaddr * socketAddress;
  char buffer[256];
  uint16_t port;
  int count;

  addresses = [sender addresses];

  /* Search for the IPv4 addresses in the array. */
  for (count = 0; count < [addresses count]; count++) {

    socketAddress = (struct sockaddr *)[[addresses objectAtIndex:count] bytes]; 

    /* Only continue if this is an IPv4 address. */
    if (socketAddress && socketAddress->sa_family == AF_INET) {

      if (inet_ntop(AF_INET, &((struct sockaddr_in *)
          socketAddress)->sin_addr, buffer, sizeof(buffer))) {

        port = ntohs(((struct sockaddr_in *)socketAddress)->sin_port);

        printf("IP Address = %s\n", buffer);
        printf("Port Number = %d\n", port);

        /* Now that you know the IP address and port number, you
        should attempt to connect to the service. If the connection
        succeeds, then cancel the Resolve operation. If the connection
        fails, keep the Resolve running just in case your Resolve
        callback gets called again with another IPv4 address, and then
        try connecting to the new address. */
      }
    }
  }

  return;
}


История версии документа


ДатаПримечания
10.01.2005

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

15.10.2003

Новый документ, объясняющий, почему Вы получаете IP-адрес 0.0.0.0 при разрешении службы Bonjour.