1 / 48

網路程式設計 Network Programming Ch.5 JAVA 網路套件

網路程式設計 Network Programming Ch.5 JAVA 網路套件. 陳冠中 國立高雄應用科技大學. 章節大綱. 5-1 位址類別. 5-4 URL 類別. 5-2 SocketAddress 類別. 5-5 URLConnection 類別. 5-3 Socket 類別. 備註:可依進度點選小節. 5-1 位址類別. Java 網路相關的類別都配置於 java.net 套件中 利用這些 JDK 所提供的類別,開發人員得以不用花時間實作或撰寫基礎的網路類別,就可以快速設計出 具有網路通訊功能 的程式。

faith-hull
Download Presentation

網路程式設計 Network Programming Ch.5 JAVA 網路套件

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 網路程式設計Network ProgrammingCh.5 JAVA網路套件 陳冠中 國立高雄應用科技大學 2012 網路程式設計

  2. 章節大綱 5-1 位址類別 5-4URL類別 5-2SocketAddress類別 5-5URLConnection類別 5-3Socket類別 備註:可依進度點選小節

  3. 5-1 位址類別 • Java網路相關的類別都配置於java.net套件中 • 利用這些JDK所提供的類別,開發人員得以不用花時間實作或撰寫基礎的網路類別,就可以快速設計出具有網路通訊功能的程式。 • 有效率地使用這些類別是網路程式設計重要的基礎 • 本章的範例將實作如何連線至網站的程式 2012 網路程式設計

  4. 5-1 位址類別 • java.net.InetAddress類別 • Internet Address用來表示主機名稱或IP位址 • InetAddress類別可用在TCP與UDP網路程式設計 • 類別方法getByName(String host)會利用DNS主機查詢到主機名稱字串資料所註冊的IP位址: InetAddress addr= InetAddress.getByName("java.sun.com"); System.out.println(addr); ▌印出addr物件的結果為: java.sun.com/192.9.162.55 2012 網路程式設計

  5. 5-1 位址類別 • java.net.InetAddress類別 • 類別方法getLocalHost()可得到本機(localhost)的網址物件如下: • InetAddresslocal = InetAddress.getLocalHost(); • System.out.println(local); ▌印出local物件的結果為(每台主機執行結果不盡相同): core2/192.168.1.10 2012 網路程式設計

  6. 5-1 位址類別 • InetAddress • InetAddress類別並不以建構子的方式產生物件,而是使用它的「靜態方法(static methods)」,以下是較常使用的方法: • 1. static InetAddress getByName(String host) • 給予一個主機名稱host字串,將回傳一個經DNS查詢得到的位址物件(包括主機名稱與IP位址),如下範例: InetAddress addr= InetAddress.getByName("java.sun.com"); System.out.println(addr); ▌執行結果 java.sun.com/72.5.124.55 2012 網路程式設計

  7. 5-1 位址類別 • InetAddress • 2. static InetAddress getByAddress(byte[] addr) • 傳入一個以byte陣列表示的IP位址,得到一個位址物件。 • byte[] b = { 61 , 64 , 12 ,1 }; • InetAddressaddr = InetAddress.getByAddress(b); • System.out.println(addr); ▌執行結果 /61.64.12.1 2012 網路程式設計

  8. 5-1 位址類別 • InetAddress • 3. static InetAddress getLocalHost() • 取得本機的位址物件,如下: • InetAddressaddr= InetAddress.getLocalHost(); • System.out.println(addr); ▌執行結果 core2/169.254.4.238 2012 網路程式設計

  9. 5-1 位址類別 • InetAddress • 4. static InetAddress[] getAllByName(String host) • 取得主機名稱host字串所對應的所有IP位址物件,回傳位址物件的陣列,如果本機有多個IP位址,可以由此方法取得所有IP位址物件 • InetAddressaddr[] = InetAddress.getAllByName("shaoye-PC "); • for (inti=0; i<addr.length; i++){ • System.out.println(addr[i]);} 須改成實際主機名稱或FQDN www.yahoo.com.tw來說,yahoo.com.tw是Domain Name, 而www是Host Name ▌執行結果 ore2/169.254.4.238 core2/192.168.1.10 core2/192.168.174.1 core2/192.168.83.1 core2/fe80:0:0:0:e414:6431:bf2d:99b8%11 core2/fe80:0:0:0:14a6:270b:4ae5:8872%18 core2/fe80:0:0:0:2966:8bde:3f65:49ae%19 core2/fe80:0:0:0:886:d53a:7968:4ee%29 Yahoo!奇摩的FQDN: www.yahoo.com.tw 2012 網路程式設計

  10. 5-1 位址類別 • 取得本機的網路介面-NetworkInterface • JDK第6版內的java.net.NetworkInterface類別提供更詳細的網路卡資訊 • 網路卡eth0、eth1的方式命名 • 利用NetworkInterface類別的靜態方法可以得到網路介面的物件 2012 網路程式設計

  11. 5-1 位址類別 • 取得本機的網路介面-NetworkInterface • 1. static NetworkInterface getByName(String name) • 傳入一個網路介面名稱,可得到符合該名稱的物件,若無符合的名稱,則回傳null值,如下: • NetworkInterface eth = NetworkInterface.getByName("eth0"); • System.out.println(eth.getName()); • System.out.println(eth.getDisplayName()); ▌執行結果 eth0 Marvell Yukon 88E8001/8003/8010 PCI Gigabit Ethernet Controller 2012 網路程式設計

  12. 5-1 位址類別 • 取得本機的網路介面-NetworkInterface • 2. static Enumeration<NetworkInterface> getNetworkInterfaces() • 若想列出主機上所有的網路介面,可使用本方法得到列舉集合,以下範例程式可列出所有的網路介面的名稱與其是否啟用: • Enumeration<NetworkInterface> ifs = NetworkInterface.getNetworkInterfaces(); • while (ifs.hasMoreElements()){ • NetworkInterface ni = ifs.nextElement(); • System.out.println(ni.getName()); • System.out.println(" 是否正啟用:"+ni.isUp()); • } 2012 網路程式設計

  13. 5-1 位址類別 • ▌執行結果 • lo • 是否正啟用:true • net0 • 是否正啟用:false • net1 • 是否正啟用:false • net2 • 是否正啟用:false • net3 • 是否正啟用:false • ppp0 • 是否正啟用:false • eth0 • 是否正啟用:false • eth1 • 是否正啟用:false • eth2 • 是否正啟用:false 2012 網路程式設計

  14. 5-1 位址類別 • 常用的方法有: • String getName():取得網路介面的名稱字串,通常有eth0,eth1或 net1,net2或ppp1,ppp2等。 • String getDisplayName():取得網路介面的易讀名稱字串,一般人較容易瞭解的名稱,如網路介面的品牌與型號。 • boolean isUp():回傳布林值,以辨認該網路介面是否處於啟用狀態。 • int getMTU():得到該網路介面的「最大傳輸單位值(MTU)」。 • boolean isVirtual():回傳該網路介面是否為一個虛擬裝置,又稱為子介面(subinterface)。 • getSubInterfaces():得到該網路介面下的所有虛擬裝置。 2012 網路程式設計

  15. 5-2SocketAddress類別 • SocketAddress抽象類別定義了一個未綁定任何通訊協定的規格,讓其他類別繼承。 • 如TCP/IP協定所使用的InetSocketAddress類別,它是代表一個網址,而一個網址內有IP位址與埠號(port)兩項資訊。 2012 網路程式設計

  16. 5-3Socket類別 • java.net.Socket類別常用來建立Client/Server型的連線 • 建立連線後就可利用輸出入串流物件進行資料傳輸 • TCP程式設計是先利用Socket類別,再利用串流物件 2012 網路程式設計

  17. 5-3Socket類別 • 建立Socket物件 • 此例必須啟動本機telnet service才能連線至主機 • 最常使用的建構子是給予主機名稱字串與遠端主機的埠號(port),由於主機名稱不一定正確,或是遠端主機可能有無法連線的情況,因此使用Socket建構子時,必須為其處理UnknownHostException與IOException例外,當連線失敗時將會顯示「主機連線失敗」,如下以try...catch處理之: • try { • Socket ptt = new Socket("localhost ", 23); • }catch (UnknownHostException ex){ • System.out.println("主機連線失敗"); • }catch (IOException ex){ • System.out.println("傳輸失敗"); • } 2012 網路程式設計

  18. 如何啟動windows XP telnet service • 1. 在 [控制台] 中,連按兩下 [系統管理工具]。2. 按兩下 [服務]。3. 按兩下 [Telnet]。4. [啟動類型] 選擇 [手動]。5. 按一下 [套用]。6. 按一下 [啟動]。7. 按一下 [確定]。 2012 網路程式設計

  19. 如何啟動windows 7 telnet service • Step 1. 控制台程式和功能(左邊)開啟或關閉Windows功能將Telnet用戶端 及 Telnet伺服端 啟動(勾選) • Step 2.“開始”“運行”,輸入servcies.msc打開服務管理器。找到並雙擊Telnet服務項,設置其啟動方式為“手動”(更安全,只在需要的時候才啟用) 2012 網路程式設計

  20. 5-3Socket類別 • 建立Socket物件 • 當程式執行到Socket建構子時,會直接嘗試與遠端主機的埠號建立TCP連線。Socket類別建構子還可以使用InetAddress物件與遠端主機建立連線,程式範例如下: • try { • InetAddress addr = InetAddress.getByName("localhost"); • Socket ptt = new Socket(addr, 23); • System.out.println(“主機連線成功!!"); • }catch (UnknownHostException ex){ • System.out.println("主機連線失敗"); • } catch (IOException ex){ • System.out.println("傳輸失敗"); • } 2012 網路程式設計

  21. 2012 網路程式設計

  22. 5-3Socket類別 • 建立Socket物件 • Socket類別中有方法會使用到SocketAddress物件,都是有關本地與遠端位址與埠號,例如: • public SocketAddress getLocalSocketAddress():取得本地的SocketAddress物件。 • public SocketAddress getRemoteSocketAddress():取得連線遠端的SocketAddress物件。 • public void bind(SocketAddress bindpoint):將Socket物件綁定一個本地位址。 • public void connect(SocketAddress endpoint):使用SocketAddress物件內的資訊,連線至其指定的遠端主機 • public void connect(SocketAddress endpoint, int timeout):使用SocketAddress物件內的資訊,連線至其指定的遠端主機,並訂定連線超過某一時間無法成功時,即告失敗。timeout值以毫秒(千分之一秒)為單位。 2012 網路程式設計

  23. 5-3Socket類別 • 本範例使用上述的幾個方法,由local主機的port 2222出發的連線,連至remote主機ptt.cc的port 23。 • 由於使用了timeout值很短(5亳秒),因此本範例執行後會throw一個java.net.SocketTimeoutException例外(5亳秒5000亳秒): 01 package com.ch05; 02 03 import java.io.IOException; 04 import java.io.net.InetSocketAddress; 05 import java.net.Socket; 06 07 public class ch5Practice{ 08 public static void main(String[] args) throws IOException { 09 Socket socket = new Socket(); 10 InetSocketAddress local = new InetSocketAddress(2222); 11 InetSocketAddress ad = new InetSocketAddress(“ptt.cc”,443); 12 socket.bind(local); 13 System.out.println(“本地埠號:“+socket.getLocalPort()); 14 socket.connect(ad,5); 15 } 16 } 2012 網路程式設計

  24. 5-3-2Socket的方法 • Socket的方法 • public InetAddress getInetAddress()取得連線至遠端的位址物件。 • public int getPort()取得連線至遠端的埠號值。 • public InetAddress getLocalAddress()取得此連線在本地端的位址物件。 • public int getLocalPort()取得此連線在本地端的埠號值。 • public InputStream getInputStream()取得此連線的輸入資料流物件,以供後續讀取遠端傳送來的資料。 • public OutputStream getOutputStream()取得此連線的輸出資料流物件,以供後續傳送資料至遠端主機。 • public void close()關閉此連線。 2012 網路程式設計

  25. 5-3-2Socket的方法 • 01 package com.ch05; • 02 • 03 import java.io.IOException; • 06 import java.net.Socket; • 07 import java.net.UnknownHostException; • 08 • 09 public class SimpleSocket2 { • public static void main(String[] args) throws UnknowHostException, IOException { • Socket socket = new Socket(“www.google.com”,80); • 12 System.out.println(“本地位址:“ + socket.getLocalAddress()); • 13 System.out.println(“本地埠號:“ + socket.getLocalPort()); • 14 System.out.println(“遠端位址:“ + socket.getInetAddress()); • 15 System.out.println(“遠端埠號:“ + socket.getPort()); • 16 } • 17 } 2012 網路程式設計

  26. 5-3Socket類別 • 取得輸出入串流 • 當Socket物件成功建立後,客戶端(程式)與伺服器端(遠端主機)可開始進行資料的傳輸,此時要利用java.io套件庫內的串流類別(Stream),如簡單的InputStream/OutputStream或支援亞洲字元的Reader/Writer類別。 • Socket類別可比喻為插頭,而串流類則是由插頭衍生出來的電線,如下圖: 2012 網路程式設計

  27. 5-3Socket類別 2012 網路程式設計

  28. 5-3Socket類別 • 01 package com.ch05; • 02 • 03 import java.io.IOException; • 04 import java.io.InputStream; • 05 import java.io.OutputStream; • 06 import java.net.Socket; • 07 import java.net.UnknownHostException; • 08 • 09 public class SimpleTCP { • 10 public static void main(String[] args) { • 11 try { • 12 Socket ptt = new Socket("ptt.cc",443); • 13 InputStream in = ptt.getInputStream(); • OutputStream out = ptt.getOutputStream(); • System.out.println(“主機連線成功"); • 16 } catch (UnknownHostException e) { • 17 System.out.println("主機連線失敗"); • 18 } catch (IOException e) { • 19 System.out.println("傳輸失敗"); • 20 } • 21 } • 22 } 由Socket物件取得串流物件的方法為getInputStream與getInputStream 2012 網路程式設計

  29. 5-3Socket類別 • 5-3-4傳輸資料 • 取得輸出入串流物件後,便可利用串流物件提供的方法,進行資料的接收與傳送 • 資料接收以InputStream的read()方法 • 資料傳送以OutputStream的write()方法將資料傳送至遠端主機 • 接收遠端主機傳來一個byte值,收到的資料以整數int的方式: • 傳送一個byte值,以整數int資料型態傳送出去,並利用flush()方去確認資料不會留存於本地端的緩衝區,送達到遠端主機: • Int data = in.read(); • out.write(65); • out.flush(); 2012 網路程式設計

  30. 5-3Socket類別 • 關閉連線 • 當程式執行至main方法的最後時,會結束整個程式,並自動將程式中使用到的變數、物件等資源釋出,但讀者在設計網路連線相關程式時,最好利用串流物件與通道物件的close()方法,主動地關閉其資源並斷線,以免遠端主機花費多餘的資源在等待斷線訊號。 • 呼叫InputStream物件in的方法close(),關閉輸入串流: • 呼叫OutSteam物件out的方法close(),關閉輸出串流: • 呼叫Socket物件ss的方法close(),關閉本機與遠端主機的連線: • In.close(); • out.close(); • ss.close(); 2012 網路程式設計

  31. 5-3Socket類別 • Telnet程式範例 • 利用連線至PTT BBS,取得遠端主機傳輸資料為例,程式中在連線成功後,以for迴圈從BBS站(遠端主機)讀取10個位元組,並印出資料: Socket ptt = new Socket("ptt.cc",23); InputStream in = ptt.getInputStream(); OutputStream out = ptt.getOutputStream(); int data = 0; for (int i=0; i<10; i++){ data = in.read(); System.out.print(data + " "); } in.close(); out.close(); ptt.close(); ▌執行結果 32 32 32 32 32 163 187 32 32 32 2012 網路程式設計

  32. 5-3Socket類別 • Telnet程式範例 • 上述執行的結果得到遠端主機先傳來5個空白(ASCII碼為空白),再收到一個Big5碼中文字(163 187),再收到3個空白。其實遠端主機後續仍有資料等待傳送至本機,但本例只用for迴圈讀到10個位元組就斷線了。 • telnet程式執行 telnet ppt.cc 2012 網路程式設計

  33. 5-4URL類別 • URL(Universal Resource Locator)稱為網址 • URL是用來上找到(定位)一個特定的網路資源,也是一個表示特定網際網路資源的國際標準 通訊協定://伺服器位址或名稱[:埠號]/路徑/檔名 • 例如:http://www.ibm.com/docs/abc.txt 2012 網路程式設計

  34. 5-4URL類別 • URL標準制定了以下常用的通訊協定 • http • 網頁通訊協定 • https • 加密傳送的網頁通訊協定 • ftp • 檔案傳輸協定 • file • 定位本地電腦上的檔案 2012 網路程式設計

  35. 5-4URL類別 • URL類別的建構子並不複雜,目的是要將一串包含資訊的字串轉換為URL物件,由於使用者傳入的網址並不一定正確地定位到特定資源,使用URL類別的建構子時皆需要處理例外(Malformed URLException),初學時可以在使用建構子的方法定義時,直接以throws關鍵字將該例外拋出。 2012 網路程式設計

  36. 5-4URL類別 • URL的建構子 • 1.URL(String spec) • 傳入一個URL字串,並產生一個URL物件,例如: • 2.URL(String proto, String host, int port, String file) • 將URL的四個要項分開為字串與整數,傳入URL類別建構子當成參數,並產生一個URL物件,例如: • 3.URL(String proto, String host, String file) • 使用預設的埠別,而需不傳入埠號參數,在URL物件中埠號的預設值為-1,代表使用該協定的預設埠號,若協定為ftp則預設使用21埠號,若協定為http則使用80埠號。 • URL url = new URL("http://snpy.org/net/index.html"); • URL url = new URL("http", "snpy.org", 80, "/net/index.html"); 2012 網路程式設計

  37. 5-4URL類別 • URL類別的方法 • String getProtocol():取得URL物件內的協定,回傳值為字串格式。 • String getHost():取得URL物件內的主機資訊,回傳值為字串格式。 • String getPort():取得URL物件內的埠號值,回傳值為整數格式。 • String getPath():取得URL物件內的目錄資訊(包括檔案),回傳值為字串格式。 • String getFile():取得URL物件內的檔案名稱(包括目錄),回傳值為字串格式。 2012 網路程式設計

  38. 5-4URL類別 • URL類別的方法 • URLConnection openConnection():依照URL物件中的欄位資訊開啟該資源,並回傳與該資源的URLConnection連線物件,後續可進行資料的讀取與傳送。URLConnection類別將於下一節內容中詳述。 • InputStream openStream():依照URL物件中的欄位資訊開啟該資源,回傳連線後的輸入資源流InputStream,可快速讀取遠端資源中的資料。 2012 網路程式設計

  39. 5-4URL類別 2012 網路程式設計

  40. 5-5URLConnection類別 • URLConnection類別代表與該網際網路資源的實質連線 • 由實質連線中又可以得到輸入或輸出的資料流物件 • URL可以比喻為一張寫著住址的紙張,而URLConnection則是依照紙張上的資訊,建立起本機與遠端資源的橋樑 2012 網路程式設計

  41. 5-5URLConnection類別 • 取得網際網路資源 • 想要連線到下列網址,並取得該網址的資料: http://j.snpy.org/net/index.html 1. 產生URL物件 2. 取得URLConnection連線物件 3. 與該資源建立實質連線 4. 取得輸入資料流物件 URL url = new URL("http://j.snpy.org/net/index.html"); URLConnection conn = url.openConnection(); conn.connect(); InputStream in = conn.getInputStream(); 2012 網路程式設計

  42. 5-5URLConnection類別 • 取得網際網路資源 5. 以迴圈取得所有資料 6. 關閉資料流物件 • int data = in.read(); • while (data!=-1){ • System.out.print((char)data); • data = in.read(); • } in.close(); 2012 網路程式設計

  43. 5-5URLConnection類別 • 由於上例使用以byte為單位的串流物件(InputStream),若網際網路資源中含有中文時,則會將雙位元或UTF-8的資源拆開處理,而造成讀取資料不正確的亂碼,例如以下的執行結果: 2012 網路程式設計

  44. 5-5URLConnection類別 因此,必須要知道遠端資源的內容編碼方式後,才能夠以特定編碼格式處理資料而得到正確的資料。 • 標頭(Header)資訊 • 本節使用的URL內容是網頁協定,因此,要先取得HTTP協定的標頭(Header)資訊才能得知遠端資源的編碼格式 • 先利用URLConnection的方法getContentType()取得遠端資源的「內文(Content)」格式 得到: text/html; charset=UTF-8 • String type = conn.getContentType(); • System.out.println("內文格式:"+type); 2012 網路程式設計

  45. 5-5URLConnection類別 • 利用字串類別的方法lastIndexOf(“=“)找到最後一個等號,再以字串方法substring()取得編碼字串(“UTF-8“); • 之後便可利用Java輸出入套件的Reader類別讀取遠端資源並完成轉碼,得到正確的中文內容,完整程式碼: 2012 網路程式設計

  46. 2012 網路程式設計

  47. 5-5URLConnection類別 • 執行結果,正確得到”這是測試網頁”內文資料。 2012 網路程式設計

  48. Any Question? 2012 網路程式設計

More Related