java - 为java程序制作本地远程的最简单方法是什么?

标签 java sockets server client inputstream

我正在尝试为 java 程序创建一个远程客户端,我已经阅读了有关套接字的内容,但似乎有几种协议(protocol)和方法可以实现这一点。

基本上,我只想能够在应用程序的客户端部分按下按钮,并在本地激活服务器部分的相关功能。

我想我应该在单独的线程中监听套接字并传输/读取字符串以了解推送的内容?主要是为了学习目的。

我想要一些建议/快速解释来了解如何实现这一点,我已经看到了基本客户端服务器通信的示例,但我没有找到任何关于如何完成此操作的真正清晰的内容(是否是新线程? )并且显然我似乎没有完全理解输入流/输出流的概念。

最佳答案

让两个 Java 应用程序(服务器和客户端)相互通信(尤其是在同一台计算机上)的一种非常简单的方法是使用 Remote Method Invocation (落基山研究所)。 RMI 允许在 Java 应用程序之间共享对象,这意味着它是一种非常高级的通信抽象,并且无需编写自定义网络代码或处理所涉及的并发性。

这是一个非常基本的示例:

第 1 步:创建通用接口(interface)

创建一个通用接口(interface)来描述服务器提供的功能:

package com.example.remote;

import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RemoteControlInterface extends Remote, Serializable {

    public void sendCommand(String command) throws RemoteException;

}

此接口(interface)必须扩展java.rmi.Remotejava.io.Serialized,并且每个方法都必须能够抛出java.rmi.RemoteException。将其放入库中,并在服务器和客户端中使用该库。如何完成此操作取决于您使用的 IDE。最简单的方法可能是将服务器、客户端和公共(public)库放在同一个项目中。

第 2 步:创建服务器应用程序

在服务器应用程序中创建通用接口(interface)的实现:

package com.example.remote.server;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import com.example.remote.RemoteControlInterface;

public class RemoteControl extends UnicastRemoteObject implements RemoteControlInterface {

    private static final long serialVersionUID = 1L;

    protected RemoteControl() throws RemoteException {
    }

    @Override
    public void sendCommand(String command) throws RemoteException {
        System.out.println("remote control asked for " + command);
    }

}

公共(public)接口(interface)的实现必须扩展java.rmi.server.UnicastRemoteObject

创建实际的服务器应用程序,将 RemoteControlInterface 的实现实例发布为 remoteControl 作为监听端口 1234 的服务器。

package com.example.remote.server;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Server {

    public static void main(String[] args) throws MalformedURLException, RemoteException, AlreadyBoundException {
        Registry registry = LocateRegistry.createRegistry(1234);
        registry.bind("remoteControl", new RemoteControl());
    }

}

第 3 步:创建客户端应用程序

创建实际的客户端应用程序,该应用程序连接到端口 1234 上的服务器,并使用名称 remoteControl 检索已发布的 RemoteControlInterface 实例。

package com.example.remote.client;

import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import com.example.remote.RemoteControlInterface;

public class Client {

    public static void main(String[] args) throws AccessException, RemoteException, NotBoundException {
        Registry registry = LocateRegistry.getRegistry(1234);
        RemoteControlInterface greetingService = (RemoteControlInterface) registry.lookup("remoteControl");
        greetingService.sendCommand("helloWorld");
    }

}

这将导致服务器应用程序在其控制台上打印remote control requests for helloWorld

公共(public)接口(interface)中所有方法的参数和返回值可能为:

  • 任何原始 Java 类型(boolean、int...)
  • 只要两个应用程序具有相同版本的相应类文件,两个应用程序共享的实现 java.io.Serialized 的任何类(String、Date...)。这封信适用于 JRE 提供的所有类以及公共(public)库中的所有类。

虽然 RMI 可以做更多事情,但这应该足以实现简单的远程控制。

关于java - 为java程序制作本地远程的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32704199/

相关文章:

node.js - 使用 Express 将静态内容提供给子域?

macos - 如何在ASyncSocket中检测远程断开连接

python - 尽管有多个套接字,但所有接口(interface)都未被使用

linux - 是否有原始套接字的安全接口(interface)?

java - 如何将 Long 转换为 byte[] 并返回到 java

javascript - 对数据库和服务器使用 Promise

windows - Dockerfile vs从容器创建镜像

java - 捕获所有 java.lang.Error 用于记录目的并允许它们在堆栈中向上工作

java - Spring 应用程序上下文 : access web. xml 上下文参数?

java - Java 中的函数类似于 C 中的 printf