菜鸟教程小白 发表于 2022-12-13 05:30:36

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


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

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

<p>是否有可能从所描述形式的现有流中获取对等方的地址(ip 和端口)?</p>

<p>这是我尝试过的一些代码:</p>

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

<p>我也尝试在监听回调方法中直接获取信息:</p>

<pre><code>NSData *peer = nil;

CFSocketNativeHandle nativeSocketHandle = *(CFSocketNativeHandle *)data;

struct sockaddr *addressinfo = NULL;

uint8_t name;

socklen_t namelen = sizeof(addressinfo);
int result = getpeername(nativeSocketHandle, addressinfo, &amp;namelen);

if (result == 0) {

      peer = ;

}

struct sockaddr_in *s = (struct sockaddr_in*)name;

char *ipstr = malloc(INET_ADDRSTRLEN);

ipstr = inet_ntoa(s-&gt;sin_addr); // is 0.0.0.0 :-(
</code></pre>

<p>我尝试了另一种方法:</p>

<pre><code>_publicIP = CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)(_writeStream), kCFStreamPropertySocketRemoteHostName);
</code></pre>

<p>为什么我总是得到空值?谁能帮帮我?</p>

<p>提前谢谢你!</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>好的,我现在想通了。这就是我所做的:</p>

<pre><code>- (void)getPublicClientAddress {
    // Get public IP from stream

    // Get hands on appropriate data structures via the socket number
    CFSocketNativeHandle nativeSocketHandle = _socketnumber;
    uint8_t name;
    socklen_t namelen = sizeof(name);
    NSData *peer = nil;
    if (0 == getpeername(nativeSocketHandle, (struct sockaddr *)name, &amp;namelen)) {
      peer = ;
    }

    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 = &amp;socketaddress-&gt;sin6_addr;
      inet_ntop(AF_INET6, ipv6addr, ipstr, sizeof(ipstr));

      // convert port to int
      int portnumber = socketaddress-&gt;sin6_port;

      // Save in properties
      _publicIP   = ;
      _publicPort = ;
    } 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 = &amp;socketaddress-&gt;sin_addr;
      ipstr = inet_ntoa(*ipv4addr);
      //inet_ntop(AF_INET, ipv4addr, ipstr, sizeof(ipstr));

      // convert port to int
      int portnumber = socketaddress-&gt;sin_port;

      // Save in properties
      _publicIP   = ;
      _publicPort = ;
    }
}
</code></pre>

<p>之后,您将在属性 <code>_publicIP</code> 中获得公共(public) IP,在属性 <code>_publicPort</code> 中获得公共(public)端口。所有信息都是从服务器端的连接收集的。</p>

<p>我希望这篇文章对某人有所帮助 =)</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 在 OSX 上从 NSStream、CFStream 或 Socket 获取对等 IP 地址和端口,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/20050274/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/20050274/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 在 OSX 上从 NSStream、CFStream 或 Socket 获取对等 IP 地址和端口