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

2024-01-03

我编写了一个服务器,用于侦听特定端口上传入的 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];
    }
}

之后您将拥有该房产的公共IP_publicIP以及酒店内的公共端口_publicPort。所有信息都是从服务器端的连接收集的。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Objective-C 中从 NSStream、CFStream 或 Socket 获取 OSX 上的对等 IP 地址和端口 的相关文章

随机推荐

  • 使用 FQL 时出现意外行为

    与没有 LIMIT 相比 向 FQL 添加 LIMIT 选项会导致返回更多结果 举个例子 SELECT post id actor id message description type FROM stream WHERE source i
  • MSIE 返回 Ajax 请求的状态代码 1223

    我正在使用 ajax 请求 POST 方法 提交表单 并检查响应上的 HTTP 状态代码以查看它是否成功 它在 Firefox 上运行良好 但在 MSIE 8 上当然不行 提交实际上工作正常 我可以检查我的服务器并确认提交有效并且服务器以状
  • .rdlc 报告中的自定义 .ToString() 格式

    我有一个自定义业务对象 它重载了 ToString 函数 它还实现了 IFormattable ToString 因此我可以定义自己的自定义格式 这种方法似乎在我的应用程序中的任何地方都适用 除了 rdlc 报告 例如 我在报表上有一个文本
  • Postgres 数据到 XML

    有谁知道将数据库条目转换为 XML 的好方法吗 IE 如果我有一个名为 Users 的表 其中包含字段 first name age last name 我想将该表转换为
  • 如何从下拉菜单中选择并调用javascript函数

    我有一个下拉菜单 其中有很多选项 我希望当我选择任何 选项 然后它通过 JavaScript 调用一个函数 我使用的代码在这里
  • 使用 angularjs 选择多个列表项

    我试图从无序列表中的元素中选择特定的列表项 它应该显示为已选中 我需要通过更改一些背景来显示它 我试图使用 index当我试图在其中使用它时 它是不确定的 li 元素 我可以从内部实现这个目标吗angularjs 不使用复选框或 jQuer
  • 使用 libcurl 发送 SMTP 邮件

    我编译了 libcurl 附带的 c 示例 源文件是smtp tls c尝试使用它通过 gmail 发送邮件 这是我得到的回复 即将 connect 到 smtp gmail com 端口 465 0 正在尝试 74 125 115 109
  • 犰狳+BLAS+LAPACK

    我正在包 LAMMPS 包 内使用犰狳库 我还使用犰狳来编译不同的代码 并且运行良好 我使用以下编译命令 g example2 cpp o example2 O3 larmadillo DARMA DONT USE WRAPPER lbla
  • 当日历在 Android 中触发提醒警报接收器时,如何获取事件 ID?

    这是我的代码 public class CalendarReminderReceiver extends BroadcastReceiver Override public void onReceive Context context In
  • logback 不打印方法或行号

    这是一个 Gradle 项目 使用 Groovy 作为应用程序代码和测试代码 但我使用 logback xml 文件进行配置 这里可能重要的一个因素是我正在使用 Groovy Slf4j http docs groovy lang org
  • Android 图形视图

    我已经使用 jjoe64 的 graphview 库在我的应用程序中实现图形 它的盒子里有非常好的样本 并立即开始将其包含在我的应用程序中 到目前为止我所得到的内容如下所示 但我真正需要的是如下所示 我不希望黑色垂直线出现在图表内 知道如何
  • 为特定站点选择 F12 开发人员工具时显示“Internet Explorer 已停止工作”

    打开开发人员工具时 Internet Explorer 11 最新 崩溃 并显示消息 Internet Explorer 已停止工作 并且我打开了网站 Chrome Edge 不会出现这个问题 我的网站中的所有功能都可以正常工作 这仅适用于
  • Postgresql函数使用动态表名创建表?

    假设我有几个用户 每个用户都有自己的一组联系人 用户可以选择哪些第三方可以访问他们的联系人 我也许可以创建 1 个大型联系人表并有一个 所有者 列 以便我可以识别哪些联系人属于哪些用户 但是 然后我需要维护行级权限 以便我可以限制哪些第三方
  • Makefile 为单个目标提供多个依赖行?

    要生成依赖文件 我可以使用类似的方法来生成依赖文件 include patsubst cpp build d SRC build o cpp CC CXXFLAGS c o lt CC CXXFLAGS MM MT MF patsubst
  • 无法使用 MD5 方法从主机连接到虚拟机上运行的 Postgres

    我有一个使用 Vagrant 设置的虚拟机 在其上运行 Postgres 在端口 5432 上 转发到主机上的端口 8280 我已经为默认用户设置了密码 并且可以很好地进行本地连接 我一直在尝试通过端口 8280 设置从主机的访问 但无法使
  • Elastic Beanstalk 上的 502 错误网关 nginx + puma + Rails 3.2

    部署成功 一切都是绿色的 但是当我们尝试访问应用程序 URL 时 它会给出502 Bad Gateway error 检查 puma 进程ps aux grep puma不返回任何附加到 puma 服务器的进程 但是pgrep返回以下 pg
  • 正则表达式选择某个字符之前的空格

    我想创建一个正则表达式 它允许我选择逗号之前的空格 IE 生日快乐 吉米 正则表达式应选择空格 Happy birthday Jimmy 出现在包含逗号的单词 字符串之前 用括号注明 您可以使用展望 https stackoverflow
  • Android Room - 自动递增@数据库版本号?

    在开发过程中 我的 Room 数据库模式非常不稳定 每次我对架构进行任何更改时 我都需要更新我的版本号 如下所示 Database version 27 entities MyClass class public abstract clas
  • 监控 Firebase 存储变化的最佳方法[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 Firebase 实时数据库和 Firebase 存储在 Unity 中构建一个应用程序
  • 在 Objective-C 中从 NSStream、CFStream 或 Socket 获取 OSX 上的对等 IP 地址和端口

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