Java在Client/Server網路中的應用 (轉)

worldblog發表於2007-12-07
Java在Client/Server網路中的應用 (轉)[@more@] 

在Client/Server中的應用

日照港務局--劉洋

---- 隨 著Java 語 言 的 日 益 流 行, 特 別 是Java 與Inte 的 密 切 結 合, 使 它 在 全 球 取 得 了 巨 大 的 成 功。Java 語 言 以 其 獨 立 於 平 臺、 面 向 對 象、 分 布 式、 多 線 索 及 完 善 的 安 全 機 制 等 特 色, 成 為 現 代 信 息 系 統 建 設 中 的 良 好 的 開 發 平 臺 和 運 行 環 境。

一、Java 網 絡 應 用 模 型

---- 和Internet 上 的 許 多 環 境 一 樣, 完 整 的Java 應 用 環 境 實 際 上 也 是 一 個 客 戶 機/ 服 務 器 環 境, 更 確 切 地 說 是 瀏 覽 器/ 服 務 器 模 型( 即Browser/Server 模 型, 簡 稱Web 模 型)。 但 與 傳 統 的 客 戶 機/ 服 務 器(C/S) 的 二 層 結 構 不 同, 應 用Java 的Web 模 型 是 由 三 層 結 構 組 成 的。 傳 統 的C/S 結 構 通 過 消 息 傳 遞 機 制, 由 客 戶 端 發 出 請 求 給 服 務 器, 服 務 器 進 行 相 應 處 理 後 經 傳 遞 機 制 送 回 客 戶 端。 而 在Web 模 型 中, 服 務 器 一 端 被 分 解 成 兩 部 分: 一 部 分 是 應 用 服 務 器(Web 服 務 器), 另 一 部 分 是 數 據 庫 服 務 器。

Java 網 絡 應 用 模 型

---- 針 對 分 布 式 計 算 環 境,Java 通 過 其 網 絡 類 庫 提 供 了 良 好 的 支 持。 對 數 據 分 布,Java 提 供 了 一 個URL(UnifoRe Locator) 對 象, 利 用 此 對 象 可 打 開 並 訪 問 網 絡 上 的 對 象, 其 訪 問 方 式 與 訪 問 本 地 文 件 系 統 幾 乎 完 全 相 同。 對 操 作 分 布,Java 的 客 戶 機/ 服 務 器 模 式 可 以 把 運 算 從 服 務 器 分 散 到 客 戶 一 端( 服 務 器 負 責 提 供 查 詢 結 果, 客 戶 機 負 責 組 織 結 果 的 顯 示), 從 而 提 高 整 個 系 統 的 執 行 效 率, 增 加 動 態 可 擴 充 性。Java 網 絡 類 庫 是Java 語 言 為 適 應Internet 環 境 而 進 行 的 擴 展。 另 外, 為 適 應Internet 的 不 斷 發 展,Java 還 提 供 了 動 態 擴 充 協 議, 以 不 斷 擴 充Java 網 絡 類 庫。

---- Java 的 網 絡 類 庫 支 持 多 種Internet 協 議, 包 括, 和HTTP(WWW), 與 此 相 對 應 的Java 網 絡 類 庫 的 子 類 庫 為:

Java.net Java.net.ftp Java.net. Java.net. Java.net.


---- 這 些 子 類 庫 各 自 容 納 了 可 用 於 處 理Internet 協 議 的 類 和 方 法。 其 中,java.net 用 於 處 理 一 些 基 本 的 網 絡 功 能, 包 括 遠 程 登 錄(Telnet);java.net.ftp 用 於 處 理ftp 協 議;java.net. 用 於 處 理WWW 頁 面 內 容;java.net. 和java.net. 則 分 別 提 供 了 對HTML 語 言 和HTTP 協 議 的 支 持。

二、 客 戶 機/ 服 務 器 環 境 下 的Java 應 用 程 序

---- 客 戶 機/ 服 務 器 在 分 布 處 理 過 程 中, 使 用 基 於 連 接 的 網 絡 通 信 模 式。 該 通 信 模 式 首 先 在 客 戶 機 和 服 務 器 之 間 定 義 一 套 通 信 協 議, 並 創 建 一Socket 類, 利 用 這 個 類 建 立 一 條 可 靠 的 鏈 接; 然 後, 客 戶 機/ 服 務 器 再 在 這 條 鏈 接 上 可 靠 地 傳 輸 數 據。 客 戶 機 發 出 請 求, 服 務 器 監 聽 來 自 客 戶 機 的 請 求, 並 為 客 戶 機 提 供 響 應 服 務。 這 就 是 典 型 的" 請?-- 應 答" 模 式。 下 面 是 客 戶?/ 服 務 器 的 一 個 典 型 運 作 過 程:

---- 2 . 服 務 器 監 聽 相 應 端 口 的 輸 入;

---- 3* 客 戶 機 發 出 一 個 請 求;

---- 5 . 服 務 器 接 收 到 此 請 求;

---- 6 . 服 務 器 處 理 這 個 請 求, 並 把 結 果 返 回 給 客 戶 機;

---- 7 . 重 復 上 述 過 程, 直 至 完 成 一 次 會 話 過 程。

---- 按 照 以 上 過 程, 我 們 使 用Java 語 言 編 寫 一 個 分 別 針 對 服 務 器 和 客 戶 機 的 應 用 程 序(Application)。 該 程 序 在 服 務 器 上 時, 程 序 負 責 監 聽 客 戶 機 請 求, 為 每 個 客 戶 機 請 求 建 立Socket 連 接, 從 而 為 客 戶 機 提 供 服 務。 本 程 序 提 供 的 服 務 為: 讀 取 來 自 客 戶 機 的 一 行 文 本, 反 轉 該 文 本, 並 把 它 發 回 給 客 戶 機。

---- 通 過 該 程 序 實 例 我 們 看 到, 使 用Java 語 言 設 計C/S 程 序 時 需 要 注 意 以 下 幾 點:

---- (1)、 服 務 器 應 使 用ServerSocket 類 來 處 理 客 戶 機 的 連 接 請 求。 當 客 戶 機 連 接 到 服 務 器 所 監 聽 的 端 口 時,ServerSocket 將 分 配 一 新 的Socket 對 象。 這 個 新 的Socket 對 象 將 連 接 到 一 些 新 端 口, 負 責 處 理 與 之 相 對 應 客 戶 機 的 通 信。 然 後, 服 務 器 繼 續 監 聽ServerSocket, 處 理 新 的 客 戶 機 連 接。

---- Socket 和ServerSocket 是Java 網 絡 類 庫 提 供 的 兩 個 類。

---- (2)、 服 務 器 使 用 了 多 線 程 機 制。Server 對 象 本 身 就 是 一 個 線 程, 它 的run() 方 法 是 一 個 無 限 循 環, 用 以 監 聽 來 自 客 戶 機 的 連 接。 每 當 有 一 個 新 的 客 戶 機 連 接 時,ServerSocket 就 會 創 建 一 個 新 的Socket 類 實 例, 同 時 服 務 器 也 將 創 建 一 新 線 程, 即 一 個Connection 對 象, 以 處 理 基 於Socket 的 通 信。 與 客 戶 機 的 所 有 通 信 均 由 這 個Connection 對 象 處 理。Connection 的 構 造 函 數 將 初 始 化 基 於Socket 對 象 的 通 信 流, 並 啟 動 線 程 的 運 行。 與 客 戶 機 的 通 信 以 及 服 務 的 提 供, 均 由Connection 對 象 處 理。

---- (3)、 客 戶 機 首 先 創 建 一Socket 對 象, 用 以 與 服 務 器 通 信。 之 後 需 創 建 兩 個 對 象:DataInputStream 和PrintStream, 前 者 用 以 從Socket 的InputStream 輸 入 流 中 讀 取 數 據, 後 者 則 用 於 往Socket 的OutputStream 中 寫 數 據。 最 後, 客 戶 機 程 序 從 標 準 輸 入( 如: 控 制 臺) 中 讀 取 數 據, 並 把 這 些 數 據 寫 到 服 務 器, 在 從 服 務 器 讀 取 應 答 消 息, 然 後 大 這 些 應 答 消 息 寫 到 到 準 輸 出。

---- 以 下 本 別 為 服 務 器 和 客 戶 機 端 的 源 程 序 清 單。 本 程 序 在NT 4.0 網 絡 環 境() 下 使 用1.1 調 試 通 過。

---- 2 . 編 寫 服 務 器 類Java 程 序

// Server.java import java.io.*; import java.net.*; public class Server extends Thread { public final static int Default_Port=6543; protectd int port; protectd ServerSockrt listen_socket; // 定 義 出 錯 例 程: 如 果 出 現 異 常 錯 誤, 退 出 程 序。


Public static void fail(Exception e, String msg) { System.err.println(msg + ": " + e); System.exit(1); } // 定 義 並 啟 動 服 務 器 的Socket 例 程, 監 聽 客 戶 機 的 連 接 請 求。 public Server(int port) { if(port == 0) port = Default_Port; this.port = port; try { listen_socket = new ServerSocket(port); } catch(IOException e) fail(e, "Exception creating server socket"); System.out.println("Server: listening on port" + port); This.start(); }


---- /* 下 面 為 服 務 器 監 聽 線 程 的 主 程 序。 該 線 程 一 直 循 環 執 行, 監 聽 並 接 受 客 戶 機 發 出 的 連 接 請 求。 對 每 一 個 連 接, 均 產 生 一 個 連 接 對 象 與 之 對 應, 通 過Socket 通 道 進 行 通 信。

*/ public void run() { try { while(true) { Socket client_socket = listen_socket.accept(); Connection c = new Connection(client_socket); } } catch(IOException e) fail(e,"Exception while listening for connections") } // 啟 動 服 務 器 主 程 序 public static void main(String args[]) { int port = 0; if (args.length == 1) { try port = Integer.parseInt(args[0]); catch(NumberFormatException e) port = 0; } new Server(port); } // End of the main } // End of Server class // 以 下 定 義 了Connection 類, 它 是 用 來 處 理 與 客 戶 機 的 所 有 通 信 的 線 程。 class Connection extends Thread { protected Socket client; protected DataInputStream in; protected PrintStream out; // 初 始 化 通 信 流 並 啟 動 線 程 public Connection(Socket client_socket) { client = client_socket; try { in = new DataInputStream(client.getinputStream()); out = new PrintStream(client.getOutputStream()); } catch(IOException e) { try client.close(); catch(IOException e2); System.err.println("Exception while getting socket streram: " + e); Return; } this.start; } // End of Connection method // 服 務 例 程: 讀 出 一 行 文 本; 反 轉 文 本; 返 回 文 本。 public void run() { String line; StringBuffer revline; int len; try { for(;;) { // Read a line line = in.readline(); if(line == null) break; // Reverse the line len = line.length(); revline = new StringBuffer(len); for(int i = len-1; i >=0; i--) revline.insert(len-1-I;line.charAt(i)); // Write out the reverse line out.println(revline); } catch(IOException e); finally try client.close(); catch(IOException e2); } // End of run method } // End of Connection class 3* 編 寫 客 戶 機 類Java 程 序 // Client.java import java.io.*; import java.net.*; public class Client extends { public static final int Default_Port = 6543; // 定 義 出 錯 例 程 public static final void usage() { System.out.println("Usage: Java Client <> [<>]"); System.exit(0); } public static void main(String args[]) { int port = Default_Port; Socket s = null; // 解 析 端 口 參 數 if ((args.length != 1)&&(args.length != 2 )) usage(); if (args.length == 1) port = Default_Port; else { try port = Integer.parseInt(args[1]); catch(NumberFormaatException e) usage(); } try{ // 產 生 一 個Socket , 通 過 指 定 的 端 口 與 主 機 通 信。 s = new Socket(args[0], port); // 產 生 用 於 發 出 和 接 收 的 文 本 字 符 流 DataInputStream sin = new DataInputStream(s.getInputStream()); PrintStream sout = new DataInputStream(s.getInputStream()); // 從 控 制 臺 讀 入 字 符 流 DataInputStream in = new DataInputStream(System.in); // 返 回 連 接 的 地 址 和 端 口 System.out.println("Connected to"+s.getInetAddress()+":"+ s.getPort()); String line; For(;;) { // 顯 示 提 示 符 System.out.print(" >"); System.out.flush(); // 讀 入 控 制 臺 輸 入 的 一 行 字 符 line = in.readline(); if (line == null) break; // 將 接 收 的 文 本 行 送 至 服 務 器 sout.println(line); // 從 服 務 器 接 收 一 行 字 符 line = sin.readline(); // Check if connection is closed(i.e. for EOF) if(line == null) { System.out.println("Connection closed by server."); Break; } // 在 控 制 臺 上 顯 示 接 收 的 字 符 System.out.println(line); }// End of for l }// End of try catch(IOException e ) System.err.println(e); // Always be sure to close the socket finally { try if(s != null) s.close(); catch(IOException e2); } }// End of main }// End of Client


---- 運 行 該 客 戶 機 程 序 時, 必 須 以 服 務 器 主 機 名 作 為 第 一 個 參 數, 服 務 器 端 口 號 為 第 二 個 參 數, 其 中 服 務 器 端 口 號 可 缺 省。

---- 通 信 地 址:
276826
山 東 省 日 照 市 黃 海 一 路
日 照 港 務 局 通 信 信 息 中 心
劉 洋
Tel: 0633-8382561
to:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-989333/,如需轉載,請註明出處,否則將追究法律責任。

相關文章