Мне нужно написать простую программу клиента/сервера Java RMI, которая работает на двух разных машинах. Я использовал руководство Oracle, чтобы помочь мне:Java RMI Compilation and Run-time Issues
Я считаю, что у меня есть сервер и работает, но я не могу получить клиент для работы. Первая проблема заключается в том, как скомпилировать java-файл клиента, если он создает объект сервера, но не имеет кода сервера. Я понимаю, что сервер должен экспортировать объект, но как клиент может получить объект, если он не может скомпилировать?
Руководство говорит, чтобы сделать это:
The source files for this example can be compiled as follows:
javac -d destDir Hello.java Server.java Client.java
where destDir is the destination directory to put the class files in.
Тем не менее, кажется, что это предполагает, что весь код находится в том же каталоге, на одной машине.
Одним из решений, которые я пытался, было просто скопировать требуемый файл класса на клиентскую машину, что позволило ему скомпилировать, но это кажется непрактичным в реальном мире.
После компиляции я попытался запустить клиент и получил эту ошибку:
Client exception: protocol = socket host = null
java.lang.IllegalArgumentException: protocol = socket host = null
asun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:170)at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.(Socket.java:425)
at java.net.Socket.(Socket.java:208)
at 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)
at 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)
at 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();
}
}
}
Client
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();
}
}
}