Objective c 获取连接到套接字的主机的主机名
我正在使用Apple的TCPServer类在侦听传入连接时打开一个套接字。以下是当有人连接到侦听套接字时调用的回调:Objective c 获取连接到套接字的主机的主机名,objective-c,ios,sockets,hostname,tcpserver,Objective C,Ios,Sockets,Hostname,Tcpserver,我正在使用Apple的TCPServer类在侦听传入连接时打开一个套接字。以下是当有人连接到侦听套接字时调用的回调: static void TCPServerAcceptCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { TCPServer *server = (TCPServer *)info; if (kCFSocketAccep
static void TCPServerAcceptCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
TCPServer *server = (TCPServer *)info;
if (kCFSocketAcceptCallBack == type) {
// for an AcceptCallBack, the data parameter is a pointer to a CFSocketNativeHandle
CFSocketNativeHandle nativeSocketHandle = *(CFSocketNativeHandle *)data;
uint8_t name[SOCK_MAXADDRLEN];
socklen_t namelen = sizeof(name);
NSData *peer = nil;
if (0 == getpeername(nativeSocketHandle, (struct sockaddr *)name, &namelen)) {
peer = [NSData dataWithBytes:name length:namelen];
}
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreatePairWithSocket(kCFAllocatorDefault, nativeSocketHandle, &readStream, &writeStream);
if (readStream && writeStream) {
CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
[server handleNewConnectionFromAddress:peer inputStream:(NSInputStream *)readStream outputStream:(NSOutputStream *)writeStream];
} else {
// on any failure, need to destroy the CFSocketNativeHandle
// since we are not going to use it any more
close(nativeSocketHandle);
}
if (readStream) CFRelease(readStream);
if (writeStream) CFRelease(writeStream);
}
}
有没有办法获取正在连接的设备的主机名?
当做
科萨
[编辑]
我尝试了类似这样的方法来提取ip:
struct sockaddr_in *s = (struct sockaddr_in*)name;
char *ipstr = malloc(INET_ADDRSTRLEN);
ipstr = inet_ntoa(s->sin_addr);
NSLog(@"ip = %s", ipstr);
但它给了我0.0.0.0
[编辑]
仍在努力,但仍然没有成功。根据苹果的文档,地址参数为:
一种CFData对象,包含适合于s协议族的结构sockaddr的内容(例如,中的结构sockaddr_或中的结构sockaddr_),用于标识s连接到的远程地址。除kCFSocketAcceptCallBack和kCFSocketDataCallBack回调外,此值为NULL
然而,我无法提取除132.20.0.1之外的任何其他IP(这显然不是我期望的IP),我真的很困惑,如果有人能帮我解决这个问题,那就太好了 在尝试按照您的方式获取地址后,我想出了一个适用于我的代码的轻微变体。如果您正在处理IPv6地址,则此代码正常工作,但很容易更改为使用IPv4。无论如何,我必须更改代码才能同时使用这两种代码
- (void)getPublicClientAddress {
// Get public IP from stream
// Get hands on appropriate data structures via the socket number
CFSocketNativeHandle nativeSocketHandle = _socketnumber;
uint8_t name[SOCK_MAXADDRLEN];
socklen_t namelen = sizeof(name);
NSData *peer = nil;
if (0 == getpeername(nativeSocketHandle, (struct sockaddr *)name, &namelen)) {
peer = [NSData dataWithBytes:name length:namelen];
}
// TODO distiguish between ipv4 and ipv6
struct sockaddr_in6 *s = (struct sockaddr_in6*)name;
// convert ip to string
char *ipstr = malloc(INET6_ADDRSTRLEN);
struct in6_addr *ipv6addr = &s->sin6_addr; // used pointer here, but that really should make no difference
inet_ntop(AF_INET6, ipv6addr, ipstr, sizeof(ipstr)); // used a different function here
// convert port to int
int portnumber = s->sin6_port;
// Save in properties
_publicIP = [NSString stringWithFormat:@"%s", ipstr];
_publicPort = [NSString stringWithFormat:@"%d", portnumber];
}
因此,这段代码对我很有用,我希望它能帮助那些在搜索答案时偶然发现这篇文章的人。TCPServer的定义是什么?TCPServer是持有这种静态方法的类。它可以在iOS开发中心的“witap”示例项目中找到。这个回调在哪里使用?我只能看到
TCPServerDelegate
的用法:“[server handleNewConnectionFromAddress:peer-inputStream:(NSInputStream*)readStream-outputStream:(NSOutputStream*)writeStream];”调用委托方法。您知道是否有其他方法可以从这里获取传入连接的主机名吗?代码的其余部分不包含任何有用的东西。