8.4. Cơ chế gọi phương thức tù’ xa
8.4.11. Ví dụ minh họa
Trongví dụ này, chúng ta định nghĩa một phương thức từ xa. Phương thức này được kích hoạtmỗi khi Clientgọi nó. Dướiđây là các bước đế xây dựng ứng dụng:
Bước 01: Tạo giao diện (interface) khai báo các phương thức được gọi từ xa của đốitượng.
Cúpháp tổng quát như sau:
import java.rmi.Remote;
importjava.rmi.RemoteException;
publicinterface InterfaceName extends Remote {
ReturnTyperemoteMethodOneQ throws RemoteException;
ReturnType remoteMethodTwoQ throwsRemoteException;
}__________________________________________________________________
Định nghĩa giao diện ờ xa có tên là Helloltf, có phương thức được gọi từ xa là String sayHelloQ như sau:
importjava.rmi.Remote;
import java.rmi.RemoteException;
publicinterface Helloltfextends Remote { StringsayHelloQ throws RemoteException;
}
Bước 02: Tạo lớp cài đặt cho giao diện đã được khai báo.
Cú pháp tống quát như sau:
import java.rmi. server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class RemoteClass extends UnicastRemoteObject implements InterfaceName {
public RemoteClassQ throwsRemoteException { superQ;
... // Cài đặt phương thức }
public ReturnTyperemoteMethodOneO throws RemoteException { ... // Cài đặt phương thức
}
public ReturnType remoteMethodTwoQthrows RemoteException { ... // Cài đặt phương thức
} }
Định nghĩa lớp cài đặt có tên là Hello để cài đật cho giao diện ở xa Helloltf.
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class Hello extends UnicastRemoteObjectimplements Helloltf { public HelloQ throws RemoteException {
superQ;
}
public String sayHelloQ { return "Hello World !";
}
}__________________________________________________________
Bước 03: Viet chương trình Server.
Cúpháp tổng quát như sau:
importjava.rmi. Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
public class ServerName {
public static void mainfString args[]) { if (System.getSecurityManagerO == null] {
11 Cài đặt cơ chế bảo mật
System.setSecurityManagerfnew RMISecurityManagerQ);
} try{
//Tạo cácđối tượng từ xa
RemoteClassremoteObject= new RemoteClassQ;
// Đăng ký tên cho cácđối tượng từ xa
Naming.rebind("RegistryName", remoteObject);
}
catch (Exception e) { System.out.println("Error:..." + e);}
}
}__________________________________________________________________
Tạo Server có tên HelloServer chứa một đối tượng từxa obj thuộc lớp cài đặt Hello và đăng ký tên cho đối tượng obj là HelioObject.
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
public class HelloServer{
public static void main(String args[]J { if(System.getSecurityManagerQ == null) {
System.setSecurityManagerfnew RMISecurityManagerQ);
} try{
Hello obj = new HelloQ; Naming.rebindf'HelloObject", obj); System.out.println("HelloObject is registried");
}
catch (Exception e) { System.out.println("Error: " + e); } }
}__________________________________________________________________
Bước 04: Vietchươngtrình Client.
Cú pháp tông quát như sau:
import java.rmi.Naming;
import java.rmi.RemoteException;
public class Client {
public static void main(String args[]J {
StringremoteObjectURL= "rmi://NameServer/RegistryName";
Interfacename object = null;
try{
object = (InterfaceName)Naming.lookup(remoteObjectURL);
objectremoteMethodOneQ;
}
catch (Exception e) { System.out.println(" Error: ”+ e);} }
}__________________________________________________________________
Tạo client có tên là HelioClient, tìm đối tượng HelloObject trên rmiregistry chang hạn tại địa chỉ 172.18.211.160. Gọi phương thức sayHello() và in kết quả trả về ra màn hình.
import java.rmi.Naming;
import java.rmi.RemoteException;
public class HelloClient{
public static voidmainfString args[]) {
String helloURL= "rmi://172.18.211.160/HelloObject";
Helloltf object= null;
try{
object = (HelloItf)Naming.lookup(helloURL);
String message = objectsayHelloQ;
System.out.println(message);
}
catch (Exception e) { System.out.printlnf'Client Error:" + e); } }
}__________________________________________________________________
Bước 05: Dịch cáctập tin nguồn theodạng RMI đế tạo ra các lóp tương ứng và stub cho Client, Skeleton cho Server.
Cúpháp tổng quátnhư sau:
javac InterfaceName.java RemoteClass.java Server.java Client.java
(Tạo ra các lớp InterfaceName.class RemoteClass.class Server.class
rmic RemoteClass
(Tạo ra các lớp cho Skeleton và Stub: RemoteClasS-Skel.class RemoteClass_Stub. class)
Biêndịch các lớp trong Hello:
javac Hello.java Helloltf.java HelloServer.java HelloClient.java rmic Hello.class
Bước 06: Khởi động dịch vụ rmiregistry.
Cú pháp tổng quát như sau:
startrmiregistry [port] //cổng mặc định là 1099.
Khiđó rmiregistry server sẽ chạy trên một cửa số mới,giữ nguyên cửa số này, không đóng nó lại.
Bước 07: Thực hiện chưong trình Server.
Cú pháp tống quát:
java -Djava.security.policy=ƯrlOfPolicyFile ServerName
Trong đó, UrlOfPolicyFilelà địa chỉ theo dạng URL của tập tin mô tả chính sách về bảo mật mã nguồn của Server (policy file). Nó quy định“ai” (chưong trình, máy tính, tiến trinh trên) sẽ có quyền download các tập tin của nó trong đó có stub. Đe đơn giản trong phần này ta cho phép tất cả mọi người đều có quyền download các tập tin của Server. Khi triển khai các ứng dụng thật sự ta phải có các chính sách bảo mậtnghiêm ngặthơn (Tham khảo tài liệuvề SecuritycủaJava). Filepolicy có dạng như sau:
grant{
java.security.AllPermission; // Cho phép truy cập mọi thứ };
Lưu nội dung trên vào tập tin có tênpolicy.txt. Sau đó, thực thi HelloServer với địa chỉ của tập tinpolicy.txt, giả sử, nằm ở đường dẫn D:\policy.txt trên hệ đều hành Windows như sau:
java -Djava.security.policy=file:///D:/policy.txt HelloServer Bước 08: Thực thichương trình Client.
Cú pháp tống quát như sau:
java ClientName
Thựcthi HelloClient với địa chỉ của rmiregistry đưa vào trong tham số.
Đe thực thi được chươngtrình HelloClient cần có hai class nằm cùng thư mục với nó làHelloltf.class và Hello Stub.class.
BÀI TẬP
8.1. Viết chươngtrình có chức năngtươngtựnhư Nslookup:
- Nhập vào một tên và tìm ra địa chỉ IP tương ứng.
- Nhập vào một địa chỉ IP và tỉm ra tên.
8.2. Sửa lại chương trình 8.2 (lóp STCPEchoServer) cho phép đảo ngược xâu ký tự nhận được từ Client và sau đó gửi ngược lại cho Client. Ví dụ: Server nhận được chuồi ký tự“Hello”, sẽ trả về cho Client chuồi “olleH”.
8.3. Sửa lại chương trình 8.4 (lóp UDPEchoServer) chophép đảo ngược xâu ký tự nhận được từ Client và sau đó gửi ngược lại cho Client. Ví dụ: Server nhận được chuỗi ký tự “Hello”, sẽ trả về cho Client chuỗi “olleH”.
8.4. Xây dựng hai lóp CountingServer vàCountingclient. Chương trình CountingServer lắng nghe ờ cống 2019 và nhận các ký tự từ Countingclient và trả về kết quả theo giao thức sau:
-Nhận ký tự “0”: gửi về chuỗi “Không\n”.
- Nhận ký tự “1”: gửi về chuỗi “Một\n”.
-Nhận ký tự “9”: gửi về chuỗi “Chín\n”.
- Neu nhận ký tự khác số: gửi về chuỗi “Không phải ký tự số\n”.
Chương trình Countingclient nhận địa chỉ IP của CoutingServer từ đối số của chương trình, sau đó kết nối đến CountingServer và gửi 1 ký tự từ bàn phím tới Server,nhận chuỗi kết quả trả về từServervà hiển thị lên màn hình.
8.5. Viết chương trình CountingClient2 tương tự như lóp Countingclient ở bài tập 8.4 nhưngnhận địa chỉ và cổng của CountingServer từđối số củachươngtrinh.
8.6. Viết chương trình WebGet nhận vào hai đối số:
-Đối số 1: địa chỉ của một Web Server.
-Đối số 2: địa chỉ URL của một trang webtrênWeb Server đó.
Ketnối đến Web Server và thực hiện:
- Gửi yêu cầu lấy trang web có URL trên.
-Nhận kết quả trả về từ Web Server và in ra màn hình (có thể mờ rộng để lưu vào một tập tin HTML).
8.7. Cài đặt STCPCountingServer:
-Phục vụ theo chếđộ tuầntự.
- Lắng nghe trên cổng 2012.
- Hoạt động theogiao thức sau:
+ Nhận ký tụ “0”: gửi về chuỗi “Không\n”. +Nhận ký tụ “1”: gửi về chuỗi “Một\n”.
+ ....
+ Nhận ký tự “9”: gửi về chuỗi “Chín\n”.
+ Nếu nhận ký tựkhác số: gửi về chuỗi “Không phải ký tựsố\n”.
- Mờ cửa sổ lệnh 1:
Thực thi STCPCountingServer.
- Mở cửa số lệnh 2:
Thục thi Countingclient với địa chỉ IP củaSTCPCountingServer.
Chương 9