主题:RMI远程文件下载
最近项目中要求实现远程文件下载, 原先如果被下载文件放在项目应用的 web 路径下那可以通过很多经典的方式去实现,但现在被下载的文件和项目应用不在同一台服务器上, 原来的方式无法实现,因为被下载文件的路径都是以 // ip地址 / 目录1/目录1/ *.* 来表示的, 网上参考了一下, 好象可以用 java RMI 实现 , 所以写了一个Demo, 客户端和服务端都放在本机(winXP系统)
(源码见附件 服务端:server.rar 客户端:client.rar)
1.远程接口
FileInterface.java代码如下:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileInterface extends Remote {
public byte[] downloadFile(String fileName) throws
RemoteException;
}
2.实现远程的接口
import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject
implements FileInterface {
private String name;
public FileImpl(String s) throws RemoteException{
super();
name = s;
}
public byte[] downloadFile(String fileName){
try {
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
} catch(Exception e){
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}}}
3.编写服务端
(1)创建并安装一个RMISecurityManager实例。
(2)创建一个远程对象的实例。
(3)使用RMI注册工具来注册这个对象。
FileServer.java 代码如下:
import java.io.*;
import java.rmi.*;
public class FileServer {
public static void main(String argv[]) {
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
FileInterface fi = new FileImpl("FileServer");
Naming.rebind("//127.0.0.1/FileServer", fi);
} catch(Exception e) {
System.out.println("FileServer: "+e.getMessage());
e.printStackTrace();
}}}
4.编写客户端
import java.io.*;
import java.rmi.*;
public class FileClient{
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
try {
String name = "//" + argv[1] + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
byte[] filedata = fi.downloadFile(argv[0]);
File file = new File(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
}}}
demo步骤:
1. 使用rmiregistry或者start rmiregistry 命令来运行RMI注册工具到window系统默认的端口上:
prompt > rmiregistry (此处没写端口,默认使用1099)
2. 运行服务FileServer
prompt > java -Djava.security.policy=policy.txt FileServer
此时不知道为什么老是报拒绝连接的错误,请各位大侠指正,不胜感激
FileServer: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185 )
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at FileServer.main(FileServer.java:11)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:516)
at java.net.Socket.connect(Socket.java:466)
at java.net.Socket. <init>(Socket.java:366)
at java.net.Socket. <init>(Socket.java:179)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirect SocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMaster SocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569) ... 6 more
(源码见附件 服务端:server.rar 客户端:client.rar)
1.远程接口
FileInterface.java代码如下:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileInterface extends Remote {
public byte[] downloadFile(String fileName) throws
RemoteException;
}
2.实现远程的接口
import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject
implements FileInterface {
private String name;
public FileImpl(String s) throws RemoteException{
super();
name = s;
}
public byte[] downloadFile(String fileName){
try {
File file = new File(fileName);
byte buffer[] = new byte[(int)file.length()];
BufferedInputStream input = new
BufferedInputStream(new FileInputStream(fileName));
input.read(buffer,0,buffer.length);
input.close();
return(buffer);
} catch(Exception e){
System.out.println("FileImpl: "+e.getMessage());
e.printStackTrace();
return(null);
}}}
3.编写服务端
(1)创建并安装一个RMISecurityManager实例。
(2)创建一个远程对象的实例。
(3)使用RMI注册工具来注册这个对象。
FileServer.java 代码如下:
import java.io.*;
import java.rmi.*;
public class FileServer {
public static void main(String argv[]) {
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
FileInterface fi = new FileImpl("FileServer");
Naming.rebind("//127.0.0.1/FileServer", fi);
} catch(Exception e) {
System.out.println("FileServer: "+e.getMessage());
e.printStackTrace();
}}}
4.编写客户端
import java.io.*;
import java.rmi.*;
public class FileClient{
public static void main(String argv[]) {
if(argv.length != 2) {
System.out.println("Usage: java FileClient fileName machineName");
System.exit(0);
}
try {
String name = "//" + argv[1] + "/FileServer";
FileInterface fi = (FileInterface) Naming.lookup(name);
byte[] filedata = fi.downloadFile(argv[0]);
File file = new File(argv[0]);
BufferedOutputStream output = new
BufferedOutputStream(new FileOutputStream(file.getName()));
output.write(filedata,0,filedata.length);
output.flush();
output.close();
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
}}}
demo步骤:
1. 使用rmiregistry或者start rmiregistry 命令来运行RMI注册工具到window系统默认的端口上:
prompt > rmiregistry (此处没写端口,默认使用1099)
2. 运行服务FileServer
prompt > java -Djava.security.policy=policy.txt FileServer
此时不知道为什么老是报拒绝连接的错误,请各位大侠指正,不胜感激
FileServer: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185 )
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at FileServer.main(FileServer.java:11)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:516)
at java.net.Socket.connect(Socket.java:466)
at java.net.Socket. <init>(Socket.java:366)
at java.net.Socket. <init>(Socket.java:179)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirect SocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMaster SocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569) ... 6 more