software meaning mac descargar apple iphone bonjour

meaning - iPhone: Bonjour NSNetService dirección IP y puerto



bonjour windows 10 (3)

El NSNetService que recupera en la devolución de llamada no está listo para ser utilizado. Tienes que llamar al siguiente método para obtener direcciones para ello:

- (void)resolveWithTimeout:(NSTimeInterval)timeout;

Implemente el método de delegado NSNetService para averiguar cuándo se resuelve:

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

En ese momento, debe haber al menos una dirección en el servicio.

Además, ¡preste atención a leer atentamente la documentación y el archivo de encabezado! Hay una cierta complejidad en el tema aquí que he pasado por alto.

Disculpe mi estado de iPhone / Objective-C novato por favor!

He encontrado mi servidor HTTP utilizando NSNetServiceBrowser, pero ahora solo quiero que se encuentre la dirección IP y el puerto del servicio.

Tengo algo como lo siguiente en mi método de delegado:

NSNetService* server = [serverBrowser.servers objectAtIndex:0]; NSString *name = nil; NSData *address = nil; struct sockaddr_in *socketAddress = nil; NSString *ipString = nil; int port; uint i; for (i = 0; i < [[server addresses] count]; i++) { name = [server name]; address = [[server addresses] objectAtIndex:i]; socketAddress = (struct sockaddr_in *) [address bytes]; ipString = [NSString stringWithFormat: @"%s", inet_ntoa (socketAddress->sin_addr)]; port = socketAddress->sin_port; NSLog(@"Server found is %s %d",ipString,port); }

pero el bucle for nunca se ingresa, aunque se llame al delegado. ¿Algunas ideas? ¡Gracias!


Me doy cuenta de que este es un hilo viejo, pero también me he topado con esto. Hay algunos problemas con el código de arriba:

  1. No es un experto en IPv6. Como mínimo, debería detectar y descartar las direcciones IPv6 si el resto de su aplicación solo puede manejar direcciones v4, pero lo ideal es que esté preparado para transferir ambas familias de direcciones en sentido ascendente.

  2. La asignación de puertos generará valores incorrectos para los procesadores Intel. Necesitas usar htons para arreglar eso.

  3. Como Andrew señaló anteriormente, la iteración debería usar el bucle mejorado para.

  4. (EDITAR: Se agregó esto) Como se señaló en otro hilo relacionado, se desaconseja el uso de inet_ntoa a favor de inet_ntop .

Al juntar todo esto, obtienes:

char addressBuffer[INET6_ADDRSTRLEN]; for (NSData *data in self.addresses) { memset(addressBuffer, 0, INET6_ADDRSTRLEN); typedef union { struct sockaddr sa; struct sockaddr_in ipv4; struct sockaddr_in6 ipv6; } ip_socket_address; ip_socket_address *socketAddress = (ip_socket_address *)[data bytes]; if (socketAddress && (socketAddress->sa.sa_family == AF_INET || socketAddress->sa.sa_family == AF_INET6)) { const char *addressStr = inet_ntop( socketAddress->sa.sa_family, (socketAddress->sa.sa_family == AF_INET ? (void *)&(socketAddress->ipv4.sin_addr) : (void *)&(socketAddress->ipv6.sin6_addr)), addressBuffer, sizeof(addressBuffer)); int port = ntohs(socketAddress->sa.sa_family == AF_INET ? socketAddress->ipv4.sin_port : socketAddress->ipv6.sin6_port); if (addressStr && port) { NSLog(@"Found service at %s:%d", addressStr, port); } } }


Remix de la respuesta aceptada en una categoría:

NSNetService + Util.h

#import <Foundation/Foundation.h> @interface NSNetService (Util) - (NSArray*) addressesAndPorts; @end @interface AddressAndPort : NSObject @property (nonatomic, assign) int port; @property (nonatomic, strong) NSString *address; @end

NSNetService + Util.m

#import "NSNetService+Util.h" #include <arpa/inet.h> @implementation NSNetService (Util) - (NSArray*) addressesAndPorts { // this came from http://.com/a/4976808/8047 NSMutableArray *retVal = [NSMutableArray array]; char addressBuffer[INET6_ADDRSTRLEN]; for (NSData *data in self.addresses) { memset(addressBuffer, 0, INET6_ADDRSTRLEN); typedef union { struct sockaddr sa; struct sockaddr_in ipv4; struct sockaddr_in6 ipv6; } ip_socket_address; ip_socket_address *socketAddress = (ip_socket_address *)[data bytes]; if (socketAddress && (socketAddress->sa.sa_family == AF_INET || socketAddress->sa.sa_family == AF_INET6)) { const char *addressStr = inet_ntop( socketAddress->sa.sa_family, (socketAddress->sa.sa_family == AF_INET ? (void *)&(socketAddress->ipv4.sin_addr) : (void *)&(socketAddress->ipv6.sin6_addr)), addressBuffer, sizeof(addressBuffer)); int port = ntohs(socketAddress->sa.sa_family == AF_INET ? socketAddress->ipv4.sin_port : socketAddress->ipv6.sin6_port); if (addressStr && port) { AddressAndPort *aAndP = [[AddressAndPort alloc] init]; aAndP.address = [NSString stringWithCString:addressStr encoding:kCFStringEncodingUTF8]; aAndP.port = port; [retVal addObject:aAndP]; } } } return retVal; } @end @implementation AddressAndPort @end

[Sí, no tengo miedo de crear muchas instancias de NSObject ...]