现在的位置: 首页 > 综合 > 正文

使用自定義的SOCKET工廠的HELLO程序

2013年10月04日 ⁄ 综合 ⁄ 共 7679字 ⁄ 字号 评论关闭

流程圖如下:

流程圖

Hello.java:

public interface Hello extends java.rmi.Remote {
    //因為是跨網調用,所有申請時一定要拋出異常
    String sayHello() throws java.rmi.RemoteException;
}  

HelloClient.java:

import java.rmi.*;
import java.rmi.registry.*;
public class HelloClient {
    public static void main(String args[]) {
 /*
  * Create and install a security manager
  */
         /*getSecurityManager:
          * 取得系統安全接口,如果當前應用程序已經建立安全應用管理器,那么就返回該安全管理器
          * 否則就返回null
          */
 if (System.getSecurityManager() == null) {
     System.setSecurityManager(new SecurityManager());
 }
        try {
          /*getRegistry:
           * Returns a reference to the the remote object <code>Registry</code> for
           * the local host on the specified <code>port</code>.
           */
           //打開一個注冊,端口號為2002
     Registry registry = LocateRegistry.getRegistry(2002);
          /*lookup:
           * Returns the remote reference bound to the specified
           * <code>name</code> in this registry.
           */
          
            Hello obj = (Hello) registry.lookup("Hello");
            String message = obj.sayHello();
            System.out.println(message);

        } catch (Exception e) {
     System.out.println("HelloClient exception: " +
                               e.getMessage());
            e.printStackTrace();
        }
    }

}

HelloImpl.java:

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;

public class HelloImpl
  implements Hello
{
  /*
     * Constructs a HelloImpl remote object.
     */

  public HelloImpl()
  {
  }

  /*
     * Returns the string "Hello World!".
     */

  public String sayHello()
  {
    return "Hello World!";
  }

  public static void main(String[] args)
  {

    /*
  * Create and install a security manager
  */
    if (System.getSecurityManager() == null)
    {
      System.setSecurityManager(new SecurityManager());
    }

    byte pattern = (byte) 0xAC;
    try
    {
      /*
       * Create remote object and export it to use
       * custom socket factories.
       */
      HelloImpl obj = new HelloImpl();
      RMIClientSocketFactory csf = new XorClientSocketFactory(pattern);
      RMIServerSocketFactory ssf = new XorServerSocketFactory(pattern);
      /*
       * 使用一個由socket factory指定的轉換導出遠程對象,使它可以接收遠程輸入調用
       * 導出遠程對象使它能夠接收輸入調用,使用由所給的socket工廠指定的轉換
       * public static Remote exportObject(Remote obj, int port,
          RMIClientSocketFactory csf,
          RMIServerSocketFactory ssf)
       */
      Hello stub =
        (Hello) UnicastRemoteObject.exportObject(obj, 0, csf, ssf);

      /*
      * Create a registry and bind stub in registry.
      */
      //開啟服務端口
      LocateRegistry.createRegistry(2002);
      //獲得服務端口
      Registry registry = LocateRegistry.getRegistry(2002);
      //創建一個名為Hello的綁定服務
      registry.rebind("Hello", stub);
      System.out.println("HelloImpl bound in registry");

    }
    catch (Exception e)
    {
      System.out.println("HelloImpl exception: " + e.getMessage());
      e.printStackTrace();
    }
  }
}

XorServerSocketFactory.java:

import java.io.*;
import java.net.*;
import java.rmi.server.*;

public class XorServerSocketFactory
    implements RMIServerSocketFactory {

    private final byte pattern;

    public XorServerSocketFactory(byte pattern) {
 this.pattern = pattern;
    }
   
    public ServerSocket createServerSocket(int port)
 throws IOException
    {
 return new XorServerSocket(port, pattern);
    }
    /*
     * 一定要引用hashCode()及equals(Object obj)方法,因為這樣JAVA RMI引用將會
     * 正確的與使用相應的SOCKET工廠的遠程導出對象分享資源
     */
    public int hashCode() {
 return (int) pattern;
    }

    public boolean equals(Object obj) {
 return (getClass() == obj.getClass() &&
  pattern == ((XorServerSocketFactory) obj).pattern);
    }

}

XorClientSocketFactory.java:

public class XorClientSocketFactory
    implements RMIClientSocketFactory, Serializable {

    private final byte pattern;
   
    public XorClientSocketFactory(byte pattern) {
 this.pattern = pattern;
    }
   
    public Socket createSocket(String host, int port)
 throws IOException
    {
 return new XorSocket(host, port, pattern);
    }
   
    public int hashCode() {
 return (int) pattern;
    }
   
    public boolean equals(Object obj) {
 return (getClass() == obj.getClass() &&
  pattern == ((XorClientSocketFactory) obj).pattern);
    }

}

XorServerSocket.java:

import java.io.*;
import java.net.*;

class XorServerSocket extends ServerSocket {
 
    /*
     * The pattern used to "encrypt" and "decrypt" each byte sent
     * or received by the socket.
     */
    private final byte pattern;
 
    /*
     * Constructor for class XorServerSocket.
     */
    public XorServerSocket(int port, byte pattern) throws IOException {
        super(port);
        this.pattern = pattern;
    }
 
    /*
     * Creates a socket of type XorSocket and then calls
     * implAccept to wait for a client connection.
     */
    public Socket accept() throws IOException {
        Socket s = new XorSocket(pattern);
        //調用父類ServerSocket中的方法,也可以不加super
        //implAccept():ServerSocket的子類使用這個方法override accept()方法,
        //這樣可以返回他們自己的子類SOCKET
        super.implAccept(s);
        return s;
    }
}

XorSocket.java:

import java.io.*;
import java.net.*;

class XorSocket extends Socket { 
    /*
     * The pattern used to "encrypt" and "decrypt" each byte sent
     * or received by the socket.
     */
    private final byte pattern;
 
    /* The InputStream used by the socket. */
    private InputStream in = null;
 
    /* The OutputStream used by the socket */
    private OutputStream out = null;
 
    /*
     * Constructor for class XorSocket.
     */
    public XorSocket(byte pattern)
        throws IOException
    {
        //繼承Socket類的所有屬性
        super();
        this.pattern = pattern;
    }
 
    /*
     * Constructor for class XorSocket.
     */
    public XorSocket(String host, int port, byte pattern)
        throws IOException
    {
        //調用父類的方法,生成一個由指定主機的指定端口的SOCKET
        super(host, port);
        //這個pattern就是由用戶指定的一個加密參數
        this.pattern = pattern;
    }
 
    /*
     * Returns a stream of type XorInputStream. 重寫父類的getInputStream()方法
     */
    public synchronized InputStream getInputStream() throws IOException {
        if (in == null) {
            in = new XorInputStream(super.getInputStream(), pattern);
        }
        return in;
    }
 
    /*
     *Returns a stream of type XorOutputStream. 重寫父類的getOutputStream()方法
     */
    public synchronized OutputStream getOutputStream() throws IOException {
        if (out == null) {
            out = new XorOutputStream(super.getOutputStream(), pattern);
        }
        return out;
    }
}

XorInputStream.java:

import java.io.*;

class XorInputStream extends FilterInputStream {
 
   /*
    * The byte being used to "decrypt" each byte of data.
    */
    private final byte pattern;
 
    /*
     * Constructs an input stream that uses the specified pattern
     * to "decrypt" each byte of data.
     */
    public XorInputStream(InputStream in, byte pattern) {
        super(in);
 this.pattern = pattern;
    }
 
    /*
     * Reads in a byte and xor's the byte with the pattern.
     * Returns the byte.
     */
    public int read() throws IOException {
      //調用父類的讀方法
        int b = in.read();
        //If not end of file or an error, truncate b to one byte
 if (b != -1)
   //進行異或運算
   b = (b ^ pattern) & 0xFF;
                    
 return b;
    }
 
    /*
     * Reads up to len bytes
     */
    public int read(byte b[], int off, int len) throws IOException {
        //調用父類的讀方法
        int numBytes = in.read(b, off, len);
 if (numBytes <= 0)
     return numBytes;

        for(int i = 0; i < numBytes; i++) {
            //對讀入的每個字節都進行異或運算
     b[off + i] = (byte)((b[off + i] ^ pattern) & 0xFF);
        }
 
 return numBytes;
    }
}

XorOutputStream.java:

import java.io.*;

class XorOutputStream extends FilterOutputStream {
 
    /*
     * The byte used to "encrypt" each byte of data.
     */
    private final byte pattern;
 
    /*
     * Constructs an output stream that uses the specified pattern
     * to "encrypt" each byte of data.
     */
    public XorOutputStream(OutputStream out, byte pattern) {
        super(out);
 this.pattern = pattern;
    }
 
    /*
     * XOR's the byte being written with the pattern
     * and writes the result. 
     */
    public void write(int b) throws IOException {
       out.write((b ^ pattern) & 0xFF);
    }
}

還有一個安全策略文件傳不上來

自已弄一個

這里還是把運行步聚寫下來:

編譯及運行程序
第一步:
javac *.java

第二步:對引用類運行rmic命令
rmic HelloImpl

第三步:運行服務端

java -Djava.security.policy=policy HelloImpl

正確運行你會看到下面的顯示
      HelloImpl bound in registry

第四步:運行客戶端

java -Djava.security.policy=policy HelloClient
正常運行你會看到如下輸出
      Hello World! 

 

 

 

抱歉!评论已关闭.