• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 在 OSX 上从 NSStream、CFStream 或 Socket 获取对等 IP 地址和端口

[复制链接]
菜鸟教程小白 发表于 2022-12-13 05:30:36 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

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

现在我想获取通过已经建立的流向我发送消息的设备的公共(public) 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);

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

提前谢谢你!



Best Answer-推荐答案


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

- (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 中获得公共(public) IP,在属性 _publicPort 中获得公共(public)端口。所有信息都是从服务器端的连接收集的。

我希望这篇文章对某人有所帮助 =)

关于ios - 在 OSX 上从 NSStream、CFStream 或 Socket 获取对等 IP 地址和端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20050274/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap