Java在Client/Server网络中的应用
副标题#e#
跟着Java语言的日益风行,出格是Java与Internet Web的密切团结,使它在 全球取得了庞大的乐成。Java语言以其独立于平台、面向工具、漫衍式、多线索 及完善的安详机制等特色,成为现代信息系统建树中的精采的开拓平台和运行环 境。
一、Java网络应用模子
和Internet上的很多情况一样,完整的Java应用情况实际上也是一个客户机/ 处事器情况,更确切地说是欣赏器/处事器模子(即Browser/Server模子,简称 Web模子)。但与传统的客户机/处事器(C/S) 的二层布局差异,应用Java的Web 模子是由三层布局构成的。传统的C/S布局通过动静通报机制,由客户端发出请 求给处事器,处事器举办相应处理惩罚后经通报机制送回客户端。而在Web模子中, 处事器一端被解析成两部门:一部门是应用处事器(Web 处事器),另一部门是数 据库处事器。
针对漫衍式计较情况,Java通过其网络类库提供了精采的支持。对数据漫衍 ,Java提供了一个URL(Uniform Resource Locator) 工具, 操作此工具可打开 并会见网络上的工具,其会见方法与会见当地文件系统险些完全沟通。对操纵分 布,Java的客户机/ 处事器模式可以把运算从处事器分手到客户一端(处事器负 责提供查询功效,客户机认真组织功效的显示),从而提高整个系统的执行效率 ,增加动态可扩充性。Java网络类库是Java 语言为适应Internet 情况而举办的 扩展。别的,为适应Internet的不绝成长,Java还提供了动态扩充协议,以不绝 扩充Java网络类库。
Java的网络类库支持多种Internet协议,包罗Telnet, FTP 和HTTP (WWW), 与此相对应的Java网络类库的子类库为:
Java.net
Java.net.ftp
Java.net.www.content
Java.net.www.html
Java.net.www.http
这些子类库各自容纳了可用于处理惩罚Internet协议的类和要领。个中, java.net用于处理惩罚一些根基的网络成果,包罗长途登录(Telnet);java.net.ftp 用于处理惩罚ftp协议;java.net.www.content用于处理惩罚WWW 页面内容; java.net.www.html 和java.net.www.http 则别离提供了对HTML 语言和HTTP 协 议的支持。
二、客户机/处事器情况下的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 中写数据。最后,客户 机措施从尺度输入(如:节制台)中读取数据,并把这些数据写随处事器,在从 处事器读取应答动静,然后把这些应答动静写到准输出。
以下别离为处事器和客户机端的源措施清单。本措施在NT 4.0 网络情况 (TCP/IP)下利用JDK1.1 调试通过。
#p#副标题#e#
三、编写处事器类Java措施
#p#分页标题#e#
// 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
运行该客户机措施时,必需以处事器主机名作为第一个参数,处事器端标语 为第二个参数,个中处事器端标语可缺省。