神奇好望角 The Magical Cape of Good Hope

          庸人不必自擾,智者何需千慮?
          posts - 26, comments - 50, trackbacks - 0, articles - 11
            BlogJava :: 首頁 ::  :: 聯(lián)系 :: 聚合  :: 管理

          我竟然到現(xiàn)在才發(fā)現(xiàn)《Fundamental Networking in Java》這本神作,真有點無地自容的感覺。最近幾年做的都是所謂的企業(yè)級開發(fā),免不了和網(wǎng)絡(luò)打交道,但在實際工作中,往往會采用框架將底層細(xì)節(jié)和上層應(yīng)用隔離開,感覺就像是在一個 Word 模板表單里面填寫內(nèi)容,做出來也沒什么成就感。雖然沒有不使用框架的理由,但我還真是有點懷念當(dāng)初直接用套接字做網(wǎng)絡(luò)編程的日子,既能掌控更多東西,還可以學(xué)到更多知識,為研究框架的實現(xiàn)原理打基礎(chǔ)。閑話完畢,轉(zhuǎn)入今天的正題:IP(Internet Protocol,互聯(lián)網(wǎng)協(xié)議)。

          IP 基礎(chǔ)知識

          說到 IP,大多數(shù)人的第一反應(yīng)估計都是 IP 地址。其實 IP 是一種協(xié)議,IP 地址只是協(xié)議的一部分。《RFC 791 - INTERNET PROTOCOL》說:“互聯(lián)網(wǎng)協(xié)議是為在包交換計算機通信網(wǎng)絡(luò)的互聯(lián)系統(tǒng)中使用而設(shè)計的。”IP 包含三方面的功能:

          1. 用于查找主機的尋址系統(tǒng)
          2. 包格式的定義
          3. 傳輸和接收包的規(guī)則

          IP 的相關(guān) Java 類

          從 Java 的角度來看上面說到的三個功能,只有第一個是開發(fā)人員需要關(guān)心的。另外兩個都依賴底層系統(tǒng)的實現(xiàn),JDK 也沒有提供相關(guān)的類去操作。下面一一介紹 JDK 提供的用于處理 IP 地址的類。

          InetAddress

          此類用來表示 IP 地址,它有兩個子類:Inet4AddressInet6Address,分別用于處理 IPv4 和 IPv6 兩個版本。在實際應(yīng)用中,InetAddress 足以應(yīng)付絕大多數(shù)情況。它提供了一些靜態(tài)方法來構(gòu)造實例,能根據(jù)參數(shù)格式自動識別 IP 版本:

          public static InetAddress[] getAllByName(String host) throws UnknownHostException
          解析指定的主機地址,并返回其所有的 IP 地址;如果傳入 IP 地址字符串,則只會校驗格式,返回的數(shù)組也只包含一個代表該 IP 地址的實例。例如,想看看谷歌有多少馬甲的話,InetAddress.getAllByName("www.google.com") 就可以了。
          public static InetAddress getByAddress(byte[] addr) throws UnknownHostException
          用表示 IP 地址的字節(jié)數(shù)組(專業(yè)術(shù)語稱為“原始 IP 地址”)構(gòu)造一個實例。IPv4 地址必須是 4 個字節(jié),IPv6 必須 16 個。不常用。
          public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException
          用主機地址和原始 IP 地址構(gòu)造一個實例。此方法應(yīng)該慎用,因為它不會對主機名進(jìn)行解析。即使主機名為 IP 地址字符串,也不會檢查是否與字節(jié)數(shù)組一致。
          public static InetAddress getByName(String host) throws UnknownHostException
          用主機地址構(gòu)造一個實例,也可以直接傳入 IP 地址字符串,等同于 getAllByName(host)[0]
          public static InetAddress getLocalHost() throws UnknownHostException
          返回本機在網(wǎng)絡(luò)中的地址。
          public static InetAddress getLoopbackAddress()
          返回環(huán)回地址 127.0.0.1,不拋出異常,等同于 getByName("localhost")(不要和 getLocalHost() 搞混)。環(huán)回地址使主機能夠自己連接自己,常被用來對在同一臺機器上測試網(wǎng)絡(luò)應(yīng)用程序。在 IPv4 中,環(huán)回地址的網(wǎng)段為 127.0.0.0/8,通常用 127.0.0.1;IPv6 中只有一個 ::1

          接下來看看 InetAddress 中定義的部分實例方法:

          public byte[] getAddress()
          返回原始 IP 地址。
          public String getCanonicalHostName()
          返回全限定域名。這個方法可以用來探查實際的主機名,例如 InetAddress.getByName("www.google.com").getCanonicalHostName() 返回 we-in-f99.1e100.net
          public String getHostAddress()
          返回構(gòu)造時傳入的主機地址。
          public String getHostName()
          返回主機名。如果構(gòu)造時傳入的主機地址為 IP 地址字符串,則調(diào)用 getCanonicalHostName(),否則直接返回構(gòu)造時傳入的主機地址。
          public boolean isAnyLocalAddress()
          檢查是否為通配符地址。通配符地址為 0.0.0.0(IPv4)或 ::0(IPv6),代表所有的本地 IP 地址。例如,假設(shè)電腦有兩塊網(wǎng)卡,各有一個地址,如果想讓一個程序同時監(jiān)聽這兩個地址,就需要用通配符地址。
          public boolean isLinkLocalAddress()
          檢查是否為鏈路本地地址。IPv4 里定義為地址段 169.254.0.0/16,Ipv6 里是以 fe80::/64 為前綴的地址。在電腦沒聯(lián)網(wǎng)的時候查看本機 IP,就能看到這種地址。
          public boolean isLoopbackAddress()
          檢查是否為環(huán)回地址。
          public boolean isSiteLocalAddress()
          檢查是否為站點本地地址。站點本地地址這個名詞實際上已經(jīng)過時了,現(xiàn)在叫唯一本地地址。IPv4 中未定義;IPv6 中定義為地址段 fc00::/7。這些地址用于私有網(wǎng)絡(luò),例如企業(yè)內(nèi)部的局域網(wǎng)。

          此外還有一些有關(guān)多播地址的方法,暫時略過。

          JDK 默認(rèn)同時支持 IPv4 和 IPv6。如果只想使用一種,可以根據(jù)情況將 java.net.preferIPv4Stackjava.net.preferIPv6Addresses 這兩個系統(tǒng)屬性之一設(shè)為 true。兩個屬性的默認(rèn)值都為 false。一般來說不需要去驚動它們。

          SocketAddress

          該類是一個空殼,事實上應(yīng)用程序使用的是它的唯一子類 InetSocketAddress,目前還看不出這樣設(shè)計有什么意義。該類只不過在 InetAddress 的基礎(chǔ)上增加了一個端口屬性。

          NetworkInterface

          該類代表網(wǎng)絡(luò)接口,例如一塊網(wǎng)卡。一個網(wǎng)絡(luò)接口可以綁定一些 IP 地址。具有多個網(wǎng)絡(luò)接口的主機被稱為多宿主主機。下面的代碼可打印出所有本機網(wǎng)絡(luò)接口的信息:

          for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces())) {
              System.out.println(ni);
              for (InterfaceAddress ia : ni.getInterfaceAddresses()) {
                  System.out.println("\t" + ia);
              }
              System.out.println();
          }
              

          在我的筆記本上運行結(jié)果為:

          name:lo (Software Loopback Interface 1)
          	/127.0.0.1/8 [/127.255.255.255]
          	/0:0:0:0:0:0:0:1/128 [null]
          name:net0 (WAN Miniport (SSTP))
          name:net1 (WAN Miniport (L2TP))
          name:net2 (WAN Miniport (PPTP))
          name:ppp0 (WAN Miniport (PPPOE))
          name:eth0 (WAN Miniport (IPv6))
          name:eth1 (WAN Miniport (Network Monitor))
          name:eth2 (WAN Miniport (IP))
          name:ppp1 (RAS Async Adapter)
          name:net3 (WAN Miniport (IKEv2))
          name:net4 (Intel(R) Wireless WiFi Link 4965AGN)
          	/fe80:0:0:0:288a:2daf:3549:1811%11/64 [null]
          name:eth3 (Broadcom NetXtreme 57xx Gigabit Controller)
          	/10.140.1.133/24 [/10.140.1.255]
          	/fe80:0:0:0:78c7:e420:1739:f947%12/64 [null]
          name:net5 (Teredo Tunneling Pseudo-Interface)
          	/fe80:0:0:0:e0:0:0:0%13/64 [null]
          name:net6 (Bluetooth Device (RFCOMM Protocol TDI))
          name:eth4 (Bluetooth Device (Personal Area Network))
          name:eth5 (Cisco AnyConnect VPN Virtual Miniport Adapter for Windows x64)
          name:net7 (Microsoft ISATAP Adapter)
          	/fe80:0:0:0:0:5efe:a8c:185%17/128 [null]
          name:net8 (Microsoft ISATAP Adapter #2)
          name:net9 (Intel(R) Wireless WiFi Link 4965AGN-QoS Packet Scheduler-0000)
          name:eth6 (Broadcom NetXtreme 57xx Gigabit Controller-TM NDIS Sample LightWeight Filter-0000)
          name:eth7 (Broadcom NetXtreme 57xx Gigabit Controller-QoS Packet Scheduler-0000)
          name:eth8 (Broadcom NetXtreme 57xx Gigabit Controller-WFP LightWeight Filter-0000)
          name:eth9 (WAN Miniport (Network Monitor)-QoS Packet Scheduler-0000)
          name:eth10 (WAN Miniport (IP)-QoS Packet Scheduler-0000)
          name:eth11 (WAN Miniport (IPv6)-QoS Packet Scheduler-0000)
          name:net10 (Intel(R) Wireless WiFi Link 4965AGN-Native WiFi Filter Driver-0000)
          name:net11 (Intel(R) Wireless WiFi Link 4965AGN-TM NDIS Sample LightWeight Filter-0000)
          name:net12 (Intel(R) Wireless WiFi Link 4965AGN-WFP LightWeight Filter-0000)
          主站蜘蛛池模板: 海城市| 武平县| 宁波市| 二连浩特市| 宁安市| 冷水江市| 云龙县| 黔南| 色达县| 卢氏县| 三河市| 寻乌县| 乌拉特前旗| 如东县| 紫阳县| 资溪县| 祥云县| 娄底市| 清水河县| 赤水市| 汾阳市| 商城县| 基隆市| 绩溪县| 丹江口市| 洮南市| 宜丰县| 焦作市| 南雄市| 吉安市| 枞阳县| 漳平市| 溧水县| 涿鹿县| 延长县| 威远县| 全椒县| 张家口市| 炉霍县| 枣庄市| 汉阴县|