Tải bản đầy đủ (.doc) (135 trang)

TÌM HIỂU KỸ THUẬT LẬP TRÌNH PHÂN TÁN TRONG JAVA

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.65 MB, 135 trang )

Khóa luận tốt nghiệp 
MỤC LỤC
Danh mục hình ảnh 7
Danh mục từ viết tắt 9
PHẦN I:
TÌM HIỂU KỸ THUẬT LẬP TRÌNH PHÂN TÁN TRONG JAVA
1. Chương 1: TỔNG QUAN VỀ LẬP TRÌNH PHÂN TÁN 7
1.1. Lập trình phân tán là gì? 7
1.2. Vấn đề gọi phương thức từ xa 8
1.3. Lập trình phân tán với Java 8
2. Chương 2: LẬP TRÌNH PHÂN TÁN VỚI RMI 10
1.1. Giới thiệu: 10
1.2. Kiến trúc RMI 12
1.3. Cài đặt ứng dụng RMI đơn giản 18
1.4. MỘT SỐ KHÁI NIỆM TRONG RMI 22
1.5. CHUYỂN THAM SỐ TRONG LỜI GỌI PHƯƠNG THỨC TỪ XA 27
1.6. TUẦN TỰ HÓA (SERIALIZABLE) ĐỐI TƯỢNG 37
1.7. MỘT SỐ KỸ THUẬT LẬP TRÌNH PHÂN TÁN VỚI RMI 41
3. CHƯƠNG 3: LẬP TRÌNH PHÂN TÁN VỚI CORBA 65
1.8. TỔNG QUAN VỀ CORBA 65
1.9. XÂY DỰNG ỨNG DỤNG CORBA TRONG MÔI TRƯỜNG JAVA 72
1.10. TÌM HIỂU JNDI VÀ DỊCH VỤ COS NAMING TRONG CORBA 79
1.11. MỘT SỐ KỸ THUẬT LẬP TRÌNH PHÂN TÁN VỚI CORBA 92
1.12. CORBA VÀ TRÌNH MÔI GIỚI ORB VISIBROKER 106
4. Chương 1:
ỨNG DỤNG LẬP TRÌNH PHÂN TÁN ĐỂ XÂY DỰNG HỆ THỐNG “TRIỂN
KHAI THI VÀ CHẤM THI TRẮC NGHIỆM QUA MẠNG LAN” 115
1.1. Đặt vấn đề 115
Trang 1
Khóa luận tốt nghiệp 
1.2. Xác định và đặc tả yêu cầu 115


1.3. Thiết kế hệ thống 123
1.4. Một số giao diện của chương trình: 130
Tổng kết đề tài 138
Tài liệu tham khảo 139
Trang 2
Khóa luận tốt nghiệp 
Danh mục hình ảnh
Hình 1.1-1: Mô hình triệu gọi các đối tượng từ xa 7
Hình 2.2-2: Biểu đồ minh họa hai lớp mô tả giao diện 13
Hình 2.2-3: Kiến trúc phân tầng của RMI 13
Hình 2.2-4: Hoạt động của các thành phần trong kiến trúc RMI 14
Hình 2.2-5: Vai trò của các lớp trung gian stub và skel 15
Hình 2.3-6: Triệu gọi đối tượng RMI Calculator từ xa 18
Hình 2.4-7: Cơ chế làm việc của trình khách và trình chủ trên máy ảo
Java22
Hình 2.4-8: Rmiregistry trong mô hình phân tán thực tế 23
Hình 2.4-9: Cơ chế nạp tự động lớp trung gian CalculatorImpl_Stub.class
xuống máy khách 26
Hình 2.5-10: Trình chủ và trình khách có thể triệu gọi lẫn nhau 33
Hình 3.1-11: Triệu gọi đối tượng CORBA thông qua trình môi giới trung
gian ORB 69
Hình 3.1-12: ORB giao tiếp với đối tượng thông qua các thông tin đặc tả
69
Hình 3.3-13: Cấu trúc cây của dịch vụ COS NAMING trong CORBA 80
Hình 3.4-14: Giao tiếp RMI-Over-IIOP giữa đối tượng trình chủ và trình
khách 102
Hình 3.5-15: Cơ chế quản lý đối tượng của CORBA theo đặc tả mới 112
Hình 1.2-16: Ca sử dụng (use-case) quản lý đề thi 117
Hình 1.2-17: Ca sử dụng (use-case) triển khai đề thi 119
Hình 1.2-18: Ca sử dụng (use-case): đăng nhập 120

Hình 1.2-19: Ca sử dụng (use-case) làm bài thi 121
Hình 1.2-20: Ca sử dụng (use-case) xem kết quả thi 122
Hình 1.3-21: Kiến trúc tổng quát của hệ thống 123
Hình 1.3-22: Biểu đồ tuần tự lớp thiết kế thực hiện ca sử dụng soạn đề
thi:124
Trang 3
Khóa luận tốt nghiệp 
Hình 1.3-23: Biểu đồ tuần tự lớp thiết kế thực hiện ca sử dụng triển khai
đề thi: 125
Hình 1.3-24: Biểu đồ tuần tự lớp thiết kế thực hiện ca sử dụng đăng
nhập126
Hình 1.3-25:Biểu đồ tuần tự lớp thiết kế thực hiện ca sử dụng làm bài thi
126
Hình 1.3-26: Biểu đồ tuần tự lớp thiết kế thực hiện ca sử dụng xem bài
làm127
Hình 1.3-27: Biểu đồ tuần tự lớp thiết kế thực hiện ca sử dụng kết thúc
bài làm 127
Hình 1.4-28: Giao diện soạn đề thi 130
Hình 1.4-29: Soạn câu hỏi có hình ảnh 131
Hình 1.4-30: Giao diện đăng nhập của thí sinh 131
Hình 1.4-31: Cảnh báo sai số báo danh 132
Hình 1.4-32: Giao diện bài làm của thí sinh 132
Hình 1.4-33: Cửa sổ khi chọn chức năng xem bài làm 133
Hình 1.4-34: Cảnh báo trước khi kết thúc bài làm 133
Hình 1.4-35: Kết quả bài thi của thí sinh 133

Trang 4
Khóa luận tốt nghiệp 
Danh mục từ viết tắt
Từ viết tắt Nghĩa của từ

CORBA Common Object Request Broker Architecture
COS Naming Common Object Services Naming
DII Dynamic Invocation Interface
IDL Interface Description Language
IIOP Interoperate Internet Object Protocol
IOR Interoperable Object References
JDK Java Development Kit
JNDI Java Naming Directory Interface
JRMP Java Remote Method Protocol
JVM Java Virtual Machine
OMG Object Management Group
ORB Object Request Broker
POA Portable Object Adapter (POA)
RMI Remote Method Invoke
TCP/IP Transmission Control Protocol/Internet Protocol
UDP/IP User Datagram Protocol/Internet Protocol
Trang 5
Khóa luận tốt nghiệp 
Lý do chọn đề tài
Ngôn ngữ lập trình Java do công ty Sun Microsystems phát triển vào đầu
thập kỷ 1990. Trải qua hơn 20 năm phát triển, Java thật sự đã lớn mạnh. Hiện tại,
Java đã có mặt trong hầu hết các lĩnh vực lập trình với các tên gọi quen thuộc như
Java.net, RMI, JDBC, JSP, Servlet, Java Mail, J2ME…
Java đang rất được ưu chuộng bởi nhiều đặc điểm nổi bật của nó:
- Hướng đối tượng (Object - oriented): Đây là xu hướng lập trình phổ
biến nhất hiện nay.
- Đa luồng (multithreaded): ngôn ngữ Java cho phép xây dựng trình
ứng dụng, trong đó nhiều quá trình có thể xảy ra đồng thời.
- Mạnh mẽ (robust): Khả năng mạnh phải phù hợp với thiết kế của
ngôn ngữ, và hướng nó vào việc khắc phục những hư hỏng bộ nhớ và đảm

bảo tính toàn vẹn dữ liệu. Java làm được điều đó.
- Tính động (dynamic): Java động vì nó được thiết kế để đáp ứng với
môi trường tác nghiệp luôn trong tình trạng thay đổi. Khi có yêu cầu mới
xuất hiện trên thị trường, các loại đối tượng mới có thể được bổ sung vào
ngay.
- Hiểu mạng (network-savvy): Java được lập ra để hoạt động trên
mạng và có các thủ tục để có thể quản lý các giao thức mạng như TCP/IP,
FTP và HTTP.
- Độc lập với cấu trúc (architecture neutral): Java không phụ thuộc
vào hệ máy (platform - loại máy, hệ điều hành)
Có thể nói Java xuất hiện đã tạo ra một cuộc cách mạng trong công nghệ
phần mềm. Java đang được phát triển từng ngày từng giờ bởi sự lao động không
mệt mỏi và tầm nhìn chiến lược của các nhà phát triển nó.
Chính vì những ưu điểm đó, bản thân em khi mới tiếp xúc với Java đã thấy
yêu thích ngôn ngữ này. Hơn nữa, với ý tưởng bài toán đặt ra ban đầu là xây dựng
một ứng dụng qua mạng nên em đã chọn mảng lập trình phân tán trong Java để
nghiên cứu và ứng dụng để xây dựng chương trình của mình.
Trang 6
Khóa luận tốt nghiệp 
PHẦN I:
TÌM HIỂU KỸ THUẬT LẬP TRÌNH PHÂN TÁN TRONG JAVA
1. Chương 1: TỔNG QUAN VỀ LẬP TRÌNH PHÂN TÁN
1.1. Lập trình phân tán là gì?
Lập trình thông thường trên máy cục bộ: Các đối tượng của chương trình là
thủ tục hay hàm được nạp trực tiếp vào bộ nhớ và thực thi ngay trên máy cục bộ.
Đối với những hàm có sẵn trong thư viện, người ta không quan tâm đến các hàm
này cài đặt và làm việc như thế nào mà chỉ quan tâm đến tham số truyền cho nó và
kết quả trả về.
Lập trình có sự giao tiếp giữa các máy khác nhau: tức là hai chương trình ở
hai máy có thể gọi lẫn nhau. Thực chất của việc giao tiếp này là sự giao tiếp của các

phương thức, các phương thức có thể gọi lẫn nhau. Vậy thì làm cách nào cài đặt
phương thức ở một máy và thực hiện lời gọi phương thức ở một máy khác? Đó
chính là nội dung của lập trình phân tán.
Có thể nói: lập trình phân tán là việc lập trình trên các máy khác nhau trong
đó các đối tượng của chương trình gồm phương thức và thuộc tính có thể triệu gọi
lẫn nhau.
Hình 1.1-1: Mô hình triệu gọi các đối tượng từ xa
Trang 7
Khóa luận tốt nghiệp 
Trong minh họa trên, các đối tượng A1 và A2 ở máy A có thể gọi nhau, B1
và B2 ở máy B cũng vậy, đó là lời gọi cục bộ. Tuy nhiên, đối tượng A1 ở máy A
cũng có thể gọi đối tượng C1 ở máy C hay B1 ở máy B cũng có thể gọi C1 ở máy
C, đó là những lời gọi từ xa.
1.2. Vấn đề gọi phương thức từ xa
Trên máy cục bộ, các phương thức đều được chương trình quản lý và định
vị trong vùng nhớ, người lập trình có thể cho phép thực hiện lời gọi một cách bình
thường mà không cần quan tâm đến việc chúng giao tiếp với nhau thế nào. Còn các
phương thức ở các máy khác nhau hoạt động trên hai tiến trình, không gian địa chỉ
khác nhau nên việc truyền tham số, tham chiếu đến địa chỉ của nhau không thể thực
hiện thông thường như trong trong cùng một máy được.
Lời gọi phương thức cục bộ luôn đưa về kết quả, có nghĩa là luôn thực hiện
được trong khi việc gọi các phương thức từ xa có thể không thực hiện được do sự
cố mạng.
Đối với hàm trên máy cục bộ, tham số truyền cho hàm thường được đưa
vào ngăn xếp rồi chương trình sẽ lấy ra để thực hiện trong khi tham số truyền cho
hàm ở xa phải được đóng gói và chuyển qua mạng theo giao thức mạng mới đến
được nơi cần đến.
1.3. Lập trình phân tán với Java
Có nhiều ngôn ngữ hỗ trợ lập trình phân tán, Java là một trong số đó với
hai thư viện chuẩn là RMI và CORBA. Thực chất RMI là một cơ chế gọi phương

thức từ xa đã được tích hợp trong ngôn ngữ Java. Vì Java là một ngôn ngữ lập trình
hướng đối tượng, nên phương pháp lập trình trong RMI là phương pháp hướng đối
tượng, do đó các thao tác hay các lời gọi phương thức đều liên quan đến đối tượng.
CORBA (Common Object Request Broker Architecture) là đặc tả của OMG
(Object Management Group) dành cho việc đạt được tính tương tác giữa các nút
tính toán phân tán. Mục tiêu của CORBA là định nghĩa một cấu trúc mà có thể cho
phép những môi trường không đồng nhất có thể liên lạc tại mức đối tượng, không
Trang 8
Khóa luận tốt nghiệp 
quan tâm đến người nào đã thiết kế ra hai điểm cuối của ứng dụng phân tán. Corba
là một ngôn ngữ trung lập được thực thi rộng rãi hơn trên các nền platform khác
nhau. Corba sử dụng một giao thức gọi là IIOP (Internet Inter-ORB Protocol) để
liên lạc giữa các hệ thống khác nhau.
Sự khác nhau giữa RMI và CORBA:
- RMI là một phần của bộ J2SDK và là các hàm thư viện hỗ trợ các lời gọi phương
thức từ xa và trả về giá trị cho các ứng dụng tính toán phân tán. Ở đây ngôn ngữ
Java được sử dụng ở cả phía gọi và phía bên phương thức được gọi
- CORBA là một chuẩn công nghiệp cho phép gọi các phương thức từ xa và nhận
kết quả trả về. Nhưng không giống như RMI, nó có thể được sử dụng khi bên phía
gọi và bên phía phương thức được gọi có thể sử dụng các ngôn ngữ lập trình khác
nhau, bao gồm cả trường hợp là cả hai bên đều không sử dụng ngôn ngữ Java
- RMI là một tập các hàm thư viện đơn giản vì cả hai bên đều sử dụng cùng một
ngôn ngữ lập trình và kiến trúc máy. Điều này sẽ làm cho vấn để triệu gọi phương
thức từ xa dễ giải quyết hơn.
- Bộ phát triển J2SDK cũng hỗ trợ cả RMI và CORBA, cho phép một đối tượng
Java gọi một đối tượng CORBA sử dụng hai cách tiếp cận khác nhau.
Trang 9
Khóa luận tốt nghiệp 

2. Chương 2: LẬP TRÌNH PHÂN TÁN VỚI RMI

1.1. Giới thiệu:
RMI (Remote Method Invoke)– triệu gọi phương thức từ xa - là công nghệ
được SUN giới thiệu đầu tiên trong JDK 1.1 (2/1997), công nghệ này đã mở ra một
thời kì mới cho lĩnh vực lập trình mạng. Mặc dù được thiết kế tương đối dễ sử dụng
nhưng RMI cũng là một công nghệ rất mạnh, cung cấp đầy đủ các công cụ để người
lập trình có thể phát triển ứng dụng phân tán một cách tốt nhất.
Trong JDK 1.1, RMI đã được tạo ra gần như đầy đủ và nó đã được bổ sung
hoàn chỉnh hơn trong JAVA 2 SDK. Ở mỗi ứng dụng, chúng ta sẽ thấy được sự
khác nhau giữa hai phiên bản này.
Mục đích chính của việc thiết kế ra RMI là cho phép người lập trình phát
triển các chương trình phân tán bằng Java với cú pháp và ngữ nghĩa giống như lập
trình thông thường. Để làm được việc này, họ đã ánh xạ các lớp và đối tượng làm
việc trong một máy ảo Java đơn thành các lớp và đối tượng làm việc trong một môi
trường phân tán.
Trong phạm vi bài khóa luận này, RMI được trình bày theo quan điểm lập
trình phân tán các đối tượng từ xa, hành vi của các đối tượng từ xa khác với các đối
tượng cục bộ. RMI định nghĩa hành vi của các đối tượng, và vấn đề ta cần quan tâm
là các đối tượng từ xa đó có thể thực thi khi nào và như thế nào, bộ nhớ được quản
lý ra sao, các thông số được truyền ra sao, kết quả trả về đâu và gọi phương thức từ
xa như thế nào…
• So sánh lập trình phân tán và phi phân tán trong Java:
Các thao tác Đối tượng cục bộ Đối tượng từ xa
Định nghĩa đối
tượng
Được định nghĩa bởi
một lớp – class
Được định nghĩa bởi interface và phải
được kế thừa (extends) từ giao diện
Remote interface
Trang 10

Khóa luận tốt nghiệp 
Mô tả đối
tượng
Được mô tả mở chính
lớp định nghĩa nó
Hành vi của đối tượng từ xa được tạo
ra bởi một lớp mô tả riêng cho
interface
Tạo đối tượng
Dùng phương thức khởi
tạo và từ khóa new
Một đối tượng từ xa được khởi tạo
trên một máy tính theo cách thông
thường. Một client không thể trực tiếp
khởi tạo đối tượng từ xa.
Truy xuất đối
tượng
Được truy xuất trực tiếp
thông qua một biến
tham chiếu đến đối
tượng đó
Được truy cập thông qua một biến
tham chiếu đến đối tượng nhưng là
tham chiếu gián tiếp vì mọi tác động
lên đối tượng đều thông qua lớp trung
gian và sau đó mới đến đối tượng.
Tham chiếu
Trong một máy ảo java
đơn, một đối tượng
tham chiếu trỏ trực tiếp

đến một đối tượng khác
trong vùng nhớ heap.
Một tham chiếu từ xa là tức là một
con trỏ trỏ đến đối tượng trung gian
trong vùng nhớ heap cục bộ. Đối
tượng trung gian cục bộ này chứa
thông tin cho phép nó có thể kết nối
đến đối tượng từ xa.
Hoạt động
tham chiếu
Trong một máy ảo java
đơn, một đối tượng sẽ
được cho là “còn sống”
nếu có ít nhất một tham
chiếu đến nó.
Trong môi trường phân tán, việc liên
lạc giữa các máy ảo Java có thể bị đứt
do sự cố mạng. Do vậy, một đối tượng
từ xa được xem là có một hành động
tham chiếu đến nó nếu nó đã được
truy xuất trong một khoảng thời gian
nhất định. Nếu tất cả các tham chiếu
từ xa đã mất hoặc hết hạn thì một đối
tượng từ xa sẽ được được giải phóng.
Finalization
Nếu một đối tượng cài
đặt phương thức
finalize(), nó được gọi
trước khi đối tượng
được thu dọn bởi chức

năng dọn rác.
Nếu một đối tượng cài đặt giao diện
Unreferenced, phương thức
unreferenced của giao diện đó sẽ được
gọi khi tất cả các tham chiếu từ xa bị
ngắt.
Thu dọn rác
Khi tất cả các tham
chiếu cục bộ đến một
đối tượng bị ngắt, nó sẽ
được xem là rác.
Chức năng thu dọn rác phân tán liên
kết làm việc với chức năng thu dọn
rác cục bộ. Nếu không có tham chiếu
từ xa nào và tất cả các tham chiếu cục
bộ đến một đối tượng bị ngắt, nó sẽ
được xem là rác.
Trang 11
Khóa luận tốt nghiệp 
Ngoại lệ
Hoặc là ngoại lệ
Runtime hoặc
Exceptions. Trình dịch
java buộc một chương
trình phải đảm nhiệm
bắt tất cả các ngoại lệ
RMI buộc các chương trình chịu bất
kì ngoại lệ nào của RemoteException
đưa ra. Điều này sẽ làm cho các việc
ném ngoại lệ của các ứng dụng phân

tán được bảo đảm.
Bảng so sánh lập trình phân tán và phi phân tán trong Java
1.2. Kiến trúc RMI
2.1.1. Giao diện (interface) - trái tim của RMI:
Kiến trúc RMI dựa trên một nguyên lý quan trọng: định nghĩa hành vi và
việc mô tả hành vi là hai khái niệm riêng biệt. RMI chấp nhận mã của định nghĩa
hành vi và mã của mô tả hành vi tách rời nhau và chạy trên các máy ảo Java độc
lập.
Điều cần làm của hệ thống phân tán là ở máy khách sẽ định nghĩa dịch vụ
mong muốn và máy chủ là nơi cung cấp các dịch vụ đó.
Trong RMI, việc định nghĩa một dịch vụ từ xa được viết bằng interface
trong Java. Mô tả chi tiết dịch vụ từ xa được viết bằng một lớp - class. Do đó, yếu tố
chính cần hiểu trong RMI là: các giao diện định nghĩa hành vi của đối tượng từ xa
và các lớp mô tả định nghĩa đó.
Hình 2.2-1: Giao diện và lớp mô tả giao diện.
Một giao diện không chứa mã thực thi. RMI hỗ trợ hai lớp mô tả giao diện
giống nhau. Lớp thứ nhất là mô tả hành vi và nó chạy trên server. Lớp thứ hai hoạt
động như một đối tượng trung gian cho các dịch vụ từ xa và nó chạy trên Client.
Trang 12
Khóa luận tốt nghiệp 
Biểu đồ minh họa:
Hình 2.2-2: Biểu đồ minh họa hai lớp mô tả giao diện
Một chương trình Client thực hiện lời gọi phương thức thông qua đối tượng
trung gian (proxy), RMI sẽ gửi đến máy ảo từ xa và từ đó đi đến đối tượng mô tả.
Bất kì giá trị trả về nào được tạo ra bởi đối tượng mô tả sẽ được gửi trở về proxy và
sau đó proxy sẽ chyển đến chương trình trên máy khách.
2.1.2. Kiến trúc phân tầng của RMI
RMI về cơ bản được xây dựng từ 3 lớp trừu tượng như mô hình dưới đây:

Hình 2.2-3: Kiến trúc phân tầng của RMI

Trang 13
Client Server
<<Interface>>
Service
Service
Proxy
Service
Implementation
RMI
Transport Layer
Remote Reference Layer
Stub & Skeletons Stub & Skeletons
Client Program Server Program
Remote Reference Layer
RMI
System
Khóa luận tốt nghiệp 
Hình 2.2-4: Hoạt động của các thành phần trong kiến trúc RMI
Bởi việc dùng kiến trúc phân lớp nên mỗi lớp có thể được cải tiến hoặc
thay thế mà không ảnh hưởng đến tính chất của hệ thống. Ví dụ như lớp transport
có thể được thay thế bởi một lớp theo phương thức kết nối UDP/IP mà không ảnh
hưởng các lớp trên nó.
• Lớp trung gian (STUB và SKELETON)
Như trên đã nói, việc gọi các phương thức từ xa là không giống như gọi
các phương thức thông thường trong cùng một máy. Vì thế, trong lập trình phân tán,
cơ chế gọi từ xa là các đối tượng trên hai máy khác nhau không gọi trực tiếp lẫn
nhau mà thông qua lớp trung gian. Người lập trình không cần phải quan tâm lớp
trung gian này chứa gì và làm việc ra sao. Lớp trung gian này sẽ đón đầu các lời gọi
phát sinh từ Client đến biến tham chiếu giao diện và gửi lại các lời gọi đó cho dịch
vụ RMI từ xa.

Lớp trung gian tồn tại ở hai phía máy khách (nơi thực hiện lời gọi) và máy
chủ (nơi cài đặt đối tượng được gọi). Phía máy khách, lớp trung gian được gọi là
Stub và phía máy chủ, lớp trung gian được gọi là Skeleton.
Trang 14
Khóa luận tốt nghiệp 
Hình 2.2-5: Vai trò của các lớp trung gian stub và skel
Ví dụ: Ta có đối tượng C1 được cài đặt trên máy C. Trình biên dịch Java sẽ
tạo ra 2 lớp là C1_Stub và C1_Skel. C1_Stub được chuyển đến máy A. Khi A1 trên
máy A gọi C1, nó sẽ chuyển lời gọi đến lớp C1_Stub. C1_Stub chịu trách nhiệm
đóng gói tham số, chuyển tham số qua mạng đến máy C. Trên máy C, C1_Skel sẽ
nhận thông tin của A do C1_Stub chuyển đến và chuyển vào vùng không gian địa
chỉ thích hợp mà C1 sẽ làm việc. Kết quả nếu có do phương thức của C1 trả về sẽ
được lớp C1_Skel đóng gói trả ngược về cho C1_Stub. C1_Stub sẽ chuyển giao kết
quả cuối cùng lại cho A1.
Bằng cơ chế này, hai đối tượng ở hai máy khác nhau có thể làm việc với
nhau như là hai đối tượng cục bộ. Hơn nữa, nếu mạng có sự cố thì lớp trung gian
Stub sẽ thông báo cho đối tượng tác động đến nó biết.
Trong Java 2 SDK, lớp skeleton không còn nữa. RMI dùng reflection để
tạo kết nối đến đối tượng dịch vụ từ xa.
• Remote Reference Layer
Lớp này được hiểu là làm phiên dịch và quản lý các tham chiếu tạo từ
Client đến đối tượng từ xa.
Trang 15
Computer C
Computer C
C2
C1
C1_skel
Computer A
Computer A

Computer B
Computer B
A2
A1
B1
C1_stub
B1_s
tub
B1_s
kel
Khóa luận tốt nghiệp 
Lớp Remote Reference Layers định nghĩa và hỗ trợ về ngữ nghĩa lời gọi
của kết nối RMI. Lớp này cung cấp một đối tượng RemoteRef, đối tượng này đại
diện cho liên kết đến đối tượng thực hiện dịch vụ từ xa.
Đối tượng stub dùng phương thức invoke() trong RemoteRef để chuyển
tiếp lời gọi phương thức. Đối tượng RemoteRef hiểu được ngữ nghĩa từ các lời gọi
từ xa.
Trong JDK 1.1, RMI chỉ cung cấp một cách cho Client để kết nối đến dịch
vụ từ xa: unicast – một nối một. Trước khi một Client có thể dùng dịch vụ từ xa,
dịch vụ từ xa đó phải được cài đặt trên Server và được export trong RMI. Nếu nó là
dịch vụ chính, nó phải được đặt tên và đăng kí đến RMI Registry.
Trong Java 2 SDK, RMI thêm một ý nghĩa mới cho kết nối client-server.
Trong phiên bản này, RMI hỗ trợ đối tượng từ xa tích cực. Khi một lời gọi phương
thức được tạo ra từ proxy đến một đối tượng activatable remote objects, RMI xác
định nếu đối tượng dịch vụ từ xa không hoạt động, RMI sẽ khởi tạo đối tượng và
khôi phục trạng thái của nó từ một file trên đĩa.
Có thể có các kiểu kết nối khác. VD: với multicast, một proxy đơn có thể
gửi cùng một yêu cầu đến nhiều đối tượng mô tả đồng thời… và nhận về sự đáp trả
đầu tiên.
• Transport Layer - Tầng vận chuyển

Tầng này có nhiệm vụ tạo kết nối giữa hai máy ảo Java (JVM). Tất cả các
kết nối là kết nối mạng cơ bản dùng giao thức TCP/IP.
Nếu hai máy ảo đang chạy trên một máy vật lý, chúng kết nối thông qua
giao thức ngăn xếp TCP/IP của chính máy tính đó. Điều này lí giải tại sao ta phải có
một cấu hình TCP/IP trên máy tính khi ta chạy các ví dụ.
TCP/IP cung cấp một kết nối an toàn giữa hai máy dựa trên địa chỉ IP và số
hiệu cổng. Trong phiên bản RMI hiện tại, kết nối TCP/IP được dùng là cơ bản cho
tất cả các kết nối từ máy này đến máy khác.
Lúc đầu dùng TCP/IP, RMI dùng giao thức JRMP, giao thức này là duy
nhất. Nhưng về sau, đã có hai phiên bản. Phiên bản đầu tiên được phát hành với
Trang 16
Khóa luận tốt nghiệp 
JDK 1.1, RMI yêu cầu dùng lớp Skeleton trên server. Phiên bản thứ 2 được phát
hành với Java 2 SDK. Nó đã được cải tiến để đạt hiệu năng và không yêu cầu lớp
skeleton. Một vài thay đổi với Java 2 SDK là interface không đòi hỏi kế thừa từ
java.rmi.Remote và các phương thức không cần thiết ném ra ngoại lệ
RemoteException
SUN và IBM đã liên kết làm việc cho phiên bản mới của RMI được gọi là
RMI-IIOP, RMI-IIOP dùng giao thức IIOP để thay thế cho JRMP.
Trang 17
Khóa luận tốt nghiệp 
1.3. Cài đặt ứng dụng RMI đơn giản
Ở ứng dụng phân tán RMI đơn giản này, ta cần có hai chương trình, một
chương trình chạy ở Server sẽ chờ phục vụ yêu cầu tính toán và một chương trình
yêu cầu chạy ở máy Client.
Hình 2.3-6: Triệu gọi đối tượng RMI Calculator từ xa
 Ở chương trình trên Server, ta cần mô tả lớp giao tiếp của đối tượng
Calculator, sau đó cài đặt chi tiết cho đối tượng Calculator và đưa cài đặt
này vào trong một chương trình điều khiển gọi là CalculatorServer.
o Đầu tiên, ta đặc tả lớp giao tiếp của đối tượng Calculator:

// Calculator.java
import java.rmi.*;
interface Calculator extends Remote
{
public int Add(int a,int b) throws RemoteException;
}
Giải thích:
Mục đích của ứng dụng là gọi từ xa đối tượng Calculator cũng như các
phương thức của nó, để làm được như vậy, ta cần cài đặt đối tượng Calculator là
một interface và interface này được kế thừa từ interface Remote. Remote là
interface rỗng, nó có chức năng là thông báo cho máy ảo Java biết interface kế thừa
từ nó (Calculator) có khả năng giao tiếp từ xa.
o Cài đặt chi tiết cho đối tượng Calculator:
// CalculatorImpl.java
import java.rmi.*;
Trang 18
Client Server
CalculatorClie
nt
Calculator
Calcul
ator._
Stub
Calcul
ator._
Skel
RMI
Khóa luận tốt nghiệp 
class CalculatorImpl implements Calculator
{

public int Add(int a,int b) throws RemoteException {
return a+b;
}
}
o Đưa đối tượng Calculator vào trong chương trình phục vụ:
// CalculatorServer.java
import java.rmi.server.*;
import java.rmi.*;
class CalculatorServer {
public static void main(String args[]) {
try {
CalculatorImpl c=new CalculatorImpl();
UnicastRemoteObject.exportObject(c);
System.out.println ("Da Export doi tuong Calculator");
Naming.bind("rmi://localhost/CalcProg",c);
System.out.println ("Da dang ki Calculator voi RMI");
}
catch(Exception e){}
}
}
Giải thích:
Ta đã mô tả xong đối tượng Calculator, nhưng tự đối tượng này chưa thể
giao tiếp với bên ngoài được. Ta cần đưa nó vào trong chương trình
CalculatorServer để có thể phục vụ lời gọi từ xa.
UnicastRemoteObject.exportObject(c);
Lệnh này để cho máy ảo Java nhận diện được đối tượng c là đối tượng có khả năng
giao tiếp từ xa.
Naming.bind("rmi://localhost/CalcProg",c);
Trang 19
Khóa luận tốt nghiệp 

Mục đích: đặt cho đối tượng c một tên gợi nhớ và đăng kí tên này với bộ quản lý
RMI. Các chương trình ở máy khách sẽ dựa vào tên này để tham chiếu đến đối
tượng tương ứng.
Cú pháp của phương thức bind(rmi://hostname:port/ObjectName,Object)
- rmi: là giao thức dùng để đăng kí
- hostname:port: địa chỉ IP hoặc tên máy và số hiệu cổng của máy nơi
mà bộ đăng kí RMI đang chạy.
- ObjectName: tên gợi nhớ đặt cho đối tượng (Object) cần đăng kí
Bộ đăng kí rmiregisty: ta cần chạy bộ đăng kí này trước khi chạy
chương trình CalculatorServer. Khi thực thi, bộ rmiregistry sẽ chờ để đón nhận
các kết nối của phương thức Naming.bind() gửi đến. Mặc định, rmiregistry sẽ các
kết nối gửi đến cổng 1099. Ta có thể thay đổi số hiệu cổng này.
Ví dụ: ta chỉ định cổng 1090 bằng lệnh:
rmiregistry.exe 1090
 Chương trình yêu cầu trên Client:
import java.rmi.*;
class CalculatorClient {
public static void main(String args[]) {
try {
Calculator c =(Calculator)Naming.lookup
("rmi://localhost/CalcProg");
System.out.print(“Ket qua: ”+c.Add(1,2));
}
catch(Exception e){System.out.print(e);}
}
}
Các bước chạy chương trình:
- Dịch và tạo _stub cho đối tượng phục vụ:
Trang 20
Khóa luận tốt nghiệp 

Lệnh rmic CalculatorImpl: Tạo ra lớp trung gian CalculatorImpl_Stub.class. Trong
J2SDK không dùng đến CalculatorImpl_Skel.class nữa.
- Chạy trình rmiregistry:
- Chạy chương trình CalculatorServer:
- Copy file Calculator.class và CalculatorImpl_Stub.class vào thư mục CalcClient.
Thư mục này được xem như là một máy Client.
- Chạy chương trình CalculatorClient:
Nhận xét:
Ở ứng dụng RMI đơn giản trên, ta thực hiện trên một máy, tất cả mã lệnh đều tập
trung trên một máy cục bộ, điều này trái với tư tưởng của lập trình phân tán. Thực
tế, Client chỉ cần các lớp CalculatorClient.class, CalculatorImpl_Stub.class,
Calculator.class.
Trang 21
Khóa luận tốt nghiệp 
1.4. MỘT SỐ KHÁI NIỆM TRONG RMI
2.1.3. Registry
Bộ đăng ký Registry dùng để tiếp nhận đăng ký tên của đối tượng giao tiếp
từ xa. Trước khi máy khách muốn sử dụng được các phương thức và gọi được các
đối tượng từ xa, nó phải liên lạc với rmiregistry để lấy về tham chiếu đến đối tượng
trên máy chủ. Dịch vụ đăng ký và truy tìm đối tượng được Java quản lý bằng các
hàm giao tiếp API JNDI (Java Naming Directory Interface). Các hàm JNDI ở máy
khách (Naming.lookup()) sẽ liên lạc với rmiregistry để nhận về tham chiếu đến đối
tượng trong khi đó các hàm JNDI ở máy chủ (Naming.bind()) có nhiệm vụ đăng ký
tên đối tượng với rmiregistry.
Lưu ý:
Hàm Naming.bind() chỉ đăng ký tên đối tượng với rmiregistry đúng một
lần. Vì vậy nếu tên đăng ký đã tồn tại khi thực hiện hàm này sẽ nhận được thông
báo lỗi AlreadyBoundException. Để khắc phục, ta cần tắt chương trình rmiregistry
và chạy lại. Tuy nhiên, ta có thể tránh điều đó bằng cách sử dụng hàm
Naming.rebind() thay cho Naming.bind(). Hàm Naming.rebind() có nhiệm vụ yêu

cầu đăng ký mới tên đối tượng với rmiregistry nếu tên này chưa có và đăng ký lại
nếu tên đối tượng đã được đăng ký.
Cơ chế làm việc của trình khách và trình chủ trên máy ảo Java khi đăng ký
và truy xuất rmiregistry:
Hình 2.4-7: Cơ chế làm việc của trình khách và trình chủ trên máy ảo Java
Trang 22
Khóa luận tốt nghiệp 
Đối tượng trên máy ảo Java B dùng hàm Naming.bind() hoặc hàm
Naming.rebind() để đăng ký đối với tượng với chương trình rmiregistry đang chạy
trên máy ảo Java A
Chương trình khách chạy trên máy ảo Java C dùng hàm Naming.lookup() để
yêu cầu bộ quản lý rmiregistry trên máy ảo A trả về tham chiếu đến đối tượng
Bộ quản lý trên máy ảo A trả về tham chiếu đến đối tượng đang tồn tại trên máy
ảo B.
Chương trình khách chạy trên máy ảo C sử dụng tham chiếu do hàm
Naming.lookup() trả về để truy và gọi phương thức của đối tượng đang chạy trên
máy ảo B từ xa.
Ba máy ảo này có thể xem là ba máy tính khác nhau nhưng do chạy trên
cùng một máy nên địa chỉ giống nhau là localhost
Thực tế mô hình trên muốn hoạt động trên mạng thật thì chỉ có thể tách ra
làm hai chứ không thể tách ra ba, vì Java không cho phép rmiregistry chạy trên máy
khác nơi đối tượng rmi đang hoạt động.
Ví dụ:
Hình 2.4-8: Rmiregistry trong mô hình phân tán thực tế
Lúc này hàm đăng ký với rmiregistry được gọi như sau:
Naming.bind(“rmi://172.16.11.12/ CalcProg”,c);
Và hàm truy tìm đối tượng từ máy khách sẽ được gọi như sau:
Calculator c = (Calculator) Naming.lookup(“rmi://172.16.11.12/CalcProg”);
Trang 23
Khóa luận tốt nghiệp 

2.1.4. Biến Classpath
CLASSPATH là một biến môi trường(environment variable) được sử dụng
bởi Java compiler và JVM để tìm kiếm các lớp cần thiết cho quá trình biên dịch
(compile) và thông dịch(interpret). Khi chạy chương trình, Java dựa vào biến môi
trường CLASSPATH để truy tìm các tập tin .class. Nếu CLASSPATH chỉ sai
đường dẫn, chương trình sẽ thông báo lỗi: java.lang.ClassNotFoundException:
ClassName
Trong ví dụ ứng dụng RMI đơn giản trên, ta có các lớp sau:
Tên lớp Mục đích Dùng trên
Calculator.class
Đặc tả các phương thức giao tiếp của
đối tượng
Server & Client
CalculatorImpl.class Cài đặt chi tiết đối tượng Server
CalculatorServer.class
Tạo ra đối tượng và đăng ký đối tượng
với rmiregistry
Server
CalculatorImpl_Stub.class Lớp giao tiếp trung gian Server & Client
CalculatorClient.class
Gọi các phương thức của đối tượng
trên Server
Client
Khi CalculatorServer yêu cầu rmiregistry đăng ký tên đối tượng,
rmiregistry sẽ đi truy tìm lớp trung gian CalculatorImpl_Stub.class. Trên máy ảo
rmiregistry đang chạy nếu CLASSPATH không trỏ đến đường dẫn
E:\Luanvan\EXAM\First\ (CalculatorImpl_Stub.class nằm ở đường dẫn này) thì
nhận được thông báo lỗi trả về trên máy ảo nơi CalculatorServer yêu cầu đăng ký
đối tượng:
java.lang.ClassNotFoundException: CalculatorImpl_Stub

Để thay đổi giá trị cho CLASSPATH ta dùng lệnh: Set Classpath
VD: set classpath=E:\Doc
Trang 24
Khóa luận tốt nghiệp 
Giá trị mặc định của Classpath là trỏ đến thư mục chứa hiện hành. Lúc đó
Classpath=E:\Doc
Khi thay đổi giá trị cho Classpath ở một máy ảo sẽ không làm ảnh hưởng tới
Classpath của máy ảo khác.
2.1.5. Codebase
Thật sự khi viết chương trình từ phía máy khách, lập trình viên chỉ cần đến
lớp giao tiếp Calculator.class. Lớp trung gian CalculatorImpl_Stub.class không có ý
nghĩa đối với các nhà phát triển ứng dụng. Nó chỉ cần thiết cho cơ chế RMI của
Java.
Chính vì điều này Java cung cấp cho ta cách thức nạp tự động lớp
CalculatorImpl_Stub.class từ xa thông qua tùy chọn Codebase khi đăng ký đối
tượng với rmiregistry trên máy chủ.
Ở máy chủ phải hỗ trợ thêm dịch vụ Web Server chạy trên máy nơi
rmiregistry đang chạy. Sau đó ta chép tập tin CalculatorImpl_Stub.class vào thư
mục myclass của trình chủ web server. Khi sử dụng tùy chọn Codebase thì biến
Classpath trên máy ảo nơi rmiregistry đang chạy không được trỏ đến cùng thư mục
chứa CalculatorImpl_Stub.class. Nếu không rmiregistry sẽ luôn ưu tiên lấy lớp
CalculatorImpl_Stub.class từ đường dẫn Classpath mà bỏ qua tùy chọn Codebase.
Câu lệnh để chạy chương trình trên máy chủ được sửa lại như sau:
java CalculatorServer –Djava.rmi.server.codebase=”http://172.16.11.12/myclass/”
Khi máy khách có yêu cầu rmiregistry trả về tham chiếu của đối tượng, nếu
máy khách chưa có lớp CalculatorImpl_Stub.class, rmiregistry sẽ hướng dẫn máy
khách tự động nạp lớp này từ địa chỉ codebase: http://172.16.11.12/myclass/.
Trang 25

×