Java RMI编译和运行时问题
我必须编写一个简单的JavaRMI客户机/服务器程序,在两台不同的机器上运行。我正在使用Oracle指南来帮助我:Java RMI编译和运行时问题,java,server,client,rmi,Java,Server,Client,Rmi,我必须编写一个简单的JavaRMI客户机/服务器程序,在两台不同的机器上运行。我正在使用Oracle指南来帮助我: 我相信我已经启动并运行了服务器,但是我无法让客户端工作。第一个问题是,如果客户端java文件创建了一个服务器对象,但没有服务器代码,它如何编译。我知道服务器应该导出一个对象,但是如果不能编译,客户端如何接收对象呢 指南上说要做到这一点: 此示例的源文件可以按如下方式编译: javac-d destDir Hello.java Server.java Client.java 其
javac-d destDir Hello.java Server.java Client.java
其中destDir是将类文件放入的目标目录 然而,这似乎是假设所有代码都在一台机器上的同一目录中 我尝试的一个解决方案是将所需的类文件复制到客户机上,这样就可以进行编译,但这在现实世界中似乎不切实际 编译后,我尝试运行客户端,但出现以下错误: 客户端异常:协议=套接字主机=空
java.lang.IllegalArgumentException:protocol=socket host=null
asun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:170) 位于java.net.socksocketimpl.connect(socksocketimpl.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) 位于sun.rmi.transport.proxy.rmismastersocketfactory.createSocket(rmismastersocketfactory.java:147) 位于sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
位于sun.rmi.transport.tcp.tcpcchannel.createConnection(tcpcchannel.java:216) 位于sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
位于sun.rmi.server.UnicastRef.newCall(UnicastRef.java:341)
在sun.rmi.registry.RegistryImpl_Stub.lookup(未知源)
位于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();
}
}
}
的第一个参数是主机名,而不是URLLocateRegistry.getRegistry()
- 任何RMI系统都有一些对服务器和客户机通用的组件。这些包括远程接口类本身,以及其中使用的任何应用程序类,等等,直到关闭为止。通常为共享类创建第三个项目