下載/瀏覽

Download Report

Transcript 下載/瀏覽

第18章 Java網路程式設計






18-1
18-2
18-3
18-4
18-5
18-6
網路的基礎
InetAddress類別的網域名稱轉換
URL類別的WWW服務
Socket類別的Internet服務
ServerSocket類別的伺服端程式
專案實例:建立Java聊天室
18-1 網路的基礎


18-1-1 TCP/IP通訊協定
18-1-2 Java的java.net套件
18-1 網路的基礎

「網路」(Network)是將不同廠牌的電
腦使用硬體裝置連接起來,以便分享資訊
或資源,但是網路電腦可能安裝不同的作
業系統,為了在電腦之間互通訊息,所以
需要一種電腦間的溝通語言,稱為「通訊
協定」(Prototocal),TCP/IP就是目前
最著名的通訊協定。
18-1-1 TCP/IP通訊協定-說明

TCP/IP是一組通訊協定的名稱,這是
Internet網際網路使用的標準通訊協定,
稱為一組是因為TCP/IP代表著十數種不同
的通訊協定,只是以該組協定中最重要的
兩個協定「TCP」(Transmission
Control Protocol)和「IP」(Internet
Protocol)為名。
18-1-1 TCP/IP通訊協定-IP位址
IP位址(IP Address)
 在Internet連接的每部電腦都擁有唯一位
址,Internet定址系統採用的方式是指定
每一台電腦一個號碼,稱為IP位址,長度
為4個位元組,以十進位格式表示,如下所
示:
dec3.dec2.dec1.dec0

上述IP位址的格式是在4個數字間使用小數
點「.」隔開,例如:HiNet郵件伺服器
ms2.hinet.net的IP位址是168.95.4.20。
18-1-1 TCP/IP通訊協定-網域名稱
網域名稱(Domain Name)
 為了管理Internet上成千上萬台電腦,網域名稱
是使用樹狀階層架構來分門別類,1983年「網域
名稱系統」(Domain Name System,縮寫為
DNS)使用樹狀階層結構對映網域名稱,在樹狀
階層結構的最上層分為九大類edu、com、gov、
mil、org、net、int、apra和國碼(依ISO標準
定義,例如:tw代表台灣)。
 例如:HiNet網站的IP位址是203.66.88.89,對
應的網域名稱為www.hinet.net。
18-1-2 Java的java.net套件-說明


網路的目的是為了資源分享,也就是將儲
存在不同電腦的檔案或資料進行交換,同
樣屬於檔案輸入和輸出的問題。
Java將網路通訊視為一種檔案I/O的串流,
當建立好電腦間的連線後,就使用第14章
的檔案串流來傳送和接收資料,只是檔案
是位在遠端的其它電腦。
18-1-2 Java的java.net套件-高階的
URL類別
高階的URL類別
 URL類別的物件是「WWW」(WorldWide Web)的URL網址,全名是「萬用
資源定址器」(Universal Resource
Locator),這個類別提供多種方法能夠剖
析URL網址,並且支援「HTTP」
(HyperText Transfer Protocol)通訊協
定,能夠連線Web網站且取得HTTP標頭資
料,或是直接下載網頁檔案。
18-1-2 Java的java.net套件-低階的
Socket類別
低階的Socket類別
 Socket類別是用來建立不同程式的網路連線,以
便Java程式可以透過網路連線到其它Java程式或
Internet服務,建立「主從架構」
(Client/Server)的網路應用程式。
 換句話說,如果2個程式使用TCP/IP進行通訊,
Java程式需要建立Socket物件來建立兩端的連線,
當建立好連線後,就可以使用輸入和輸出串流進
行資料傳輸。
18-2 InetAddress類別的網域名
稱轉換-說明
在java.net套件的InetAddress類別提供
網域名稱和IP位址轉換功能,可以查詢
DNS伺服器的對照表來進行網域名稱轉換。
DNS伺服器
 DNS伺服器類似現實生活的電話薄,在網
路上的DNS伺服器負責替我們從網域名稱
找到IP位址,反之,從IP位址找到網域名
稱,這和電話薄使用人名找電話,或是由
電話找人是相同的道理。

18-2 InetAddress類別的網域名
稱轉換-方法

在Java程式是使用InetAddress類別處理網域名
稱轉換,InetAddress類別的相關方法,如下表
所示:
方法
InetAddress getByName(String)
InetAddress getLocalHost()
InetAddress[]
getAllByName(String)
String getHostName()
String getHostAddress()
說明
使用參數 String 的網域名稱取得 IP 位
址的 InetAddress 物件
取得本機電腦的 InetAddress 物件
使用參數 String 的網域名稱取得所有 IP
位址的 InetAddress 物件陣列
取得 InetAddress 物件的網域名稱字串
取得 InetAddress 物件的 IP 位址字串
18-3 URL類別的WWW服務



18-3-1 剖析URL位址
18-3-2 URL物件的檔案下載
18-3-3 檢查網站的連線狀態
18-3 URL類別的WWW服務-說
明與建構子

URL類別的物件是WWW服務的資源物件,
每一個URL物件就是URL位址,也就是瀏
覽程式在【網址】欄輸入的位址字串。
URL類別的建構子,如下表所示:
建構子
說明
URL(String)
建立 URL 物件,如果只有 1 個參數 String,
URL(String,String,String) 就是完整的位址,3 個 String 參數分別為通
URL(String,String,int,String) 訊協定、主機和檔案路徑,參數 int 是埠號
18-3 URL類別的WWW服務-方
法

URL類別建立連線的相關方法,如下表所
示:
方法
InputStream openStream()
URLConnection
openConnection()
說明
建立 URL 連線取得輸入串流 InputStream
取得 URL 連線的 URLConnection 物件
18-3-1 剖析URL位址-說明

URL位址可以剖析成數種資訊,例如:微
軟的URL網址,如下所示:
http://www.microsoft.com:80/intdev#user
http://www.microsoft.com:80/intdev?user=
hueyan

上述URL網址範例在建立URL物件後,可
以使用相關方法剖析出部分資訊。
18-3-1 剖析URL位址-方法
方法
String getHost()
說明
取得伺服器網域名稱,傳回
www.microsoft.com
String getRef() 取得 URL 網址「#」符號後的部分,傳回#user
int getPort()
取得使用的通訊埠號,傳回 80
String getFile()
取得網頁檔案的名稱和路徑,傳回 intdev
String getQuery()
取得 URL 網址「?」符號後的部分,傳
回?user=hueyan
String getProtocol()
使用的通訊協定,傳回 http:
18-3-2 URL物件的檔案下載
URL物件在建立URL資源物件的連線後,就可以
使用openStream()方法開啟輸入串流
InputStream,換句話說,開啟的輸入串流能夠
直接下載網頁檔案,如下所示:
DataInputStream in = new
DataInputStream(url.openStream());
RandomAccessFile out = new
RandomAccessFile(args[1], "rw");
 上述程式碼在開啟URL物件的輸入串流後,建立
檔案輸出物件,將讀取的資料寫入檔案,以此例
是使用RadomAccessFile類別。

18-3-3 檢查網站的連線狀態-說明


瀏覽程式向伺服器提出瀏覽網頁的請求時,
伺服器回應請求的資料包含HTTP標頭資訊,
HTTP標頭提供網頁檔案的重要資訊。
例如:HTTP方法、檔案最後修改的日期/
時間等,只需檢查回應狀態,就可以知道
網站的連線狀態。
18-3-3 檢查網站的連線狀態-說明
URL物件的openConnection()方法可以建立連
線的URLConnection物件,在本節範例是使用
HttpURLConnection物件,這是
URLConnection支援HTTP連線的子類別,如下
所示:
HttpURLConnection http =
(HttpURLConnection)url.openConnection();
 上述程式碼在建立好連線的
HttpURLConnection物件後,就可以使用
HttpURLConnction類別的相關方法檢查連線狀
態和取得標頭欄位的資料。

18-3-3 檢查網站的連線狀態-方法

HttpURLConnction類別的相關方法檢查連線狀
態和取得標頭欄位的資料,如下表所示:
方法
void disconnect()
void
setFollowRedirects(boolean)
說明
中斷 HTTP 連線
設定是否啟動 HTTP 自動轉址,參數 boolean
為 true 表示是,false 為否
void setRequestMethod(String) 指定 URL 請求的 HTTP 方法,參數 String 是
HTTP 方法的 GET、POST、HEAD、
OPTIONS、PUT、DELETE 和 TRACE。方
法需要處理 ProtocolException 例外處理
int getResponseCode()
取得 HTTP 回應狀態碼
long getLastModified()
取得 last-modified 標頭欄位的資訊
String getContentType()
取得 content-type 標頭欄位的資訊
String getContentEncoding()
取得 content-encoding 標頭欄位的資訊
int getContentLength()
取得 content-length 標頭欄位的資訊
18-4 Socket類別的Internet服務




18-4-1
18-4-2
18-4-3
18-4-4
Daytime日期時間服務
HTTP的Web服務
SMTP寄送電子郵件
POP3檢查電子郵件
18-4 Socket類別的Internet服務說明與建構子

Socket類別可以透過TCP/IP連接一些常用
的Internet服務,然後向這些服務送出指
令字串,就可以取得所需的資訊。Socket
類別的建構子,如下表所示:
建構子
說明
Socket(String, int)
建立連線的 Socket 物件,參數 String 和 InetAddress
Socket(InetAddress, int) 物件是主機的網域名稱,參數 int 是上表的埠號,
埠號的範圍是 1025~65535
18-4 Socket類別的Internet服務連線方法

Socket類別關於建立連線和取得串流的方
法,如下表所示:
方法
說明
void close()
關閉 Socket 物件
InputStream getInputStream() 取得輸入串流 InputStream,可以從伺服端
讀取資料
OutputStream
取得輸出串流 OutputStream,可以將資料
getOutputStream()
送到伺服端
18-4 Socket類別的Internet服務埠號
服務名稱
echo
discard
daytime
ftp
telnet
smtp
whois
finger
http
pop3
nntp
埠號
7
9
13
21
23
25
43
79
80
110
119
說明
伺服端只是將客戶端傳送的資料,原封不動的送回
無論客戶端傳送什麼資料,伺服端都直接捨棄
傳回伺服器的日期和時間
FTP 服務
Telnet 服務
SMTP 寄送郵件服務
Whois 服務
Finger 服務
WWW 服務
POP3 郵件接收服務
News 新聞服務
18-4-1 Daytime日期時間服務
當Internet伺服器如果支援Daytime服務,
其埠號為13,我們就可以在Java程式建立
Socket物件取得伺服器當地的日期/時間,
如下所示:
Socket socket = new Socket(server,
13);
 上述程式碼的server是主機的網域名稱,
在建立好Socket物件後,即可建立主機間
的TCP/IP連線,然後使用
getInputStream()方法取得輸入串流讀取
日期/時間資料。

18-4-2 HTTP的Web服務


WWW服務的埠號是80,Java程式可以使
用Socket物件建立HTTP連線下載網頁檔案,
在功能上類似第18-3-2節的URL物件檔案
下載,讀取檔案是顯示在Swing套件的
JTextArea元件。
在建立好Socket物件的連線且送出GET指
令即可取得網頁檔案,如下所示:
out.println("GET " + url.getFile());
18-4-3 SMTP寄送電子郵件

Java程式只需使用Socket物件的埠號25,
就可以透過SMTP寄送電子郵件,當建立
SMTP服務的連線後,依序傳遞相關指令指
定電子郵件的寄件者、送件者、主旨等資
料,即可寄送電子郵件。
18-4-4 POP3檢查電子郵件

在Java程式的Socket物件使用埠號110建
立連線,即可使用PO3服務檢查信箱共有
幾封尚未接收的電子郵件。我們只需送出
LIST指令顯示郵件清單後,就可以使用
while迴圈計算郵件數,如下所示:
int no = 0;
while((str = in.readLine()) != null)
{ if (!(str.equals("."))) no++;
else
return no;
}
18-5 ServerSocket類別的伺服端
程式-程式架構
Java語言也可以使用SeverSocket類別自
行撰寫伺服器程式,如下所示:
ServerSocket server =
new ServerSocket(PORT);
while (true)
{
Socket socket = server.accept();
………
}

18-5 ServerSocket類別的伺服端程
式-建構子與相關方法

ServerSocket類別的建構子,如下表所示:
建構子
ServerSocket(int)
說明
建立可供連線的 ServerSocket 物件,參數 int 是使用
的埠號,埠號範圍是 1025~65535
 ServerSocket類別建立連線的相關方法,
如下表所示:
方法
Socket accept()
void close()
說明
傾聽客戶端 Socket 物件的連線,當連線建立後,傳
回 Socket 物件
關閉 ServerSocket 物件
18-6 專案實例:建立Java聊天室
-說明

聊天室是一種網路上公開的談天園地,一
種即時留言和回應的應用程式,使用者不
但可以看到其它使用者的留言,還可以馬
上回應留言。
18-6 專案實例:建立Java聊天室
-系統架構
多執行緒伺服器系統架構

Java聊天室是主從架構應用程式,能夠讓多個客
戶端應用程式同時連線聊天伺服器,聊天室伺服
器是一個多執行緒伺服器,每一個執行緒對應一
個客戶端的連線請求,如下圖所示:
18-6 專案實例:建立Java聊天室
-程式架構

Java聊天室的程式分為伺服端和客戶端,
如下表所示:
Java 程式
ChatServer.java
ChatClient.java
ChatClientApplet.java
ChatClientApplet.htm
說明
多執行緒的聊天室伺服器
Swing 版本的客戶端程式
JApplet 版本的客戶端程式
內含 Java Applet 的 HTML 網頁
18-6 專案實例:建立Java聊天室
-ChatUserThread類別1
ChatUserThread類別是繼承自Thread的執行緒
類別,每一個ChatUserThread物件能夠建立一
個客戶端連線,所有執行緒物件都儲存在
HashSet集合物件,可以用來記錄聊天室的所有
使用者執行緒物件,如下所示:
private static HashSet<ChatUserThread>
userThreadList =
new HashSet<ChatUserThread>();
 程式碼建立HashSet物件,在執行緒物件的run()
方法可以將本身的執行緒物件新增到HashSet物
件,如下所示:
userThreadList.add(this);

18-6 專案實例:建立Java聊天室ChatUserThread類別2

當使用HashSet物件記錄所有執行緒物件
後,任何一位使用者張貼訊息,就可以呼
叫sendMsgs()方法取出HashSet物件的
每一個執行緒物件,以便可以將訊息送給
每一位客戶端的使用者,如下所示:
18-6 專案實例:建立Java聊天室ChatUserThread類別3
public static void sendMsgs(String message)
{ synchronized(userThreadList) {
Iterator<ChatUserThread> iterator =
userThreadList.iterator();
while (iterator.hasNext())
{ ChatUserThread currentUser =
iterator.next();
try {
synchronized(currentUser.out) {
currentUser.out.writeUTF(message);
}
currentUser.out.flush();
……….
18-6 專案實例:建立Java聊天室ChatServer類別
ChatServer類別是Java聊天室的伺服端應用程
式類別,在建立好ServerSocket物件後,使用
while迴圈等待客戶端連線,如下所示:
while (true)
{ // 建立客戶端Socket物件
Socket client = server.accept();
……
ChatUserThread currentUser = new
ChatUserThread(client);
currentUser.start();
}

18-6 專案實例:建立Java聊天室ChatClient.java(1)
ChatClient.java是實作Runnable介面的執行緒應用程
式,Swing應用程式是在run()方法接收聊天訊息,並且
將它顯示出來,如下所示:
public void run()
{ try {
…….
while (true)
{ String msg = in.readUTF();
output.append(msg + "\n");
}
}
catch ( IOException e ) { }
}

18-6 專案實例:建立Java聊天室ChatClient.java(2)
送出張貼訊息是在JButton按鈕元件的事件處理,
如下所示:
public void actionPerformed(ActionEvent evt)
{ try
{ out.writeUTF(input.getText());
out.flush();
}
catch ( IOException e ) { }
………
}

18-6 專案實例:建立Java聊天室-圖
例1
18-6 專案實例:建立Java聊天室-圖
例2