程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> C/S環境下Java應用程序運行過程講解

C/S環境下Java應用程序運行過程講解

編輯:關於JAVA

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

1、服務器監聽相應端口的輸入;

2、客戶機發出一個請求;

3、服務器接收到此請求;

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

5、重復上述過程,直至完成一次會話過程。

按照以上過程,我們使用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中寫數據。最後,客戶機程序從標准輸入(如:控制台)中讀取數據,並把這些數據寫到服務器,在從服務器讀取應答消息,然後把這些應答消息寫到准輸出。

實例:

// Server.java
import java.io.*;
import java.net.*;
public class Server extends Thread
{
public final static int Default_Port=6543;
protectd int port;
protectd ServerSockt 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);
// 返回連接的地址和端口
ystem.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 loop
}
/ 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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved