Linux下運行java RMI程序

安裝java

下載jdk
由於Oracle官網下載速度過慢,故在華爲鏡像站下載jdk https://repo.huaweicloud.com/java/jdk/
在這裏插入圖片描述
下載成功後用xftp傳至服務器上
將壓縮包解壓

tar -zxvf /usr/local/jdk-8u181-linux-x64.tar.gz

修改配置文件

vim /etc/profile

在文件末端加入以下語句

java_home 爲解壓後的路徑,可用pwd命令查看


export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JRE_HOME=$JAVA_HOME/jre

重啓服務器

reboot

測試是否成功

java -version
/*
java version "13" 2019-09-17
Java(TM) SE Runtime Environment (build 13+33)
Java HotSpot(TM) 64-Bit Server VM (build 13+33, mixed mode, sharing)
*/

運行java程序示例

源碼

本地端運行
服務器端運行

導入運行

示例程序目錄結構
在這裏插入圖片描述
將Java程序用xftp移動到服務器上,在/server/InterFace目錄下

javac *.java

編譯接口類中的所有Java文件
在/server/Server目錄下

javac -cp /你自己的路徑/server *.java
// -cp 導入依賴包的路徑 爲待導入包的父目錄

在/server目錄下

java Server.MyRMIServer
// 需要加入包名

問題解決

常用的檢測端口命令
服務器(linux):

start /b rmiregistry
// 後臺運行
lsof -i:端口號
// 檢測端口是否被佔用
kill -s 9  進程號 (linux)
taskkill /pid 進程號 /F (windows)

// 殺死進程 pid爲進程號

客戶端(windows):

ping ip 
// 檢測ip地址是否可達
telnet ip 端口號
// 檢測端口是否可達
// 如果可達則會加入telnet頁面
// telnet服務需要自行開啓
java.rmi.ConnectException: Connection refused to host: 127.0.0.1

即連接某個局域網的的連接失效

這個問題其實是由rmi服務器端程序造成的。 客戶端程序向服務端請求一個對象的時候,返回的stub對象裏面包含了服務器的hostname,客戶端的後續操作根據這個hostname來連接服務器端。要想知道這個hostname具體是什麼值可以在服務器端bash中打入指令:hostname -i 如果返回的是127.0.0.1或其他局域網的地址,那麼你的客戶端肯定會拋如標題的異常了。

ans:

一:適用於Cenos系統

先在/etc/hosts裏添加一行,然後修改/etc/sysconfig/network文件裏面的HOSTNAME

如你的hosts文件原來內容
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1               localhost.localdomain localhost

# 機器的實際IP爲10.1.60.121,則可以添加以下內容

10.1.60.14       test  localhost

# 然後修改/etc/sysconfig/network文件的HOSTNAME=test,則可以訪問成功。

二:服務器端程序加入以下代碼

System.setProperty("java.rmi.server.hostname","服務器公網IP");

或者
服務器程序啓動的時候,java命令加一個參數:-Djava.rmi.server.hostname=服務器公網ip

**客戶端在獲取

通過Naming.lookup(…)獲取該遠程對象的引用後,調用方法時公網IP卻拒絕訪問

在從註冊中心得到遠程對象的引用後,客戶端與其建立另一個socket通道,若接口實現類通過繼承 UnicastRemoteObject 類,則該socket通道端口隨機,故由服務器防火牆的緣故,服務器拒絕訪問
故通過UnicastRemoteObject.exportObjec指定端口(此時接口實現類不需要繼承UnicastRemoteObject 類)

BookSystemInfo engine = new BookSystem();
BookSystemInfo skeleton = ( BookSystemInfo) UnicastRemoteObject.exportObject(engine, 5678);

tip:可以通過Naming.list(…)方法列出所有可用的遠程對象。

序列化與反序列化

在遠程對象中參數和返回值爲基本類型的,默認序列化。若涉及自定義類(例如示例中的Book類),則會涉及到序列化與反序列的問題,對於Book類,必須滿足以下條件:

必須實現java.io.Serializable接口;

其中必須有serialVersionUID字段,格式如下:

private static final long serialVersionUID = 428674L;//大小隨便,客戶端與服務端一致即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章