Reputation: 2026
I am connecting to a hostname using CFStreams in my iOS app like:
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
outputStream = (__bridge NSOutputStream *)writeStream;
inputStream = (__bridge NSInputStream *)readStream;
But I want to know how I can get the remote IP address of host
from the stream?
Upvotes: 1
Views: 246
Reputation: 2026
You can get the file descriptor (which Apple calls the "Native Handle") and with that use your typical POSIX networking commands to get the address:
Get the file descriptor from the stream:
CFDataRef handleData = (CFDataRef)CFReadStreamCopyProperty((__bridge CFReadStreamRef) inputStream, kCFStreamPropertySocketNativeHandle);
long length = CFDataGetLength(handleData);
uint8_t * buffer = malloc(length);
CFDataGetBytes(handleData, CFRangeMake(0, length), buffer);
int sock_fd = (int)*buffer;
Get the remote address for that file descriptor:
struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
getpeername(socket, (struct sockaddr *)&addr, &addr_len);
NSString * remoteAddr;
if (addr.ss_family == AF_INET) {
char addressString[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &((struct sockaddr_in *)&addr)->sin_addr, addressString, INET_ADDRSTRLEN);
remoteAddr = [[NSString alloc] initWithUTF8String:addressString];
} else if (addr.ss_family == AF_INET6) {
char addressString[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr, addressString, INET6_ADDRSTRLEN);
remoteAddr = [[NSString alloc] initWithUTF8String:addressString];
}
free(buffer);
// Now you have remoteAddr which will be a
// string representation of a IPv4 or IPv6 address!
NSLog(@"Remote Address: %@", remoteAddr);
Upvotes: 2