我使用域名创建了一个请求,例如http://www.google.com
。但是我该如何获取框架用于连接服务器的确切IP地址?
我知道gethostbyname
方法或nslookup
方法可以给我们地址,但由于IP地址是动态分配的,也许我请求的IP地址与这些方法返回的不同。
那么有没有办法让我获取实际请求的IP地址?(我想以编程方式获取IP,而不是使用tcpdump等工具。)
我使用域名创建了一个请求,例如http://www.google.com
。但是我该如何获取框架用于连接服务器的确切IP地址?
我知道gethostbyname
方法或nslookup
方法可以给我们地址,但由于IP地址是动态分配的,也许我请求的IP地址与这些方法返回的不同。
那么有没有办法让我获取实际请求的IP地址?(我想以编程方式获取IP,而不是使用tcpdump等工具。)
您的浏览器或其他用于发出HTTP请求的工具将在请求时查找地址。在任何合理的系统上,它们将使用与 gethostbyname
相同的方法来查找地址,只是浏览器可能会有本地缓存(通常可以关闭或清除)。
请求可能会收到重定向响应,以使相同的请求发送到不同的位置。这些通常用于负载均衡等。我唯一能想到的直接方式是通过编程方式进行请求并记录任何重定向的细节,才能找到这些背后的“最终目的地”。当然,负载平衡的特点是您可能每次都会被重定向到略微不同的服务器。
顺便说一句,这与“动态分配IP地址”无关。如果 www.google.com
的IP地址更改,那很可能不是因为同一个服务器被分配了不同的IP地址,而是因为请求正在定向到不同的机器。
NSURLSession
、NSURLConnection
、UIWebView
或WKWebView
。虽然每个框架的情况略有不同,但在所有情况下,答案都是直接不可能实现(但请参见下文;可以间接实现)。您无法访问它们使用的任何底层套接字。它们全部使用连接池,即使您可以获得“套接字”,这也会稍微复杂化事情。而在UIWebView
和WKWebView
的情况下,对www.google.com
的单个请求可能会生成多个独立的连接,每个连接都可能与不同的IP地址交互。 WKWebView
之外,所有系统通常都可以实现。我假设您已经知道(或可以轻松学习)如何创建套接字并使用 CFSocket
和 CFHTTPMessage
执行HTTP。这在CFNetwork编程指南中得到了广泛的涵盖。如果您已经创建了套接字,您可以使用 CFSocketCopyPeerAddress
检查您真正连接到的主机。这就是您想要的那部分。 NSURLProtocol
将其钩入主要的URL加载器(除了 WKWebView
)。有关快速介绍和一些示例代码,请参见UIWebView(和NSURLProtocol)的即插即用离线缓存。您只需获取请求并使用 CFSocket
自己进行处理,从而有机会查看您连接到的确切端口。如果您正在使用NSURLSession
来获取URLSessionStreamTask
,您可以使用-captureStreams
来捕获底层流。这将调用-URLSession:streamTask:didBecomeInputStream:outputStream:
委托方法,提供给您一个NSInputStream
和一个NSOutputStream
。NSInputStream
可以无缝桥接到CFReadStreamRef
,并且使用CFReadStreamCopyProperty()
和常量kCFStreamPropertySocketNativeHandle
可以为您提供本机套接字句柄,您可以将其传递给getpeername()
。至于上传任务、下载任务和数据任务,则似乎没有这样的可能性存在。