2014-02-28 232 views
1

我是一名學生,我試圖理解IP地址背後的想法。我知道,輸入網址與輸入相應的IP地址相同 - 無論哪種方式,我們都會被引導到同一個網頁。瞭解IP。在此服務器上找不到請求的URL

我用ping命令查找howstuffworks.com的IP地址。然後我在瀏覽器中輸入IP地址(谷歌瀏覽器),但得到了這個錯誤:

The requested URL was not found on this server. 

爲什麼?我試着與google.com IP一樣,並且它工作正常。

此外,我使用ping命令發現的IP地址是IPv4(對於谷歌來說,它是173.194.40.80)。爲什麼它沒有顯示IPv6地址?

+0

IP地址與URL一樣好的描述性假設僅適用於某些Web服務器配置。顯然這不是真的。 –

+0

可能的重複http://stackoverflow.com/questions/5142030/why-does-the-resolved-ip-of-youtube-com-direct-to-google-com –

回答

2

FQDN(例如www.stackoverflow.com)和IP地址(例如198.252.206.140)之間的關係不一定是一對一的關係。例如,如果我爲www.stackoverflow.com進行DNS查找,則得到198.252.206.140。所以,www.stackoverflow.com網站託管在一個IP地址爲198.252.206.140的網絡服務器上。但是,可能有其他的網站也可能在198.252.206.140上託管。

這就是爲什麼我們在http協議中有Host命令。瀏覽器在端口80上連接到Web服務器後,瀏覽器會發送host命令以指示它正試圖連接到Web服務器上的哪個站點。請參閱http://blog.tonycode.com/tech-stuff/http-notes/making-http-requests-via-telnet以獲得有關如何工作的良好教程。下面複製的是一個與198.252.206.140的telnet會話,在這個會話中建立http連接,併發出host命令來選擇www.stackoverflow.com,並返回www.stackoverflow.com的默認響應(在本例中爲301重定向到stackoverflow.com):

$ telnet 198.252.206.140 80 
Trying 198.252.206.140... 
Connected to 198.252.206.140. 
Escape character is '^]'. 
GET/HTTP/1.1 
Host: www.stackoverflow.com 

HTTP/1.1 301 Moved Permanently 
Content-Type: text/html; charset=UTF-8 
Location: http://stackoverflow.com/ 
Date: Tue, 04 Mar 2014 10:58:36 GMT 
Content-Length: 148 

<head><title>Document Moved</title></head> 
<body><h1>Object Moved</h1>This document may be found <a 
HREF="http://stackoverflow.com/">here</a></body> 
1

主機名稱大致相當於您的瀏覽器到達遠程服務器時的IP地址。

HTTP/1.1協議指定客戶端(瀏覽器)必須通過主機名稱作爲標題,如:

Host: www.howstuffworks.com 

這是非常有用的,因爲它允許多個網站要對託管相同的服務器,或無論如何可以從相同的IP地址訪問。

您可以使用該實用程序的命令curl發現了這一點:

curl -v http://54.236.73.243/ -H 'Host: www.howstuffworks.com' 

或使用你的瀏覽器有一些插件,允許設置自定義頭。

1

爲了回答你問題的第二部分:

ping命令選擇地址的一個來ping時,主機有多個地址。在Windows系統上,ping可用於IPv4和IPv6。在類Unix系統上,您必須使用ping6來支持IPv6。

如果你想看看你必須使用一個支持此目的的一種工具是什麼在DNS如host或(在類Unix系統上),或者nslookup(當在Windows系統上) 。例如:

$ dig google.com any 

; <<>> DiG 9.8.3-P1 <<>> google.com any 
;; global options: +cmd 
;; Got answer: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42780 
;; flags: qr rd ra; QUERY: 1, ANSWER: 19, AUTHORITY: 0, ADDITIONAL: 0 

;; QUESTION SECTION: 
;google.com.   IN ANY 

;; ANSWER SECTION: 
google.com.  299 IN A 173.194.65.138 
google.com.  299 IN A 173.194.65.100 
google.com.  299 IN A 173.194.65.101 
google.com.  299 IN A 173.194.65.113 
google.com.  299 IN A 173.194.65.139 
google.com.  299 IN A 173.194.65.102 
google.com.  299 IN AAAA 2a00:1450:4013:c00::8b 
google.com.  599 IN MX 10 aspmx.l.google.com. 
google.com.  599 IN MX 20 alt1.aspmx.l.google.com. 
google.com.  599 IN MX 30 alt2.aspmx.l.google.com. 
google.com.  599 IN MX 40 alt3.aspmx.l.google.com. 
google.com.  599 IN MX 50 alt4.aspmx.l.google.com. 
google.com.  21599 IN NS ns1.google.com. 
google.com.  21599 IN NS ns2.google.com. 
google.com.  21599 IN NS ns3.google.com. 
google.com.  21599 IN NS ns4.google.com. 
google.com.  3599 IN TXT "v=spf1 include:_spf.google.com ip4:216.73.93.70/31 ip4:216.73.93.72/31 ~all" 
google.com.  21599 IN SOA ns1.google.com. dns-admin.google.com. 2014021800 7200 1800 1209600 300 
google.com.  21599 IN TYPE257 \# 19 0005697373756573796D616E7465632E636F6D 

;; Query time: 27 msec 
;; SERVER: 8.8.8.8#53(8.8.8.8) 
;; WHEN: Fri Feb 28 23:53:29 2014 
;; MSG SIZE rcvd: 497 

正如你可以看到有更多的DNS比AAAAA記錄:-)

而爲了讓這個答案至少有一點上,話題的StackOverflow,這裏是如何您可以正確處理在雙棧環境中解析名稱。編寫代碼的方式可以自動使用任何可用的協議。這是Python中的一個示例:

#!/usr/bin/python 
import sys, socket 

# Get the hostname from the command line 
if len(sys.argv) == 2: 
    host = sys.argv[1] 
else: 
    print("Usage: {} <hostname>".format(sys.argv[0])) 
    sys.exit(1) 

# Set the parameters for the getaddrinfo call 
service = "http" 
family = socket.AF_UNSPEC 
socktype = socket.SOCK_STREAM 
protocol = socket.SOL_TCP 
flags = 0 

# Call getaddrinfo, it will give back a list of possible parameter-sets 
try: 
    resultset = socket.getaddrinfo(host, service, family, socktype, protocol, flags) 
except socket.error: 
    print("I'm sorry, but {} doesn't seem to exist".format(host)) 
    sys.exit(1) 

# Now try to connect to them one by one 
sock = None 
for family, socktype, protocol, canonname, sockaddr in resultset: 
    print("Trying to connect to {}".format(sockaddr)) 

    try: 
     # Create a socket with the given parameters 
     sock = socket.socket(family, socktype, protocol) 
    except socket.error: 
     # Failed to create a socket, try the next one 
     continue 

    try: 
     # We have a socket, now use it to connect 
     sock.connect(sockaddr) 
    except socket.error: 
     # The connection failed, close the socket 
     sock.close() 
     sock = None 

     # And try the next one 
     continue 

    # Wonderful, we have a socket, and it is now connected! 
    # Stop retrying 
    break 

if sock is None: 
    print("None of the available addresses worked") 
    sys.exit(1) 

print("That one worked!") 
my_addr = sock.getsockname() 
remote_addr = sock.getpeername() 
print("There is now a connection from {} to {}".format(my_addr, remote_addr)) 

# And close the connection nicely 
sock.close() 
相關問題