java rmi 实例:远程执行cmd

rmi,远程方法调用,将service通过rmi接口对外进行发布,客户端通过地址+端口远程调用服务。

项目结构(java项目即可,jdk无要求):

--src
  --rim2
    --CmdService.java
    --CmdServiceImpl.java
    --GetService.java
    --SetService.java
  --cfg.properties

代码:

应用服务部分:

定义一个服务接口,集成rmi的Remote接口:

package rim2;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Map;

public interface CmdService extends Remote {
	public Map<String, String> executeCmd(String cmd) throws RemoteException;
}

服务实现:

package rim2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;

public class CmdServiceImpl extends UnicastRemoteObject implements CmdService {
	public CmdServiceImpl() throws RemoteException {
	}

	public Map<String, String> executeCmd(String cmd) throws RemoteException {
        Runtime rt = Runtime.getRuntime(); // 运行时系统获取
        Map<String, String> lineMap = new HashMap<String, String>();//存放返回值
        try {
            Process proc = rt.exec(cmd);// 执行命令
            InputStream stderr = proc.getInputStream();//执行结果 得到进程的标准输出信息流
            InputStreamReader isr = new InputStreamReader(stderr);//将字节流转化成字符流
            BufferedReader br = new BufferedReader(isr);//将字符流以缓存的形式一行一行输出
            String line = null;
            while ((line = br.readLine()) != null) { 
                if (line!=null && !"".equals(line)) {
                    String[] strLine = line.split(":");
                    if(strLine.length>=2) {
                        lineMap.put(strLine[0].trim(), strLine[1].trim());
                    }
                    
                }
            }
            br.close();
            isr.close();
            stderr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return lineMap;
    }
}

备注:java.rmi.server.UnicastRemoteObject类
通常,远程对象都 继承UnicastRemoteObject类,UnicastRemoteObject 类提供远程对象所需的基本行为。在这个类中提供了支持创建和导出远程对象的一系列方法,一个对象继承UnicastRemoteObject它将获得以下特性:

A、对这种对象的引用至多仅在创建该远程对象的进程生命期内有效
B、使得远程对象既有使用TCP协议通信的能力(Socket)
C、对于客户端与服务器的调用、传参、返回值等操作使用流的方式来处理
其他的,java.rmi.registry.LocateRegistry类提供了一系列的方法用于创建、获取Registry实例的方法;在Registry接口中,定义了一系列的方法,用于操作远程对象包括:绑定对象(bind)、获取对象(lookup)、重写绑定(rebind)、解除绑定(unbind)和返回注册表绑定列表(list)方法(也可以使用java.rmi.Naming来操作)。

发布服务:

package rim2;

import java.io.InputStream;
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import java.util.Properties;

public class SetService {
	public static void main(String[] args) {
		try {
			Properties properties = new Properties();
			InputStream in = GetService.class.getClassLoader().getResourceAsStream("./cfg.properties");
			properties.load(in);
			String serverip = properties.getProperty("serverip");
			String serverport = properties.getProperty("serverport");
			String rmiString = "rmi://"+serverip+":"+serverport+"/cmdService";
			
			CmdService studentService = new CmdServiceImpl();
			LocateRegistry.createRegistry(Integer.parseInt(serverport));// 定义端口号
			Naming.rebind(rmiString, studentService);
			System.out.println("服务已启动");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

为了方便使用,ip、端口信息配置化:

cfg.properties

serverip:127.0.0.1
serverport:5008

客户端调用代码:

package rim2;

import java.io.InputStream;
import java.rmi.Naming;
import java.util.Map;
import java.util.Properties;

public class GetService {
	public static void main(String[] args) {
		try {

			Properties properties = new Properties();
			InputStream in = GetService.class.getClassLoader().getResourceAsStream("./cfg.properties");
			properties.load(in);
			String serverip = properties.getProperty("serverip");
			String serverport = properties.getProperty("serverport");
			String rmiString = "rmi://"+serverip+":"+serverport+"/cmdService";

			CmdService studentService = (CmdService) Naming.lookup(rmiString);
			Map<String, String> map = studentService.executeCmd("ifconfig");
			for (String ket : map.keySet()) {
				System.out.println(map.get(ket));
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

简单示例参考:https://www.cnblogs.com/qujiajun/p/4065857.html

猜你喜欢

转载自blog.csdn.net/yygg329405/article/details/83999583