我使用域名创建了请求,例如http://www.google.com
。但是,我怎样才能获得框架用于连接服务器的确切IP地址?
我知道gethostbyname
方法或nslookup
方法可以给我们地址,但由于ip地址是动态分配的,也许我请求的ip地址与返回这些方法的时间不同。
那么有没有办法让我获得真正的请求IP地址? (我想以编程方式获取ip,而不是使用tcpdump等。)
答案 0 :(得分:1)
您的浏览器或用于发出HTTP请求的任何其他工具将在执行请求时查找地址。在任何合理的系统上,他们将使用相同的方法查找地址gethostbyname
,除了浏览器中可能存在本地缓存(通常可以关闭或清除)。
请求可能会获得重定向响应,以便向不同的位置发出相同的请求。这些通常用于负载平衡等。我可以看到你能够找到最终目的地的唯一直接方式'在这些之后,将以编程方式发出请求并记录任何重定向的详细信息。当然,负载平衡的本质是您每次都可能重定向到稍微不同的服务器。
这与动态分配IP地址'无关。顺便说说。如果www.google.com
的IP地址发生更改,则可能不是因为同一服务器已分配了不同的IP地址,而是因为请求被定向到另一台计算机。
答案 1 :(得分:1)
当您在此处说“框架使用了哪个”时,我认为您的意思是NSURLSession
,NSURLConnection
,UIWebView
或WKWebView
。每一个都是略有不同的情况,但在所有这些情况下,答案是不可能直接(但见下文;它可能是间接的)。您无权访问其中任何一个使用的底层套接字。所有这些都使用连接池,即使你可以获得“套接字”,这也会使事情变得复杂。对于UIWebView
和WKWebView
,对www.google.com
的单个请求可能会生成多个独立的连接,每个连接都可能与不同的IP地址进行交互。
(我对你要做的事情有点着迷。由于负载平衡,单个IP地址并不意味着单个服务器,因此IP地址只比CNAME稍微更具识别性。代理....)
如果您需要此类访问权限,则必须自行管理套接字。除了WKWebView
之外,所有系统通常都可以这样做。我假设您已经知道(或可以轻松学习)如何使用CFSocket
和CFHTTPMessage
创建套接字并执行HTTP。 CFNetwork Programming Guide广泛涵盖了这一点。如果您已创建套接字,则可以使用CFSocketCopyPeerAddress
检查您真正连接的主机。这就是你想要的作品。
鉴于您能够创建此类套接字并自行管理,您可以使用WKWebView
将其挂钩到主要的URL加载器(NSURLProtocol
除外)。有关快速介绍和一些示例代码,请参阅Drop-in Offline Caching for UIWebView (and NSURLProtocol)。您只需要接受请求并使用CFSocket
自行创建,这样您就有机会看到您所连接的确切端口。
答案 2 :(得分:0)
如果使用NSURLSession
获取URLSessionStreamTask
,则可以使用-captureStreams
捕获基础流。这将调用-URLSession:streamTask:didBecomeInputStream:outputStream:
委托方法,为您提供NSInputStream
和NSOutputStream
。 NSInputStream
是免费电话桥接到CFReadStreamRef
,并使用CFReadStreamCopyProperty()
,常量kCFStreamPropertySocketNativeHandle
为您提供了本地套接字句柄,您可以将其传递到getpeername()
中。对于上载,下载和数据任务,似乎不存在这种可能性。