我必须编写一个在两台不同机器上运行的简单Java RMI客户机/服务器程序。我正在使用Oracle的指南来帮助我:
我相信我已启动并运行服务器,但我无法让客户端工作。第一个问题是如果客户端java文件创建服务器对象但没有服务器代码,它如何编译。我理解服务器应该导出一个对象,但如果无法编译,客户端如何接收该对象?
指南说这样做:
此示例的源文件可以编译如下:
javac -d destDir Hello.java Server.java Client.java
其中destDir是放置类文件的目标目录。
然而,似乎这假设所有代码都在一台机器上的同一目录中。
我尝试过的一个解决方案是将所需的类文件复制到客户端计算机上,这样就可以编译,但这在现实世界中似乎不切实际。
编译完成后,我尝试运行客户端并收到此错误:
客户端异常:protocol = socket host = null
java.lang.IllegalArgumentException:protocol = socket host = null
asun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:170)在java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
在java.net.Socket.connect(Socket.java:579)
在java.net.Socket.connect(Socket.java:528)
在java.net.Socket。(Socket.java:425)
在java.net.Socket。(Socket.java:208)
在sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:147)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
在sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:341)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
在Client.main(Client.java:14)
这是我的代码:
服务器
import java.rmi.server.UnicastRemoteObject;
import java.rmi.Remote;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.util.Scanner;
interface ServerInfo extends Remote {
public String getDate() throws RemoteException;
public String getUpTime() throws RemoteException;
public String getMemUse() throws RemoteException;
public String getNetstat() throws RemoteException;
public String getUsers() throws RemoteException;
public String getProcesses() throws RemoteException;
public String Disconnect() throws RemoteException;
}
public class Server implements ServerInfo {
public Server() {}
public String getDate() throws RemoteException {
System.out.println("Sent date");
return TerminalCMD("date");
}
public String getUpTime() throws RemoteException {
System.out.println("Sent uptime");
return TerminalCMD("uptime");
}
public String getMemUse() throws RemoteException {
System.out.println("Sent Memory Usage");
return TerminalCMD("free -m");
}
public String getNetstat() throws RemoteException {
System.out.println("Sent Netstat");
return TerminalCMD("netstat");
}
public String getUsers() throws RemoteException {
System.out.println("Sent Users");
return TerminalCMD("who");
}
public String getProcesses() throws RemoteException {
System.out.println("Sent Processes");
return TerminalCMD("ps aux");
}
public String Disconnect() throws RemoteException {
System.out.println("Disconnecting Client...");
return "Disconnecting...";
}
public String TerminalCMD(String cmd) {
String info = "";
try {
Process runTerminal = Runtime.getRuntime().exec(cmd);
Scanner terminalReader = new Scanner(runTerminal.getInputStream());
while(terminalReader.hasNextLine()) {
info += terminalReader.nextLine() + "\n";
}
}
catch(Exception e) {
info = "Error";
}
return info;
}
public static void main(String[] args) {
try {
Server serverInstance = new Server();
ServerInfo stub = (ServerInfo)UnicastRemoteObject.exportObject(serverInstance, 0);
Registry registry = LocateRegistry.getRegistry(2541);
registry.bind("Instance1", stub);
System.out.println("Awaiting Connection...");
}
catch(Exception e) {
System.out.println("Server error: " + e.getMessage());
e.printStackTrace();
}
}
}
客户端
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Scanner kbreader = new Scanner(System.in);
int choice;
boolean quit = false;
String serverURL = "//CNT4505B.ccec.unf.edu/";
try {
Registry registry = LocateRegistry.getRegistry(serverURL, 2541);
ServerInfo serverInstance = (ServerInfo)registry.lookup("Instance1");
while(!quit) {
System.out.println("1 - Host current Date and Time\n2 - Host uptime\n3 - Host memory use\n4 - Host Netstat\n5 - Host current users\n6 - Host running processes\n7 - Quit");
choice = kbreader.nextInt();
switch(choice) {
case 1: System.out.println(serverInstance.getDate());
break;
case 2: System.out.println(serverInstance.getUpTime());
break;
case 3: System.out.println(serverInstance.getMemUse());
break;
case 4: System.out.println(serverInstance.getNetstat());
break;
case 5: System.out.println(serverInstance.getUsers());
break;
case 6: System.out.println(serverInstance.getProcesses());
break;
case 7: System.out.println(serverInstance.Disconnect());
quit = true;
break;
default: System.out.println("Invalid selection.");
break;
}
}
}
catch(Exception e) {
System.out.println("Client exception: " + e.getMessage());
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
LocateRegistry.getRegistry()
的第一个参数是主机名,而不是网址。
服务器和客户端共有任何RMI系统的某些组件。这些包括远程接口类本身,以及其中使用的任何应用程序类,依此类推,直到关闭。通常,您为共享类创建第三个项目。