IT评测·应用市场-qidao123.com

标题: Java 网络编程 —— 客户端协议处理框架 [打印本页]

作者: 篮之新喜    时间: 2023-6-3 01:29
标题: Java 网络编程 —— 客户端协议处理框架
概述

Java 对客户程序的通信过程进行了抽象,提供了通用的协议处理框架,该框架封装了 Socket,主要包括以下类:
以上类都位于 java.net 包,除 URL 类为具体类,其余的都是抽象类,对于一种具体的协议,需要创建相应的具体子类。Oracle 公司为协议处理框架提供了基于 HTTP 的实现,它们都位于 JDK 类库的 sun.net.www 包或者其子包

URL 类的用法

下例的 HtpClient 类利用 URL 类创建了一个简单的 HTTP 客户程序,先创建了一个 URL 对象,然后通过它的 openStream() 方法获得一个输入流,接下来就从这个输入流中读取服务器发送的响应结果
  1. public class HttpClient {
  2.    
  3.     public static void main(String args[]) throws IOException {
  4.         //http是协议符号
  5.         URI url = new URL("http://www.javathinker.net/hello.htm");
  6.         //接收响应结果
  7.         InputStream in = url.openStream();
  8.         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
  9.         bytel] buff = new byte[1024];
  10.         int len = -l;
  11.         
  12.         while((len = in.read(buff)) != -1) {
  13.             buffer.write(buff, 0, len);
  14.         }
  15.         //把字节数组转换为字符串
  16.         System.out.println(new String(buffer.toByteArray()));
  17.     }
  18. }
复制代码
URL 类的构造方法创建 URLStreamHandler 实例的流程如下:
URL 类具有以下方法:

URLConnection 类的用法

URLConnection 类表示客户程序与远程服务器的连接,URLConnection 有两个 boolean 类型的属性以及相应的 get 和 set 方法:
URLConnection 类提供了读取远程服务器的响应数据的一系列方法:
下例的 HtpClient 类利用 URLConnection 类来读取服务器的响应结果
  1. public class HttpClient {
  2.    
  3.     public static void main(String args[]) throws IOException {
  4.         URL url = new URL("http://www,javathinkernet/hello.htm");
  5.         URLConnection connection = url.openConnection();
  6.         //接收响应结果
  7.         System.out.printIn("正文类型:" + connection.getContentType());
  8.         System.out.printIn("正文长度:" + connection.getContentLength());
  9.         //读取响应正文
  10.         InputStream in = connection.getInputStream();
  11.         
  12.         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
  13.         byte[] buff = new byte[1024];
  14.         int len = -l;
  15.         
  16.         while((len = in.read(buff)) != -1) {
  17.             buffer.write(buff, 0, len);
  18.         }
  19.         
  20.         //把字节数组转换为字符串
  21.         System.out.println(new String(buffer.toByteArray()));
  22.     }
  23. }
复制代码
实现协议处理框架

本节将为用户自定义的 ECHO 协议实现处理框架,共创建了以下类:
1. 创建 EchoURLConnection 类

EchoURLConnection 类封装了一个 Socket,在 connect() 方法中创建与远程服务器连接的 Socket 对象
  1. public class EchoURLConnection extends URLConnection {
  2.    
  3.     private Socket connection = null;
  4.     public final static int DEFAULT PORT = 8000;
  5.    
  6.     public EchoURLConnection(URL url) {
  7.         super(url);
  8.     }
  9.    
  10.     public synchronized InputStream getInputStream() throws IOException {
  11.         if(!connected) connect();
  12.         return connection.getInputStream();
  13.     }
  14.    
  15.     public synchronized OutputStream getOutputStream() throws IOException {
  16.         if(!connected) connect();
  17.         return connection.getOutputStream();
  18.     }
  19.    
  20.     public String getContentType() {
  21.         return "text/plain";
  22.     }
  23.    
  24.     public synchronized void connect() throws IOException {
  25.         if(!connected) {
  26.             int port = url.getPort();
  27.             if(port < 0 || port > 65535) port = DEFAULT_PORT;
  28.             this.connection = new Socket(url.getHost(), port);
  29.             this.connected = true;
  30.         }
  31.     }
  32.    
  33.     public synchronized void disconnect() throws IOException {
  34.         if(connected) {
  35.             //断开连接
  36.             this.connection.close();
  37.             this.connected = false;
  38.         }
  39.     }
  40. }
复制代码
2. 创建 EchoURLStreamHandler 及工厂类

EchoURLStreamHandler 类的 openConnection() 方法负责创建一个 EchoURLConnection 对象
  1. public class EchoURLStreamHandler extends URLStreamHandler {
  2.    
  3.     public int getDefaultPort() {
  4.         return 8000;
  5.     }
  6.    
  7.     protected URLConnection openConnection(URL url) throws IOException {
  8.         return new EchoURLConnection(url);
  9.     }
  10. }
复制代码
EchoURLStreamHandlerFactory 类的 createURLStreamHandle() 方法负责构造 EchoURLStreamHandler 实例
  1. public class EchoURLStreamHandlerFactory implements URLStreamhandlerFactory {
  2.    
  3.     public URLStreamHandler createURLStreamHandler(String protocol) {
  4.         if(protocol.equals("echo"))
  5.             return new EchoURLStreamHandler();
  6.         else
  7.             return null;
  8.     }
  9. }
复制代码
在客户程序中,可以通过以下方式设置 EchoURLStreamHandlerFactory
  1. URL.setURLStreamHandlerFactory(new EchoURLStreamHandlerFactory());
  2. URL url=new URL("echo://localhost:8000");
复制代码
3. 创建 EchoContentHandler 类及工厂类

URLConnection 类还提供了 getContent() 方法,它有两种重载形式:
  1. public Object getContent();
  2. public Object getContent(Class[] classes);
复制代码
第二个 getContent() 方法把服务器发送的数据优先转换为 classes 数组第一个元素指定的类型,如果转换失败,再尝试转换第二个元素指定的类型,以此类推
下例 HttpClient 演示处理服务器发送的数据
  1. public class HttpClient {
  2.    
  3.     public static void main(String args[]) throws IOException {
  4.         URL url = new URL("http://www,javathinker.net/hello.htm");
  5.         URlConnection connection = url.openConnection();
  6.         //接收响应结果
  7.         InputStream in = connection.getInputStream();
  8.         Class[] types = {String.class, InputStream.class};
  9.         Object obj = connection.getContent(types);
  10.         
  11.         if(obj instanceof String) {
  12.             System.out.println(obj);
  13.         } else if(obj instanceof InputStream) {
  14.             in = (InputStream) obj;
  15.             FileOutputStream file = new FileOutputStream("data");
  16.             byte[] buff = new byte[1024];
  17.             int len = -l;
  18.             
  19.             while((len = in.read(buff)) != -1) {
  20.                 file.write(buff, 0 ,len);
  21.             }
  22.             
  23.             System.out.println("正文保存完毕");
  24.         } else {
  25.             System.out.println("未知的响应正文类型");
  26.         }
  27.     }
  28. }
复制代码
EchoContentHandler 类负责处理 EchoServer 服务器发送的数据
  1. public class EchoContentHandler extends ContentHandler {
  2.    
  3.     /** 读取服务器发送的一行数据,把它转换为字符串对象 */
  4.     public Object getContent(URLConnection connection) throws IOException {
  5.             InputStream in = connection.getInputStream();
  6.         BufferedReader br = new BufferedReader(new InputStreamReader(in));
  7.         return br.readLine();
  8.     }
  9.    
  10.     public Object getContent(URLConnection connection, Class[] classes) throws IOException {
  11.         InputStream in = connection.getInputStream();
  12.         for(int i = 0; i < classes.length; i++) {
  13.             if(classes[i] == InputStream.class) {
  14.                 return in;
  15.             } else if(classes[i] == String.class) {
  16.                 return getContent(connection);
  17.             }
  18.         }
  19.         return null;
  20.     }
  21. }
复制代码
第二个 getContent() 方法依次遍历 classes 参数中的元素,判断元素是否为 InputSuream 类型或 String 类型,如果是,就返回相应类型的对象,它包含了服务器发送的数据。如果 classes 参数中的元素都不是 InputStream 类型或 String 类型,就返回 null
EchoContentHandlerFactory 类的 createContentHandler() 方法负责创建一个EchoContentHandler 对象
  1. public class EchoContentHandlerFactory implements ContentHandlerFactory {
  2.    
  3.     public ContentHandler createContentHandler(String mimetype) {
  4.         if(mimetype.equals("text/plain")) {
  5.             return new EchoContentHandler();
  6.         } else {
  7.             return null;
  8.         }
  9.     }
  10. }
复制代码
在客户程序中,可以通过以下方式设置 EchoContentHandlerFactory
  1. URLConnection.setContentHandlerFactory(new EchoContentHandlerFactory());
  2. URL url = new URL("echo://localhost:8000");
  3. EchoURLConnection connection = (EchoURLConnection)url.openConnection();
  4. ...
  5. //读取服务器返回的数据,它被包装为一个字符串对象
  6. String echoMsg = (String)connection.getContent();
复制代码
4. 在 EchoClient 类运用 ECHO 协议处理框架
  1. public class EchoClient {
  2.    
  3.     public static void main(String args[]) throws IOException {
  4.         //设置URLStreamHandlerFactory
  5.         URL.setURLStreamHandlerFactory(new EchoURLStreamHandlerFactory());
  6.         //设置ContentHandlerFactory
  7.         URLConnection.setContentHandlerFactory(new EchoContentHandlerFactory());
  8.         
  9.         URL url = new URL("echo://localhost:8000");
  10.         EchoURLConnection connection = (EchoURlConnection) url.openConnection();
  11.         //允许获得输出流
  12.         connection.setDoOutput(true);
  13.         //获得输出流
  14.         PrintWriter pw = new PrintWriter(connection.getOutputStream(), true);
  15.         while(true) {
  16.             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  17.             String msg = br.readLine();
  18.             //向服务器发送消息
  19.             pw.println(msg);
  20.             //读取服务器返回的消息
  21.             String echoMsg = (String) connection.getContent();
  22.             System.out.println(echoMsg);
  23.             if(echoMsg.equals("echo:bye")) {
  24.                 //断开连接
  25.                 connection.disconnect();
  26.                 break;
  27.             }
  28.         }
  29.     }
  30. }
复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4