在 Objective-c 中从 NSStream、CFStream 或 Socket 获取 OSX 上的对等 IP 地址和端口 [英] Get peer IP address and port on OSX in objective-c from NSStream, CFStream or Socket

查看:87
本文介绍了在 Objective-c 中从 NSStream、CFStream 或 Socket 获取 OSX 上的对等 IP 地址和端口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have written a server that listens on a specific port for incoming tcp connections. To manage the network connectivity I am using Streams (CFStream/NSStream). When a connection is esthablished I save all the information about this very connection in another instance of a dedicated class which is also set as the delegate for the streams.

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

Now I want to get the public IP of the device that sends me a message through the already esthablished streams, in other words, I would like to store the IP of the stream's peer. I tried many things, but unfortunately I only get null-values.

是否有可能从描述形式的现有流中获取对等方的地址(IP 和端口)?

Is there a possibility to get the peer's address (ip and port) from an existing stream of the described form?

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

Here is some code I have tried:

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

我也试过直接在监听回调方法中获取信息:

I also tried to get the information direct in the listening callback method:

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);

为什么我总是得到空值?有人可以帮我吗?

Why do I always get null-values? Can anyone help me?

先谢谢你!

推荐答案

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

Okay I figured it out by now. This is what I did:

- (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 和属性 _publicPort 中的公共端口.所有信息均通过服务器端的连接收集.

Afterwards you will have the public IP in the property _publicIP and the public port in the property _publicPort. All information is gathered from a connection on the server side.

我希望这篇文章能帮助别人=)

I hope this post will help someone =)

这篇关于在 Objective-c 中从 NSStream、CFStream 或 Socket 获取 OSX 上的对等 IP 地址和端口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆