




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
使用Java開(kāi)發(fā)兼容IPv6的網(wǎng)絡(luò)應(yīng)用程序IPv6背景介紹目前我們使用的是第二代互聯(lián)網(wǎng)IPv4技術(shù),它的最大問(wèn)題是網(wǎng)絡(luò)地址資源有限,從理論上講,可以編址1600萬(wàn)個(gè)網(wǎng)絡(luò)、40億臺(tái)主機(jī)。但采用A、B、C三類(lèi)編址方式后,可用的網(wǎng)絡(luò)地址和主機(jī)地址的數(shù)目大打折扣,以至目前的IP地址近乎枯竭。網(wǎng)絡(luò)地址不足,嚴(yán)重地制約了全球互聯(lián)網(wǎng)的應(yīng)用和發(fā)展。一方面是地址資源數(shù)量的限制,另一方面是隨著電子技術(shù)及網(wǎng)絡(luò)技術(shù)的發(fā)展計(jì)算機(jī)網(wǎng)絡(luò)將進(jìn)入人們的日常生活,可能身邊的每一樣?xùn)|西都需要連入全球因特網(wǎng)。在這種網(wǎng)絡(luò)空間匱乏的環(huán)境下,IPv6應(yīng)運(yùn)而生。它的產(chǎn)生不但解決了網(wǎng)絡(luò)地址資源數(shù)量的問(wèn)題,同時(shí)也為除電腦外的設(shè)備連入互聯(lián)網(wǎng)在數(shù)量限制上掃清了障礙。如果說(shuō)IPv4實(shí)現(xiàn)的只是人機(jī)對(duì)話,那么IPv6則擴(kuò)展到任意事物之間的對(duì)話,它不僅可以為人類(lèi)服務(wù),還將服務(wù)于眾多硬件設(shè)備,如家用電器、傳感器、遠(yuǎn)程照相機(jī)、汽車(chē)等,它將是無(wú)時(shí)不在,無(wú)處不在的深入社會(huì)每個(gè)角落的真正的寬帶網(wǎng),它所帶來(lái)的經(jīng)濟(jì)效益也將非常巨大。當(dāng)然,IPv6并非十全十美、一勞永逸,不可能解決所有問(wèn)題。IPv6只能在發(fā)展中不斷完善,也不可能在一夜之間發(fā)生,過(guò)渡需要時(shí)間和成本,但從長(zhǎng)遠(yuǎn)看,IPv6有利于互聯(lián)網(wǎng)的持續(xù)和長(zhǎng)久發(fā)展。目前,國(guó)際互聯(lián)網(wǎng)組織已經(jīng)決定成立兩個(gè)專(zhuān)門(mén)工作組,制定相應(yīng)的國(guó)際標(biāo)準(zhǔn)。Java對(duì)IPv6的支持隨著IPv6越來(lái)越受到業(yè)界的重視,Java從1.4版開(kāi)始支持Linux和Solaris平臺(tái)上的IPv6。1.5版起又加入了Windows平臺(tái)上的支持。相對(duì)于C++,Java很好得封裝了IPv4和IPv6的變化部分,遺留代碼都可以原生支持IPv6,而不用隨底層具體實(shí)現(xiàn)的變化而變化。那么Java是如何來(lái)支持IPv6的呢?Java網(wǎng)絡(luò)棧會(huì)優(yōu)先檢查底層系統(tǒng)是否支持IPv6,以及采用的何種IP棧系統(tǒng)。如果是雙棧系統(tǒng),那它直接創(chuàng)建一個(gè)IPv6套接字(如圖1)。圖1.雙棧結(jié)構(gòu)對(duì)于分隔棧系統(tǒng),Java則創(chuàng)建IPv4/v6兩個(gè)套接字(如圖2)。如果是TCP客戶端程序,一旦其中某個(gè)套接字連接成功,另一個(gè)套接字就會(huì)被關(guān)閉,這個(gè)套接字連接使用的IP協(xié)議類(lèi)型也就此被固定下來(lái)。如果是TCP服務(wù)器端程序,因?yàn)闊o(wú)法預(yù)期客戶端使用的IP協(xié)議,所以IPv4/v6兩個(gè)套接字會(huì)被一直保留。對(duì)于UDP應(yīng)用程序,無(wú)論是客戶端還是服務(wù)器端程序,兩個(gè)套接字都會(huì)保留來(lái)完成通信。圖2.分隔棧結(jié)構(gòu)如何驗(yàn)證IPv6地址IPv6地址表示從IPv4到IPv6最顯著的變化就是網(wǎng)絡(luò)地址的長(zhǎng)度,IPv6地址為128位長(zhǎng)度,一般采用32個(gè)十六進(jìn)制數(shù),但通常寫(xiě)做8組每組4個(gè)十六進(jìn)制的形式。例如:2001:0db8:85a3:08d3:1319:8a2e:0370:7344是一個(gè)合法的IPv6地址。如果四個(gè)數(shù)字都是零,則可以被省略。2001:0db8:85a3:0000:1319:8a2e:0370:7344等同于2001:0db8:85a3::1319:8a2e:0370:7344。遵從這些規(guī)則,如果因?yàn)槭÷远霈F(xiàn)了兩個(gè)以上的冒號(hào)的話,可以壓縮為一個(gè),但這種零壓縮在地址中只能出現(xiàn)一次。因此:CODE:2001:0DB8:0000:0000:0000:0000:1428:57ab2001:0DB8:0000:0000:0000::1428:57ab2001:0DB8:0:0:0:0:1428:57ab2001:0DB8:0::0:1428:57ab2001:0DB8::1428:57ab都是合法的地址,并且他們是等價(jià)的。但2001::25de::cade是非法的。(因?yàn)檫@樣會(huì)使得搞不清楚每個(gè)壓縮中有幾個(gè)全零的分組)。同時(shí)前導(dǎo)的零可以省略,因此:2001:0DB8:02de::0e13等于2001:DB8:2de::e13。IPv6地址校驗(yàn)IPv4地址可以很容易的轉(zhuǎn)化為IPv6格式。舉例來(lái)說(shuō),如果IPv4的一個(gè)地址為2(十六進(jìn)制為0x874B2B34),它可以被轉(zhuǎn)化為0000:0000:0000:0000:0000:0000:874B:2B34或者::874B:2B34。同時(shí),還可以使用混合符號(hào)(IPv4-compatibleaddress),則地址可以為::2。在IPv6的環(huán)境下開(kāi)發(fā)Java應(yīng)用,或者移植已有的IPv4環(huán)境下開(kāi)發(fā)的Java應(yīng)用到IPv6環(huán)境中來(lái),對(duì)于IPv6網(wǎng)絡(luò)地址的驗(yàn)證是必須的步驟,尤其是對(duì)那些提供了UI(用戶接口)的Java應(yīng)用。所幸的是,從Java1.5開(kāi)始,Sun就增加了對(duì)IPv6網(wǎng)絡(luò)地址校驗(yàn)的Java支持。程序員可以通過(guò)簡(jiǎn)單地調(diào)用方法.util.IPAddressUtil.isIPv6LiteralAddress()來(lái)驗(yàn)證一個(gè)String類(lèi)型的輸入是否是一個(gè)合法的IPv6網(wǎng)絡(luò)地址。為了更深入一步地了解IPv6的網(wǎng)絡(luò)地址規(guī)范,及其驗(yàn)證算法,筆者參閱了一些材料,包括上文所述的方法.util.IPAddressUtil.isIPv6LiteralAddress()的源代碼,以及目前網(wǎng)絡(luò)上流傳的一些IPv6網(wǎng)絡(luò)地址的正則表達(dá)式,發(fā)現(xiàn):由于IPv6協(xié)議所允許的網(wǎng)絡(luò)地址格式較多,規(guī)范較寬松(例如零壓縮地址,IPv4映射地址等),所以導(dǎo)致了IPv6網(wǎng)絡(luò)地址的格式變化很大。Java對(duì)于IPv6網(wǎng)絡(luò)地址的驗(yàn)證是通過(guò)對(duì)輸入字符的循環(huán)匹配做到的,并沒(méi)有采取正則表達(dá)式的做法。其匹配過(guò)程中還依賴于其它的Java方法。目前網(wǎng)絡(luò)上流傳的IPv6網(wǎng)絡(luò)地址驗(yàn)證的正則表達(dá)式通常都只能涵蓋部分地址格式,而且表達(dá)式冗長(zhǎng)難讀,非常不易于理解?;谕ㄓ眯钥紤],以及為了使驗(yàn)證方法盡量簡(jiǎn)單易讀,筆者嘗試將IPv6網(wǎng)絡(luò)地址的格式簡(jiǎn)單分類(lèi)以后,使用多個(gè)正則表達(dá)式進(jìn)行驗(yàn)證。這種做法兼顧了通用性(基于正則表達(dá)式,所以方便用各種不同的編程語(yǔ)言進(jìn)行實(shí)現(xiàn)),以及易讀性(每個(gè)獨(dú)立的正則表達(dá)式相對(duì)簡(jiǎn)短);并且根據(jù)測(cè)試,支持目前所有的IPv6網(wǎng)絡(luò)地址格式類(lèi)型,尚未發(fā)現(xiàn)例外。以下是筆者用Java編寫(xiě)的對(duì)于IPv6網(wǎng)絡(luò)地址的驗(yàn)證方法。此算法可被簡(jiǎn)單地用其它編程語(yǔ)言仿照重寫(xiě)。清單1.驗(yàn)證地址CODE://IPv6addressvalidatormatchestheseIPv6formats//::ffff:21:21|2001:0db8:85a3:08d3:1319:8a2e:0370:7344//|::8a2e:0:0370:7344|2001:0db8:85a3:08d3:1319:8a2e:5//|2001:0db8::8a2e:5|::5|ffff:://Andsuchaddressesareinvalid//::8a2e:0:0370:7344.4|2001:idb8::111:11|2001::100.a2.44.55//|:2001::5publicstaticbooleanisIPV6Format(Stringip){ip=ip.trim();//inmanycasessuchasURLs,IPv6addressesarewrappedby[]return(1<Ppile(":").split(ip).length)//avalidIPv6addressshouldcontainsnolessthan1,//andnomorethan7“:”asseparators&&(Ppile(":").split(ip).length<=8)//theaddresscanbecompressed,but“::”canappearonlyonce&&(Ppile("::").split(ip).length<=2)//ifacompressedaddress&&(Ppile("::").split(ip).length==2)//ifstartswith—leadingzerosarecompressed?(((ip.substring(0,2).equals("::"))?Pattern.matches("入::([\\da-f]{1,4}(:)){0,4}(([\\da-f]{1,4}(:)[\\da-f]{1,4})|([\\da-f]{1,4})|((\\d{1,3}.){3}\\d{1,3}))",ip):Pattern.matches("入([\\da-f]{1,4}(:|::)){1,5}(([\\da-f]{1,4}(:|::)[\\da-f]{1,4})|([\\da-f]{1,4})|((\\d{1,3}.){3}\\d{1,3}))",ip)))//ifendswith"::"-endingzerosarecompressed:((ip.substring(ip.length()-2).equals("::"))?Pattern.matches("入([\\da-f]{1,4}(:|::)){1,7}",ip):Pattern.matches("入([\\da-f]{1,4}:){6}(([\\da-f]{1,4}:[\\da-f]{1,4})|((\\d{1,3}.){3}\\d{1,3}))",ip));}}如何正規(guī)化IPv6地址在網(wǎng)絡(luò)程序開(kāi)發(fā)中,經(jīng)常使用IP地址來(lái)標(biāo)識(shí)一個(gè)主機(jī),例如記錄終端用戶的訪問(wèn)記錄等。由于IPv6具有有零壓縮地址等多種表示形式,因此直接使用IPv6地址作為標(biāo)示符,可能會(huì)帶來(lái)一些問(wèn)題。為了避免這些問(wèn)題,在使用IPv6地址之前,有必要將其正規(guī)化。除了通過(guò)我們熟知的正則表達(dá)式,筆者在開(kāi)發(fā)過(guò)程中發(fā)現(xiàn)使用一個(gè)簡(jiǎn)單的JavaAPI也可以達(dá)到相同的效果。清單2.正規(guī)化地址CODE:InetAddressinetAddr=InetAddress.getByName(ipAddr);ipAddr=inetAddr.getHostAddress();System.out.println(ipAddr);InetAddress.getByName(String)方法接受的System.out.println(ipAddr);參數(shù)既可以是一個(gè)主機(jī)名,也可以是一個(gè)IP地址字符串。我們輸入任一信息的合法IPv6地址,再通過(guò)getHostAddress()方法取出主機(jī)IP時(shí),地址字符串ipAddr已經(jīng)被轉(zhuǎn)換為完整形式。例如輸入2002:97b:e7aa::97b:e7aa,上述代碼執(zhí)行過(guò)后,零壓縮部分將被還原,ipAddr變?yōu)?002:97b:e7aa:0:0:0:97b:e7aa。如何獲取本機(jī)IPv6地址有時(shí)為了能夠注冊(cè)listener,開(kāi)發(fā)人員需要使用本機(jī)的IPv6地址,這一地址不能簡(jiǎn)單得通過(guò)InetAddress.getLocalhost()獲得。因?yàn)檫@樣有可能獲得諸如0:0:0:0:0:0:0:1這樣的特殊地址。使用這樣的地址,其他服務(wù)器將無(wú)法把通知發(fā)送到本機(jī)上,因此必須先進(jìn)行過(guò)濾,選出確實(shí)可用的地址。以下代碼實(shí)現(xiàn)了這一功能,思路是遍歷網(wǎng)絡(luò)接口的各個(gè)地址,直至找到符合要求的地址。清單3.獲取本機(jī)IP地址CODE:InetAddressinetAddr=InetAddress.getByName(ipAddr);ipAddr=inetAddr.getHostAddress();System.out.println(ipAddr);InetAddress.getByName(String)方法接受的參數(shù)既可以是一個(gè)主機(jī)名,也可以是一個(gè)IP地址字符串。我們輸入任一信息的合法IPv6地址,再通過(guò)getHostAddress()方法取出主機(jī)IP時(shí),地址字符串ipAddr已經(jīng)被轉(zhuǎn)換為完整形式。例如輸入2002:97b:e7aa::97b:e7aa,上述代碼執(zhí)行過(guò)后,零壓縮部分將被還原,ipAddr變?yōu)?002:97b:e7aa:0:0:0:97b:e7aa。如何獲取本機(jī)IPv6地址有時(shí)為了能夠注冊(cè)listener,開(kāi)發(fā)人員需要使用本機(jī)的IPv6地址,這一地址不能簡(jiǎn)單得通過(guò)InetAddress.getLocalhost()獲得。因?yàn)檫@樣有可能獲得諸如0:0:0:0:0:0:0:1這樣的特殊地址。使用這樣的地址,其他服務(wù)器將無(wú)法把通知發(fā)送到本機(jī)上,因此必須先進(jìn)行過(guò)濾,選出確實(shí)可用的地址。以下代碼實(shí)現(xiàn)了這一功能,思路是遍歷網(wǎng)絡(luò)接口的各個(gè)地址,直至找到符合要求的地址。清單3.獲取本機(jī)IP地址#div_codeimg{border:0px;}<!--CodehighlightingproducedbyActiproCodeHighlighter(freeware)http://www.CodeH/-->publicstaticStringgetLocalIPv6Address()throwsIOException{InetAddressinetAddress=null;Enumeration<NetworkInterface>networkInterfaces=NetworkInterface.getNetworkInterfaces();outer:while(networkInterfaces.hasMoreElements()){Enumeration<InetAddress>inetAds=networkInterfaces.nextElement().getInetAddresses();while(inetAds.hasMoreElements()){inetAddress=inetAds.nextElement();//Checkifit'sipv6addressandreservedaddressif(inetAddressinstanceofInet6Address&&!isReservedAddr(inetAddress)){breakouter;}}}StringipAddr=inetAddress.getHostAddress();//FilternetworkcardNointindex=ipAddr.indexOf('%');if(index>0){ipAddr=ipAddr.substring(0,index);}returnipAddr;}/***Checkifit's"localaddress"or"linklocaladdress"or*"loopbackaddress"**@paramipaddress**@returnresult*/privatestaticbooleanisReservedAddr(InetAddressinetAddr){if(inetAddr.isAnyLocalAddress()||inetAddr.isLinkLocalAddress()||inetAddr.isLoopbackAddress()){returntrue;}returnfalse;}為了支持IPv6,Java中增加了兩個(gè)InetAddress的子類(lèi):Inet4Address和Inet6Address。一般情況下這兩個(gè)子類(lèi)并不會(huì)被使用到,但是當(dāng)我們需要分別處理不同的IP協(xié)議時(shí)就非常有用,在這我們根據(jù)Inet6Address來(lái)篩選地址isReservedAddr()方法過(guò)濾了本機(jī)特殊IP地址,包括“LocalAddress",“LinkLocalAddress"和“LoopbackAddress"。讀者可根據(jù)自己的需要修改過(guò)濾標(biāo)準(zhǔn)。另一個(gè)需要注意的地方是:在windows平臺(tái)上,取得的IPv6地址后面可能跟了一個(gè)百分號(hào)加數(shù)字。這里的數(shù)字是本機(jī)網(wǎng)絡(luò)適配器的編號(hào)。這個(gè)后綴并不是IPv6標(biāo)準(zhǔn)地址的一部分,可以去除。IPv4/IPv6雙環(huán)境下,網(wǎng)絡(luò)的選擇和測(cè)試我們先看一下筆者所在的IPv4/IPv6開(kāi)發(fā)測(cè)試環(huán)境及其配置方法。筆者所處的IPv4/IPv6雙環(huán)境是一個(gè)典型的“6to4”雙棧網(wǎng)絡(luò),其中存在著一個(gè)IPv6到IPv4的映射機(jī)制,即任意一個(gè)IPv6地址2002:92a:8f7a:100:a:b:c:d在路由時(shí)會(huì)被默認(rèn)映射為IPv4地址a.b.c.d,所以路由表只有一套。在此環(huán)境內(nèi),IPv4地址與IPv6地址的——對(duì)應(yīng)是人工保證的。如果一臺(tái)客戶機(jī)使用不匹配的IPv4和IPv6雙地址,或者同時(shí)使用DHCPv4和DHCPv6(可能會(huì)導(dǎo)致IPv4地址和IPv6地址不匹配),會(huì)導(dǎo)致IPv6的路由尋址失敗。正因?yàn)槿绱?,為了配置雙地址環(huán)境,我們一般使用DHCPv4來(lái)自動(dòng)獲取IPv4地址,然后人工配置相對(duì)應(yīng)的IPv6地址。Windows系統(tǒng)Windows2000及以下:不支持IPv6Windows2003和WindowsXP:使用Windows自帶的netsh命令行方式添加IPv6地址以及DNS,例如:C:\>netshinterfaceipv6addaddress“LocalAreaConnection"2002:92a:8f7a:100:10:13:l:2和C:\>netshinterfaceipv6adddns“LocalAreaConnection”2002:92a:8f7a:100:10::250Windows2008和WindowsVista:既可以使用Windows網(wǎng)絡(luò)屬性頁(yè)面進(jìn)行配置,也可以使用類(lèi)似Windows2003和WindowsXP的netsh命令行來(lái)配置Linux系統(tǒng)(以下是IPv6的臨時(shí)配置方法,即不修改配置文件,計(jì)算機(jī)重啟后配置失效)RedhatLinux:最簡(jiǎn)單的方法是使用ifconfig命令行添加IPv6地址,例如:ifconfigeth0inet6add2002:92a:8f7a:100:10:14:24:106/96。SUSELinux:同上。從實(shí)踐上講,由于Java的面向?qū)ο筇匦裕约鞍鼘?duì)于IP地址的良好封裝,從而使得將Java應(yīng)用從IPv4環(huán)境移植到IPv4/IPv6雙環(huán)境,或者純IPv6環(huán)境變得異常簡(jiǎn)單。通常我們需要做的僅是檢查代碼并移除明碼編寫(xiě)的IPv4地址,用主機(jī)名來(lái)替代則可。除此以外,對(duì)于一些特殊的需求,Java還提供了InetAddress的兩個(gè)擴(kuò)展類(lèi)以供使用:Inet4Address和Inet6Address,其中封裝了對(duì)于IPv4和IPv6的特殊屬性和行為。然而由于Java的多態(tài)特性,使得程序員一般只需要使用父類(lèi)InetAddress,Java虛擬機(jī)可以根據(jù)所封裝的IP地址類(lèi)型的不同,在運(yùn)行時(shí)選擇正確的行為邏輯。所以在多數(shù)情況下,程
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度職業(yè)教育培訓(xùn)機(jī)構(gòu)導(dǎo)師聘用合同
- 2025年度綠色能源合資項(xiàng)目合同范本
- 二零二五年度時(shí)尚服飾店門(mén)面房買(mǎi)賣(mài)協(xié)議
- 二零二五年度演出活動(dòng)主辦方觀眾免責(zé)協(xié)議模板
- 二零二五年度綜合醫(yī)院與專(zhuān)科醫(yī)院雙向轉(zhuǎn)診合作協(xié)議書(shū)
- 2025年度航空航天知識(shí)產(chǎn)權(quán)保護(hù)及保密合同
- 二零二五年度退股股權(quán)變更與風(fēng)險(xiǎn)控制協(xié)議
- 2025年度裝修公司拖欠工資無(wú)勞動(dòng)合同糾紛解決協(xié)議
- 二零二五年度金融科技內(nèi)部股東股權(quán)轉(zhuǎn)讓合同范本
- 二零二五年度石英石采礦權(quán)轉(zhuǎn)讓合同
- 2025年湖南司法警官職業(yè)學(xué)院?jiǎn)握新殬I(yè)傾向性測(cè)試題庫(kù)學(xué)生專(zhuān)用
- 2025山西國(guó)際能源集團(tuán)有限公司所屬企業(yè)社會(huì)招聘258人筆試參考題庫(kù)附帶答案詳解
- 醫(yī)學(xué)遺傳學(xué)教案-山東大學(xué)醫(yī)學(xué)遺傳學(xué)
- 四川德陽(yáng)歷年中考語(yǔ)文文言文閱讀試題12篇(含答案與翻譯)(截至2024年)
- 10以內(nèi)加減法口算趣味學(xué)習(xí)500題(可打?。?/a>
- 合唱之美知到智慧樹(shù)章節(jié)測(cè)試課后答案2024年秋山東航空學(xué)院
- 中國(guó)卒中學(xué)會(huì)急性缺血性卒中再灌注治療指南+2024解讀
- 海南省澄邁縣2024-2025學(xué)年七年級(jí)上學(xué)期期末考試地理試題(含答案)
- 人工智能應(yīng)用概論(第2版) 教案全套 莫少林
- 食品安全演練預(yù)案及流程
- 2025年蘇州衛(wèi)生職業(yè)技術(shù)學(xué)院高職單招職業(yè)技能測(cè)試近5年??及鎱⒖碱}庫(kù)含答案解析
評(píng)論
0/150
提交評(píng)論