Java實(shí)現(xiàn)簡(jiǎn)單的server/client回顯功能
如果要建立連接,一臺(tái)機(jī)器必須運(yùn)行一個(gè)進(jìn)程來(lái)等待連接,而另一臺(tái)機(jī)器必須試圖到達(dá)第一臺(tái)機(jī)器。這個(gè)電話系統(tǒng)類似:一方必須發(fā)起呼叫,而另一方在此時(shí)必須等待電話呼叫。
java網(wǎng)絡(luò)模型圖
下面通過(guò)一個(gè)有“回顯”功能的服務(wù)器和客戶端來(lái)介紹應(yīng)用java.net包編寫(xiě)網(wǎng)絡(luò)應(yīng)用程序。
這個(gè)例子主要功能是服務(wù)器端的程序等待客戶的輸入,然后將讀取到的信息回顯給客戶端,同時(shí)在服務(wù)器端的控制臺(tái)輸出。而客戶端從控制臺(tái)接收信息后,向客戶端發(fā)送輸入,并接收服務(wù)器的回顯數(shù)據(jù),然后顯示在控制臺(tái)。
客戶端程序代碼如下:
package com.javapp.ch11; import java.io.*; import java.net.*; /** * Description: 具有“回顯”功能的服務(wù)器端和客戶端程序 */ public class EchoClientDemo { // 服務(wù)器端的服務(wù)端口。 public static final int SERVERPORT = 990; public static void main(String[] args) { try { // 建立連接套接字。 Socket s = new Socket("localhost",SERVERPORT); System.out.println("socket = " + s); // 新建網(wǎng)絡(luò)連接的輸入流。 BufferedReader in = new BufferedReader(new InputStreamReader(s .getInputStream())); // 新建網(wǎng)絡(luò)連接的自動(dòng)刷新的輸出流。 PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(s.getOutputStream())),true); // 先使用System.in構(gòu)造InputStreamReader,再構(gòu)造BufferedReader。 BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.println("Enter a string, Enter BYE to exit! "); while (true) { // 讀取從控制臺(tái)輸入的字符串,并向網(wǎng)絡(luò)連接輸出,即向服務(wù)器端發(fā)送數(shù)據(jù)。 out.println(stdin.readLine()); // 從網(wǎng)絡(luò)連接讀取一行,即接收服務(wù)器端的數(shù)據(jù)。 String str = in.readLine(); // 如果接收到的數(shù)據(jù)為空(如果直接按Enter,不是空數(shù)據(jù)),則退出循環(huán),關(guān)閉連接。 if (str == null) { break; } System.out.println(str); } s.close(); } catch (IOException e) { System.err.println("IOException" + e.getMessage()); } } } |
支持多客戶端的“回顯”服務(wù)器端程序代碼如下:
package com.javapp.ch11; import java.io.*; import java.net.*; /** * Description:支持多客戶端的“回顯”服務(wù)器端程序 */ public class EchoServerThreadDemo { // 服務(wù)器端的服務(wù)端口。 public static final int SERVERPORT = 990; public static void main(String[] args) { try { // 已經(jīng)連接上的客戶端的序號(hào)。 int number = 1; // 建立服務(wù)器端傾聽(tīng)套接字。 ServerSocket s = new ServerSocket(SERVERPORT); System.out.println("Started: " + s); while (true) { // 等待并接收請(qǐng)求,建立連接套接字。 Socket incoming = s.accept(); System.out.println("Connection " + number + " accepted: "); System.out.println(incoming); // 啟動(dòng)一個(gè)線程來(lái)進(jìn)行服務(wù)器端和客戶端的數(shù)據(jù)傳輸。 // 主程序繼續(xù)監(jiān)聽(tīng)是否有請(qǐng)求到來(lái)。 Thread t = new EchoThread(incoming,number); t.start(); number++; } } catch (IOException e) { System.err.println("IOException"); } } } class EchoThread extends Thread { private Socket s; int n; public EchoThread(Socket incoming,int number) { s = incoming; n = number; } public void run() { try { // 新建網(wǎng)絡(luò)連接的輸入流。 BufferedReader in = new BufferedReader(new InputStreamReader(s .getInputStream())); // 新建網(wǎng)絡(luò)連接的自動(dòng)刷新的輸出流。 PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(s.getOutputStream())),true); System.out.println("Hello! Enter BYE to exit."); // 回顯客戶端的輸入。 while (true) { // 從網(wǎng)絡(luò)連接讀取一行,即接收客戶端的數(shù)據(jù)。 String line = in.readLine(); // 如果接收到的數(shù)據(jù)為空(如果直接按Enter,不是空數(shù)據(jù)),則退出循環(huán),關(guān)閉連接。 if (line == null) { break; } else { if (line.trim().equals("BYE")) { System.out.println("The client " + n + " entered BYE!"); System.out.println("Connection " + n + " will be closed!"); break; } System.out.println("Echo " + n + ": " + line); // 向網(wǎng)絡(luò)連接輸出一行,即向客戶端發(fā)送數(shù)據(jù)。 out.println("Echo " + n + ": " + line); } } // 關(guān)閉套接字。 s.close(); } catch (IOException e) { System.err.println("IOException"); } } } |
在服務(wù)器端程序中,首先用java.net包中的ServerSocket類創(chuàng)建一個(gè)服務(wù)器端偵聽(tīng)套接字。其后應(yīng)用ServerSocket類 的accept方法等待并接收用戶請(qǐng)求。當(dāng)服務(wù)器每接收到一個(gè)連接請(qǐng)求后,就啟動(dòng)一個(gè)線程來(lái)單獨(dú)處理服務(wù)器和客戶端的數(shù)據(jù)傳輸。服務(wù)器端數(shù)據(jù)的接收和發(fā)送 與上面介紹的客戶端數(shù)據(jù)的發(fā)送和介紹相同。
posted on 2013-05-24 10:31 順其自然EVO 閱讀(205) 評(píng)論(0) 編輯 收藏