Java 在Client/Server 中应用 |
一、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 调试通过 。 三、编写服务器类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 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 // 服务例程:读出一行文本;反转文本;返回文本 。
|