成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用Java打造兼容IPv6的網(wǎng)絡(luò)程序

開發(fā) 后端
對于 Java,從其 1.4 版開始對 IPv6 提供了較好的支持,對程序員基本屏蔽了 IPv4 和 IPv6 的差異,但其中仍有一些 IPv6 引起的變化需要我們小心處理。針對這一情況,本文介紹了如何運用現(xiàn)有的 Java 技術(shù)應(yīng)對這些變化。

51CTO曾經(jīng)為網(wǎng)友介紹過“Java開發(fā)中常見的異常問題”,今天向大家介紹一下如何使我們Java對IPv6進行支持的。

IPv6 背景介紹

目前我們使用的是第二代互聯(lián)網(wǎng) IPv4 技術(shù),它的最大問題是網(wǎng)絡(luò)地址資源有限,從理論上講,可以編址 1600 萬個網(wǎng)絡(luò)、40 億臺主機。但采用 A、B、C 三類編址方式后,可用的網(wǎng)絡(luò)地址和主機地址的數(shù)目大打折扣,以至目前的 IP 地址近乎枯竭。網(wǎng)絡(luò)地址不足,嚴(yán)重地制約了全球互聯(lián)網(wǎng)的應(yīng)用和發(fā)展。

一方面是地址資源數(shù)量的限制,另一方面是隨著電子技術(shù)及網(wǎng)絡(luò)技術(shù)的發(fā)展,計算機網(wǎng)絡(luò)將進入人們的日常生活,可能身邊的每一樣?xùn)|西都需要連入全球因特網(wǎng)。在這種網(wǎng)絡(luò)空間匱乏的環(huán)境下,IPv6 應(yīng)運而生。它的產(chǎn)生不但解決了網(wǎng)絡(luò)地址資源數(shù)量的問題,同時也為除電腦外的設(shè)備連入互聯(lián)網(wǎng)在數(shù)量限制上掃清了障礙。

如果說 IPv4 實現(xiàn)的只是人機對話,那么 IPv6 則擴展到任意事物之間的對話,它不僅可以為人類服務(wù),還將服務(wù)于眾多硬件設(shè)備,如家用電器、傳感器、遠(yuǎn)程照相機、汽車等,它將是無時不在,無處不在的深入社會每個角落的真正的寬帶網(wǎng),它所帶來的經(jīng)濟效益也將非常巨大。

當(dāng)然,IPv6 并非十全十美、一勞永逸,不可能解決所有問題。IPv6 只能在發(fā)展中不斷完善,也不可能在一夜之間發(fā)生,過渡需要時間和成本,但從長遠(yuǎn)看,IPv6 有利于互聯(lián)網(wǎng)的持續(xù)和長久發(fā)展。目前,國際互聯(lián)網(wǎng)組織已經(jīng)決定成立兩個專門工作組,制定相應(yīng)的國際標(biāo)準(zhǔn)。

Java 對 IPv6 的支持

隨著 IPv6 越來越受到業(yè)界的重視,Java 從 1.4 版開始支持 Linux 和 Solaris 平臺上的 IPv6。1.5 版起又加入了 Windows 平臺上的支持。相對于 C++,Java 很好得封裝了 IPv4 和 IPv6 的變化部分,遺留代碼都可以原生支持 IPv6,而不用隨底層具體實現(xiàn)的變化而變化。

那么 Java 是如何來支持 IPv6 的呢? Java 網(wǎng)絡(luò)棧會優(yōu)先檢查底層系統(tǒng)是否支持 IPv6,以及采用的何種 IP 棧系統(tǒng)。如果是雙棧系統(tǒng),那它直接創(chuàng)建一個 IPv6 套接字(如圖 1)。

 

雙棧結(jié)構(gòu) 

圖 1. 雙棧結(jié)構(gòu)

對于分隔棧系統(tǒng),Java 則創(chuàng)建 IPv4/v6 兩個套接字(如圖 2)。如果是 TCP 客戶端程序,一旦其中某個套接字連接成功,另一個套接字就會被關(guān)閉,這個套接字連接使用的 IP 協(xié)議類型也就此被固定下來。如果是 TCP 服務(wù)器端程序,因為無法預(yù)期客戶端使用的 IP 協(xié)議,所以 IPv4/v6 兩個套接字會被一直保留。對于 UDP 應(yīng)用程序,無論是客戶端還是服務(wù)器端程序,兩個套接字都會保留來完成通信。

 

分隔棧結(jié)構(gòu) 

圖 2. 分隔棧結(jié)構(gòu)
 

#p#

如何驗證 IPv6 地址

IPv6 地址表示

從 IPv4 到 IPv6 最顯著的變化就是網(wǎng)絡(luò)地址的長度,IPv6 地址為 128 位長度,一般采用 32 個十六進制數(shù),但通常寫做 8 組每組 4 個十六進制的形式。例如:

2001:0db8:85a3:08d3:1319:8a2e:0370:7344 是一個合法的 IPv6 地址。如果四個數(shù)字都是零,則可以被省略。

2001:0db8:85a3:0000:1319:8a2e:0370:7344 等同于 2001:0db8:85a3::1319:8a2e:0370:7344。

遵從這些規(guī)則,如果因為省略而出現(xiàn)了兩個以上的冒號的話,可以壓縮為一個,但這種零壓縮在地址中只能出現(xiàn)一次。因此

  1. 2001:0DB8:0000:0000:0000:0000:1428:57ab  
  2. 2001:0DB8:0000:0000:0000::1428:57ab  
  3. 2001:0DB8:0:0:0:0:1428:57ab  
  4. 2001:0DB8:0::0:1428:57ab  
  5. 2001:0DB8::1428:57ab 

都是合法的地址,并且他們是等價的。但 2001::25de::cade 是非法的。(因為這樣會使得搞不清楚每個壓縮中有幾個全零的分組)。同時前導(dǎo)的零可以省略,因此:2001:0DB8:02de::0e13 等于 2001:DB8:2de::e13。

IPv6 地址校驗

IPv4 地址可以很容易的轉(zhuǎn)化為 IPv6 格式。舉例來說,如果 IPv4 的一個地址為 135.75.43.52(十六進制為 0x874B2B34),它可以被轉(zhuǎn)化為 0000:0000:0000:0000:0000:0000:874B:2B34 或者::874B:2B34。同時,還可以使用混合符號(IPv4- compatible address),則地址可以為::135.75.43.52。

在 IPv6 的環(huán)境下開發(fā) Java 應(yīng)用,或者移植已有的 IPv4 環(huán)境下開發(fā)的 Java 應(yīng)用到 IPv6 環(huán)境中來,對于 IPv6 網(wǎng)絡(luò)地址的驗證是必須的步驟,尤其是對那些提供了 UI(用戶接口)的 Java 應(yīng)用。

所幸的是,從 Java 1.5 開始,Sun 就增加了對 IPv6 網(wǎng)絡(luò)地址校驗的 Java 支持。程序員可以通過簡單地調(diào)用方法 sun.net.util.IPAddressUtil.isIPv6LiteralAddress() 來驗證一個 String 類型的輸入是否是一個合法的 IPv6 網(wǎng)絡(luò)地址。

為了更深入一步地了解 IPv6 的網(wǎng)絡(luò)地址規(guī)范,及其驗證算法,筆者參閱了一些材料,包括上文所述的方法 sun.net.util.IPAddressUtil.isIPv6LiteralAddress() 的源代碼,以及目前網(wǎng)絡(luò)上流傳的一些 IPv6 網(wǎng)絡(luò)地址的正則表達式,發(fā)現(xiàn):

1.由于 IPv6 協(xié)議所允許的網(wǎng)絡(luò)地址格式較多,規(guī)范較寬松(例如零壓縮地址,IPv4 映射地址等),所以導(dǎo)致了 IPv6 網(wǎng)絡(luò)地址的格式變化很大。

2.Java 對于 IPv6 網(wǎng)絡(luò)地址的驗證是通過對輸入字符的循環(huán)匹配做到的,并沒有采取正則表達式的做法。其匹配過程中還依賴于其它的 Java 方法。

3.目前網(wǎng)絡(luò)上流傳的 IPv6 網(wǎng)絡(luò)地址驗證的正則表達式通常都只能涵蓋部分地址格式,而且表達式冗長難讀,非常不易于理解。

基于通用性考慮,以及為了使驗證方法盡量簡單易讀,筆者嘗試將 IPv6 網(wǎng)絡(luò)地址的格式簡單分類以后,使用多個正則表達式進行驗證。

這種做法兼顧了通用性(基于正則表達式,所以方便用各種不同的編程語言進行實現(xiàn)),以及易讀性(每個獨立的正則表達式相對簡短);并且根據(jù)測試,支持目前所有的 IPv6 網(wǎng)絡(luò)地址格式類型,尚未發(fā)現(xiàn)例外。

以下是筆者用 Java 編寫的對于 IPv6 網(wǎng)絡(luò)地址的驗證方法。此算法可被簡單地用其它編程語言仿照重寫。

清單 1. 驗證地址

  1. //IPv6 address validator matches these IPv6 formats  
  2. //::ffff:21:7.8.9.221 | 2001:0db8:85a3:08d3:1319:8a2e:0370:7344   
  3. //| ::8a2e:0:0370:7344 | 2001:0db8:85a3:08d3:1319:8a2e:100.22.44.55   
  4. //| 2001:0db8::8a2e:100.22.44.55 | ::100.22.44.55 | ffff::  
  5. //And such addresses are invalid  
  6. //::8a2e:0:0370:7344.4 | 2001:idb8::111:7.8.9.111 | 2001::100.a2.44.55   
  7. //| :2001::100.22.44.55   
  8. public static boolean isIPV6Format(String ip) {  
  9.     ipip = ip.trim();  
  10.  
  11.     //in many cases such as URLs, IPv6 addresses are wrapped by []  
  12.     if(ip.substring(0, 1).equals("[") && ip.substring(ip.length()-1).equals("]"))   
  13.       
  14.         ipip = ip.substring(1, ip.length()-1);  
  15.  
  16.         return (1 < Pattern.compile(":").split(ip).length)  
  17.      //a valid IPv6 address should contains no less than 1,   
  18.      //and no more than 7 “:” as separators  
  19.             && (Pattern.compile(":").split(ip).length <= 8)  
  20.  
  21.      //the address can be compressed, but “::” can appear only once  
  22.             && (Pattern.compile("::").split(ip).length <= 2)  
  23.  
  24.      //if a compressed address  
  25.             && (Pattern.compile("::").split(ip).length == 2)  
  26.  
  27.             //if starts with “::” – leading zeros are compressed  
  28.             ? (((ip.substring(0, 2).equals("::"))    
  29.             ? Pattern.matches("^::([\\da-f]{1,4}(:)){0,4}(([\\da-f]{1,4}(:)[\\da-f]{1,4})  
  30.      |([\\da-f]{1,4})|((\\d{1,3}.){3}\\d{1,3}))", ip)  
  31.                 : Pattern.matches("^([\\da-f]{1,4}(:|::)){1,5}  
  32.   (([\\da-f]{1,4}(:|::)[\\da-f]{1,4})|([\\da-f]{1,4})  
  33.   |((\\d{1,3}.){3}\\d{1,3}))", ip)))  
  34.  
  35.   //if ends with "::" - ending zeros are compressed  
  36.                 : ((ip.substring(ip.length()-2).equals("::"))    
  37.                 ? Pattern.matches("^([\\da-f]{1,4}(:|::)){1,7}", ip)  
  38.                 : Pattern.matches("^([\\da-f]{1,4}:){6}(([\\da-f]{1,4}  
  39.   :[\\da-f]{1,4})|((\\d{1,3}.){3}\\d{1,3}))", ip));  
  40.     }}  

#p#

如何正規(guī)化 IPv6 地址

在網(wǎng)絡(luò)程序開發(fā)中,經(jīng)常使用 IP 地址來標(biāo)識一個主機,例如記錄終端用戶的訪問記錄等。由于 IPv6 具有有零壓縮地址等多種表示形式,因此直接使用 IPv6 地址作為標(biāo)示符,可能會帶來一些問題。為了避免這些問題,在使用 IPv6 地址之前,有必要將其正規(guī)化。除了通過我們熟知的正則表達式,筆者在開發(fā)過程中發(fā)現(xiàn)使用一個簡單的 Java API 也可以達到相同的效果。

清單 2. 正規(guī)化地址  

  1. InetAddress inetAddr = InetAddress.getByName(ipAddr);   
  2. ipAddr = inetAddr.getHostAddress();   
  3. System.out.println(ipAddr); 

InetAddress.getByName(String) 方法接受的參數(shù)既可以是一個主機名,也可以是一個 IP 地址字符串。我們輸入任一信息的合法 IPv6 地址,再通過 getHostAddress() 方法取出主機 IP 時,地址字符串 ipAddr 已經(jīng)被轉(zhuǎn)換為完整形式。例如輸入 2002:97b:e7aa::97b:e7aa,上述代碼執(zhí)行過后,零壓縮部分將被還原,ipAddr 變?yōu)?2002:97b:e7aa:0:0:0:97b:e7aa。

如何獲取本機 IPv6 地址

今天我們再來講講如何獲取本機 IPv6 地址有時為了能夠注冊 listener,開發(fā)人員需要使用本機的 IPv6 地址,這一地址不能簡單得通過 InetAddress.getLocalhost() 獲得。因為這樣有可能獲得諸如 0:0:0:0:0:0:0:1 這樣的特殊地址。使用這樣的地址,其他服務(wù)器將無法把通知發(fā)送到本機上,因此必須先進行過濾,選出確實可用的地址。以下代碼實現(xiàn)了這一功能,思路是遍歷網(wǎng)絡(luò)接口的各個地址,直至找到符合要求的地址。

清單 3. 獲取本機 IP 地址

  1. public static String getLocalIPv6Address() throws IOException {  
  2.     InetAddress inetAddress = null;  
  3.     Enumeration<NetworkInterface> networkInterfaces = NetworkInterface 
  4.         .getNetworkInterfaces();  
  5.     outer:   
  6.     while (networkInterfaces.hasMoreElements()) {  
  7.         Enumeration<InetAddress> inetAds = networkInterfaces.nextElement()  
  8.      .getInetAddresses();  
  9.         while (inetAds.hasMoreElements()) {  
  10.             inetAddress = inetAds.nextElement();  
  11.             //Check if it's ipv6 address and reserved address  
  12.             if (inetAddress instanceof Inet6Address   
  13.                 && !isReservedAddr(inetAddress)) {  
  14.                 break outer;  
  15.             }  
  16.         }  
  17.     }  
  18.  
  19.     String ipAddr = inetAddress.getHostAddress();  
  20.     // Filter network card No  
  21.     int index = ipAddr.indexOf('%');  
  22.     if (index > 0) {  
  23.         ipAddripAddr = ipAddr.substring(0, index);  
  24.     }  
  25.  
  26.     return ipAddr;  
  27. }  
  28.  
  29. /**  
  30.  * Check if it's "local address" or "link local address" or  
  31.  * "loopbackaddress"  
  32.  *   
  33.  * @param ip address  
  34.  *   
  35.  * @return result  
  36.  */  
  37. private static boolean isReservedAddr(InetAddress inetAddr) {  
  38.     if (inetAddr.isAnyLocalAddress() || inetAddr.isLinkLocalAddress()  
  39.         || inetAddr.isLoopbackAddress()) {  
  40.         return true;  
  41.     }  
  42.  
  43.     return false;  
  44. }   
  45.  

 為了支持 IPv6,Java 中增加了兩個 InetAddress 的子類:Inet4Address 和 Inet6Address。一般情況下這兩個子類并不會被使用到,但是當(dāng)我們需要分別處理不同的 IP 協(xié)議時就非常有用,在這我們根據(jù) Inet6Address 來篩選地址。

isReservedAddr() 方法過濾了本機特殊 IP 地址,包括“LocalAddress”,“LinkLocalAddress”和“LoopbackAddress”。讀者可根據(jù)自己的需要修改過濾標(biāo)準(zhǔn)。

另一個需要注意的地方是:在 windows 平臺上,取得的 IPv6 地址后面可能跟了一個百分號加數(shù)字。這里的數(shù)字是本機網(wǎng)絡(luò)適配器的編號。這個后綴并不是 IPv6 標(biāo)準(zhǔn)地址的一部分,可以去除。

IPv4/IPv6 雙環(huán)境下,網(wǎng)絡(luò)的選擇和測試

我們先看一下筆者所在的 IPv4/IPv6 開發(fā)測試環(huán)境及其配置方法。

筆者所處的 IPv4/IPv6 雙環(huán)境是一個典型的“6to4”雙棧網(wǎng)絡(luò),其中存在著一個 IPv6 到 IPv4 的映射機制,即任意一個 IPv6 地址 2002:92a:8f7a:100:a:b:c:d 在路由時會被默認(rèn)映射為 IPv4 地址 a.b.c.d,所以路由表只有一套。

在此環(huán)境內(nèi),IPv4 地址與 IPv6 地址的一一對應(yīng)是人工保證的。如果一臺客戶機使用不匹配的 IPv4 和 IPv6 雙地址,或者同時使用 DHCPv4 和 DHCPv6(可能會導(dǎo)致 IPv4 地址和 IPv6 地址不匹配),會導(dǎo)致 IPv6 的路由尋址失敗。

正因為如此,為了配置雙地址環(huán)境,我們一般使用 DHCPv4 來自動獲取 IPv4 地址,然后人工配置相對應(yīng)的 IPv6 地址。

#p#

Windows 系統(tǒng)

◆Windows 2000 及以下:不支持 IPv6
◆Windows 2003 和 Windows XP:使用 Windows 自帶的 netsh 命令行方式添加 IPv6 地址以及 DNS, 例如:C:\>netsh interface ipv6 add address “Local Area Connection” 2002:92a:8f7a:100:10:13:1:2 和 C:\>netsh interface ipv6 add dns “Local Area Connection” 2002:92a:8f7a:100:10::250
◆Windows 2008 和 Windows Vista:既可以使用 Windows 網(wǎng)絡(luò)屬性頁面進行配置,也可以使用類似 Windows 2003 和 Windows XP 的 netsh 命令行來配置
Linux 系統(tǒng) (以下是 IPv6 的臨時配置方法,即不修改配置文件,計算機重啟后配置失效)

◆Redhat Linux:最簡單的方法是使用 ifconfig 命令行添加 IPv6 地址,例如:ifconfig eth0 inet6 add 2002:92a:8f7a:100:10:14:24:106/96。
◆SUSE Linux:同上。
從實踐上講,由于 Java 的面向?qū)ο筇匦裕约?java.net 包對于 IP 地址的良好封裝,從而使得將 Java 應(yīng)用從 IPv4 環(huán)境移植到 IPv4/IPv6 雙環(huán)境,或者純 IPv6 環(huán)境變得異常簡單。通常我們需要做的僅是檢查代碼并移除明碼編寫的 IPv4 地址,用主機名來替代則可。

除此以外,對于一些特殊的需求,Java 還提供了 InetAddress 的兩個擴展類以供使用:Inet4Address 和 Inet6Address,其中封裝了對于 IPv4 和 IPv6 的特殊屬性和行為。然而由于 Java 的多態(tài)特性,使得程序員一般只需要使用父類 InetAddress,Java 虛擬機可以根據(jù)所封裝的 IP 地址類型的不同,在運行時選擇正確的行為邏輯。所以在多數(shù)情況下,程序員并不需要精確控制所使用的類型及其行為,一切交給 Java 虛擬機即可。

具體的新增類型及其新增方法,請具體參閱 Sun 公司的 JavaDoc。

另外,在 IPv4/IPv6 雙環(huán)境中,對于使用 Java 開發(fā)的網(wǎng)絡(luò)應(yīng)用,比較值得注意的是以下兩個 IPv6 相關(guān)的 Java 虛擬機系統(tǒng)屬性。

 

  1. java.net.preferIPv4Stack=<true|false>   
  2. java.net.preferIPv6Addresses=<true|false> 

preferIPv4Stack(默認(rèn) false)表示如果存在 IPv4 和 IPv6 雙棧,Java 程序是否優(yōu)先使用 IPv4 套接字。默認(rèn)值是優(yōu)先使用 IPv6 套接字,因為 IPv6 套接字可以與對應(yīng)的 IPv4 或 IPv6 主機進行對話;相反如果優(yōu)先使用 IPv4,則只不能與 IPv6 主機進行通信。

preferIPv6Addresses(默認(rèn) false)表示在查詢本地或遠(yuǎn)端 IP 地址時,如果存在 IPv4 和 IPv6 雙地址,Java 程序是否優(yōu)先返回 IPv6 地址。Java 默認(rèn)返回 IPv4 地址主要是為了向后兼容,以支持舊有的 IPv4 驗證邏輯,以及舊有的僅支持 IPv4 地址的服務(wù)。

總結(jié)

從計算機技術(shù)的發(fā)展、因特網(wǎng)的規(guī)律和網(wǎng)絡(luò)的傳輸速率來看,IPV4 都已經(jīng)不適用了。其中最主要的問題就是 IPV4 的 32 比特的 IP 地址空間已經(jīng)無法滿足迅速膨脹的因特網(wǎng)規(guī)模,但是 IPv6 的引入為我們解決了 IP 地址近乎枯竭的問題。本文對 IPv6 地址做了一些基本的介紹,著重介紹了如何使用 Java 開發(fā)兼容 IPv6 的網(wǎng)絡(luò)應(yīng)用程序,包括如何驗證 IPv6 地址,如何正規(guī)化 IPv6 地址的表示,如何獲取本機 IPv6 的地址,以及在 IPv4/IPv6 雙地址環(huán)境下的網(wǎng)絡(luò)選擇和測試,同時作者結(jié)合在日常工作中使用的 Java 代碼片段,希望呈現(xiàn)給讀者一個全方位的、具有較強實用性的文本介紹,也希望本文能給讀者在以后使用 Java 開發(fā) IPv6 兼容程序的過程中帶來一些幫助。

 

【編輯推薦】

  1. Java開發(fā)中常見的異常問題
  2. 十四種Java開發(fā)工具點評
  3. Java開發(fā)最容易犯的幾種錯誤
責(zé)任編輯:佚名 來源: developerWorks 中國
相關(guān)推薦

2010-05-26 17:50:40

IPv4與IPv6協(xié)議轉(zhuǎn)換

2010-06-02 10:13:45

IPv6網(wǎng)絡(luò)協(xié)議

2010-05-26 17:53:38

IPv4 to IPv

2010-09-17 16:42:26

IPv6網(wǎng)絡(luò)協(xié)議

2012-04-27 13:33:40

銳捷網(wǎng)絡(luò)物聯(lián)網(wǎng)IPv6

2010-06-01 14:00:02

IPv6協(xié)議

2010-05-26 18:34:04

IPv6網(wǎng)絡(luò)

2012-05-07 15:19:51

IPv6

2010-08-11 16:07:14

IPv6協(xié)議H3C

2015-02-03 14:56:55

2019-04-13 14:21:13

2013-03-13 09:56:24

IPv6IPv4NDP

2012-05-24 19:08:13

2010-06-02 10:20:36

IPv6業(yè)務(wù)

2010-06-01 14:55:35

IPv6組播

2010-05-28 17:07:52

IPv6商用網(wǎng)絡(luò)

2019-07-01 10:09:09

IPv6IPv4運營商

2022-02-23 11:22:18

IPv6十四五網(wǎng)絡(luò)

2010-05-26 17:37:50

IPv6網(wǎng)絡(luò)

2009-07-15 10:22:27

點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美激情一区二区 | 一区 | 久久中文字幕一区 | 日韩黄色免费 | 黄网站免费在线看 | 精品成人在线 | 亚洲一区中文字幕在线观看 | 操操日| 国产高清一区二区 | 亚洲精品成人网 | 久久精品亚洲精品国产欧美 | 久久精品国产一区二区三区不卡 | 日韩爱爱网站 | 欧洲视频一区二区 | 久久久久久久久国产精品 | 欧美高清视频一区 | av影音在线| 国产精品久久久久久一区二区三区 | 久久久久91 | 伊人网99 | 日本久久久一区二区三区 | 91日韩在线 | 欧美日韩在线一区二区 | 欧美a级成人淫片免费看 | 亚洲精品中文字幕在线观看 | av中文在线播放 | 久产久精国产品 | 久久久av中文字幕 | 黄毛片| 另类专区亚洲 | 日韩高清国产一区在线 | 国产成人99久久亚洲综合精品 | 中文字幕一区二区三区四区 | 亚洲成人免费电影 | 欧美精品v国产精品v日韩精品 | 日韩精品免费看 | 亚洲精品国产a久久久久久 中文字幕一区二区三区四区五区 | 国产精品欧美精品日韩精品 | 黄网站在线播放 | 亚洲国产精品一区二区第一页 | 精品久久久久久亚洲综合网 |