从NSStream,CFStream或Socket获取Objective-c中OSX上的对等IP地址和端口

我编写了一个服务器,它侦听特定端口上的传入tcp连接。 为了管理网络连接,我正在使用Streams(CFStream / NSStream)。 在建立连接时,我将有关此连接的所有信息保存在专用类的另一个实例中,该专用类也被设置为流的委托。

现在我想得到设备的公共IP,它通过已经建立的流向我发送消息,换句话说,我想存储流的对等体的IP。 我尝试了很多东西,但遗憾的是我只获得了空值。

是否有可能从所描述的表单的现有流中获取对等方的地址(ip和端口)?

这是我尝试过的一些代码:

CFDataRef peerAddress = CFSocketCopyPeerAddress(_sockRef); // _sockRef is saved when connection is established in listening callback and is not null 

我还尝试在侦听回调方法中直接获取信息:

 NSData *peer = nil; CFSocketNativeHandle nativeSocketHandle = *(CFSocketNativeHandle *)data; struct sockaddr *addressinfo = NULL; uint8_t name[SOCK_MAXADDRLEN]; socklen_t namelen = sizeof(addressinfo); int result = getpeername(nativeSocketHandle, addressinfo, &namelen); if (result == 0) { peer = [NSData dataWithBytes:name length:namelen]; } struct sockaddr_in *s = (struct sockaddr_in*)name; char *ipstr = malloc(INET_ADDRSTRLEN); ipstr = inet_ntoa(s->sin_addr); // is 0.0.0.0 :-( 

我尝试了另一种方法:

 _publicIP = CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)(_writeStream), kCFStreamPropertySocketRemoteHostName); 

为什么我总是得到空值? 谁能帮我?

先谢谢你!

好的,我现在想通了。 这就是我做的:

 - (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]; } if (_ipv6){ // If ipv6 is used struct sockaddr_in6 *socketaddress = (struct sockaddr_in6*)name; // convert ip to string char *ipstr = malloc(INET6_ADDRSTRLEN); struct in6_addr *ipv6addr = &socketaddress->sin6_addr; inet_ntop(AF_INET6, ipv6addr, ipstr, sizeof(ipstr)); // convert port to int int portnumber = socketaddress->sin6_port; // Save in properties _publicIP = [NSString stringWithFormat:@"%s", ipstr]; _publicPort = [NSString stringWithFormat:@"%d", portnumber]; } else { // If ipv4 is used struct sockaddr_in *socketaddress = (struct sockaddr_in*)name; // convert ip to string char *ipstr = malloc(INET_ADDRSTRLEN); struct in_addr *ipv4addr = &socketaddress->sin_addr; ipstr = inet_ntoa(*ipv4addr); //inet_ntop(AF_INET, ipv4addr, ipstr, sizeof(ipstr)); // convert port to int int portnumber = socketaddress->sin_port; // Save in properties _publicIP = [NSString stringWithFormat:@"%s", ipstr]; _publicPort = [NSString stringWithFormat:@"%d", portnumber]; } } 

之后,您将在属性_publicIP拥有公共IP,并在属性_publicIP拥有公共端口。 所有信息都是从服务器端的连接收集的。

我希望这篇文章可以帮助某人=)