IPv6協(xié)議
整體來看,IPv6協(xié)議相比IPv4, 格式上簡(jiǎn)潔很多:
- IPv6報(bào)文頭部是定長(zhǎng)(固定為40字節(jié)),IPv4報(bào)文頭部是變長(zhǎng)的。這個(gè)意味著,寫代碼處理IPv6數(shù)據(jù)報(bào)文的效率會(huì)提高很多:);
- IPv6中Hop Limit字段含義類似IPv4的TTL;
- IPv6中的Traffic Class字段含義類似IPv4中的TOS(Type Of Service);
- IPv6的報(bào)文頭部取消了校驗(yàn)和字段:取消這個(gè)字段也是對(duì)IPv4協(xié)議的一個(gè)改進(jìn)。當(dāng)IPv4報(bào)文在網(wǎng)路間傳輸,每經(jīng)過一個(gè)路由器轉(zhuǎn)發(fā)就是修改TTL字段,就需要重新計(jì)算校驗(yàn)和,而由于數(shù)據(jù)鏈路層L2和傳輸層L4的校驗(yàn)已經(jīng)足夠強(qiáng)壯,因此IPv6取消這個(gè)字段會(huì)提高路由器的轉(zhuǎn)發(fā)效率。值得一提的是,在IPv6協(xié)議下,傳輸層L4協(xié)議UDP、TCP是強(qiáng)制需要進(jìn)行校驗(yàn)和的(IPv4是可選的);
- IPv6報(bào)文頭部中的Next Header字段表示“承載上一層的協(xié)議類型”或者“擴(kuò)展頭部類型”。
IPv6的地址語法
一個(gè)IPv6的地址使用冒號(hào)十六進(jìn)制表示方法:128位的地址每16位分成一段,每個(gè)16位的段用十六進(jìn)制表示并用冒號(hào)分隔開,例如一個(gè)普通公網(wǎng)IPv6地址:
2001:0D12:0000:0000:02AA:0987:FE29:9871
IPv6地址支持壓縮前導(dǎo)零的表示方法,例如上面的地址可以壓縮表示為:
2001:12:0:0:2AA:987:FE29:9871
為了進(jìn)一步精簡(jiǎn)IPv6地址,當(dāng)冒號(hào)十六進(jìn)制格式中出現(xiàn)連續(xù)幾段數(shù)值0的位段時(shí),這些段可以壓縮為雙冒號(hào)的表示,例如上面的地址還可以進(jìn)一步精簡(jiǎn)表示為:
2001:12::2AA:987:FE29:9871
又例如IPv6的地址FF80:0:0:0:FF:3BA:891:67C2可以進(jìn)一步精簡(jiǎn)表示為:
FE80::FF:3BA:891:67C2
這里值得注意的是:雙冒號(hào)只能出現(xiàn)一次。
IPv6地址前綴表示法
IPv6支持子網(wǎng)前綴標(biāo)識(shí)方法,類似于IPv4的無分類域間路由CIDR機(jī)制(注意:IPv6沒有子網(wǎng)掩碼mask的概念)。
使用IPv6地址/前綴長(zhǎng)度表示方法,例如:
2001:C3:0:2C6A::/64表示一個(gè)子網(wǎng);
而2001:C3:0:2C6A:C9B4:FF12:48BC:1A22/64表示該子網(wǎng)下的一個(gè)節(jié)點(diǎn)地址。
IPv6尋址模式
- 單播 : 跟ipv4單播一致,在單播尋址模式下,IPv6接口(host)在網(wǎng)段中唯一標(biāo)識(shí)。 IPv6數(shù)據(jù)包包含源IP地址和目標(biāo)IP地址。 主機(jī)接口配備有在該網(wǎng)絡(luò)段中唯一的IP地址。
- 多播 : IPv6組播模式與IPv4相同。 目的地為多個(gè)主機(jī)的數(shù)據(jù)包在特殊的多播地址上發(fā)送。 所有對(duì)該組播信息感興趣的主機(jī)需要首先加入該組播組。 加入組的所有接口接收組播數(shù)據(jù)包并對(duì)其進(jìn)行處理,而對(duì)組播數(shù)據(jù)不感興趣的其他主機(jī)則忽略組播信息。
- 任播 : IPv6引入了一種新型的尋址,稱為Anycast尋址。 在此尋址模式下,多個(gè)接口(host)被分配相同的任播IP地址。 當(dāng)主機(jī)希望與配備有任播IP地址的主機(jī)通信時(shí),它發(fā)送單播消息。 在復(fù)雜的路由機(jī)制的幫助下,在路由成本方面,該單播消息被遞送到最接近發(fā)送方的主機(jī)。
IPv6沒有廣播地址,用組播地址實(shí)現(xiàn)廣播的功能。
IPv6單播地址
- 全球單播地址:前綴2000::/3,相當(dāng)于IPv4的公網(wǎng)地址。這種地址在全球的路由器間可以路由。
- 鏈路本地地址:前綴FE80::/10Windows和Linux支持或開啟IPv6后,默認(rèn)會(huì)給網(wǎng)卡接口自動(dòng)配置一個(gè)鏈路本地地址。也就是說,一個(gè)接口一定有一個(gè)鏈路本地地址。
- 唯一本地地址前綴:FC00::/7前綴FC00::和 FD00::的IPV6地址,相當(dāng)于IPv4的私網(wǎng)地址10.0.0.0、172.16.0.0、192.168.0.0。
- 回環(huán)地址:::1等同于IPv4的127.0.0.1。
面向IPv6的應(yīng)用開發(fā)
Golang服務(wù)端
package mainimport ( 'fmt' 'net' 'net/http')func main() { var err error http.Handle('/', &helloHandler{}) // 監(jiān)聽本地IPv4地址的8083端口 // err = http.ListenAndServe(':8083', nil) // 監(jiān)聽指定IPv6地址的8083端口 // err = http.ListenAndServe('[2604:180:3:dd3::276e]:8083', nil) // 同時(shí)監(jiān)聽本地IPv4和IPv6地址的8083端口 err = ListenAndServe(':8083', nil) if err != nil { fmt.Println(err) }}
Curl客戶端
curl 'http://[2604:180:3:dd3::276e]:8083'curl -g -6 'http://[2604:180:3:dd3::276e]:8083/'
Python UDP服務(wù)端:
import socketUDP_IP = '::' # = IPv4 0.0.0.0UDP_PORT = 5005sock = socket.socket(socket.AF_INET6, # Internet socket.SOCK_DGRAM) # UDPsock.bind((UDP_IP, UDP_PORT))while True: data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes print 'received message:', data
Python UDP客戶端:
import socketUDP_IP = '::1' # localhostUDP_PORT = 5005MESSAGE = 'Hello, World!'print 'UDP target IP:', UDP_IPprint 'UDP target port:', UDP_PORTprint 'message:', MESSAGEsock = socket.socket(socket.AF_INET6, # Internet socket.SOCK_DGRAM) # UDPsock.sendto(MESSAGE, (UDP_IP, UDP_PORT))