Lời mở đầu Sự bùng nổ của mạng Internet cùng với các ứng dụng của nó đã đem lại cho xã hội một cuộc sống tiện nghi. Mạng Internet đã giúp cho con người bước vào một kỷ nguyên công nghệ thông tin và tri thức. Để có được thành tựu đó thì lĩnh vực phân tán trong hệ tin học cũng đóng một vai trò hết sức quan trọng. Mục đích của lập trình mạng phân tán là tận dụng các khả năng tính toán và khai thác dữ liệu của các hệ thống máy tính ở xa để thực hiện những tính toán nhanh hơn trên cơ sở sử dụng nhiều bộ xử lý, nhiều bộ nhớ đồng thời hoặc nhiều dữ liệu quý giá được phân tán khắp nơi. Trên nền hệ thống mạng máy tính được kết nối như hiện nay, việc xử lý phân tán sẽ giải quyết được những bài toán lớn hơn, phức tạp hơn của thực tế. Trong phạm vi của tiểu luận này nhóm chúng em chỉ đề cập đến hai phần: Phần 1: Lý thuyết về Lập trình mạng phân tán và RMI Phần 2: Bài toán: Người sản xuất Người tiêu thụ. Mặc dầu nhóm chúng em đã rất cố gắng tìm tài liệu để tham khảo trong quá trình làm đề tài nhưng với kiến thức và kinh nghiệm còn hạn chế sẽ không tránh khỏi những sai sót, kính mong thầy giáo và các bạn góp ý thêm.
Trang 1BỘ GIÁO DỤC VÀ ĐÀO TẠO
ĐẠI HỌC ĐÀ NẴNG - -
Báo cáo Tiểu luận:
Phạm Khánh Thiện
Trang 2Đà Nẵng, 03-2010
Lời mở đầu
Sự bùng nổ của mạng Internet cùng với các ứng dụng của nó đã đemlại cho xã hội một cuộc sống tiện nghi Mạng Internet đã giúp cho conngười bước vào một kỷ nguyên công nghệ thông tin và tri thức Để cóđược thành tựu đó thì lĩnh vực phân tán trong hệ tin học cũng đóng mộtvai trò hết sức quan trọng
Mục đích của lập trình mạng phân tán là tận dụng các khả năng tínhtoán và khai thác dữ liệu của các hệ thống máy tính ở xa để thực hiệnnhững tính toán nhanh hơn trên cơ sở sử dụng nhiều bộ xử lý, nhiều bộnhớ đồng thời hoặc nhiều dữ liệu quý giá được phân tán khắp nơi Trênnền hệ thống mạng máy tính được kết nối như hiện nay, việc xử lý phântán sẽ giải quyết được những bài toán lớn hơn, phức tạp hơn của thực tế Trong phạm vi của tiểu luận này nhóm chúng em chỉ đề cập đến haiphần:
Phần 1: Lý thuyết về Lập trình mạng phân tán và RMI
Phần 2: Bài toán: Người sản xuất - Người tiêu thụ.
Mặc dầu nhóm chúng em đã rất cố gắng tìm tài liệu để tham khảotrong quá trình làm đề tài nhưng với kiến thức và kinh nghiệm còn hạnchế sẽ không tránh khỏi những sai sót, kính mong thầy giáo và các bạngóp ý thêm
Nhóm thực hiện
Huỳnh Tấn Dựng – Phạm Khánh Thiện
Trang 3PHẦN I
CƠ SỞ LÝ THUYẾT LẬP TRÌNH MẠNG PHÂN TÁN
VÀ RMI
1 Mạng máy tính Phân tán
Hệ thống tính toán phân tán đã tạo được bước ngoặc so với các hệtập trung, và hệ khách chủ (Client/Server) Việc tính toán phân tán về cơbản cũng giống như việc tính toán của hệ khách chủ trên phạm vi rộnglớn Dữ liệu được chứa trên nhiều máy chủ ở tại nhiều vị trí địa lý khácnhau kết nối nhau thông qua mạng diện rộng WAN hình thành các nơilàm việc, các phòng ban, các chi nhánh của một cơ quan
2 Giới thiệu phương thức triệu gọi đối tượng từ xa RMI (Remote Method Invocation)
Lập trình phân tán đối tượng bằng cách triệu gọi phương thức từ
xa RMI là cách hợp tác giữa các đối tượng Java có những mã lệnh càiđặt (bao gồm các phương thức và thuộc tính) nằm trên các máy khácnhau (chính xác là nằm trên các JVM – máy ảo Java khác nhau) và cóthể triệu gọi lẫn nhau để trao đổi tin
Trong mô hình Client / Server truyền thống, các yêu cầu đượcdịch sang một format (dạng) trung gian (dạng từng cặp tên gọi / giá trịhoặc các dữ liệu trong XML) Máy chủ Server phân tích format yêu cầu,
xử lý để có được kết quả và gửi trả lời cho máy khách Client Máy kháchphân tích format trả lời và hiển thị thông tin cho người sử dụng
Trang 42.1 Triệu gọi phương thức từ xa
2.2 Kiến trúc RMI Java
Về cơ bản, RMI được xây dựng dựa trên kiến trúc ba tầng như
hình 2
Đầu tiên là tầng bao gồm hai lớp trung gian Stub và Skeleton,
chúng được hệ thống tạo ra theo yêu cầu Các lớp này chặn các lờigọi phương thức của chương trình khách (Client) tới các biến thamchiếu và gửi tới dịch vụ triệu gọi từ xa Lớp Skeleton liên lạc vớiStub thông qua liên kết RMI Nó đọc các tham số của lời triệu gọi
từ xa từ một liên kết nào đó, thực hiện lời gọi tới đối tượng thựcthi dịch vụ từ xa và sau đó gửi các giá trị trả lại cho Stub Trong
Stub & Skeleton Tham chiếu từ xa
Stub & Skeleton Tham chiếu từ xa Tầng giao vận
Chương trình khách
Chương trình chủ
Hệ thống
RMI
Hình 2: Kiến trúc ba tầng của RMI
Gửi yêu cầu về dữ liệu
Trả lại thông tin yêu cầu
Hình 1: Sự trao đổi giữa đối tượng khách và phục vụ (chủ)
Trang 5Java 2 SDK, các giao diện mới được xây dựng đã làm cho Skeletonlỗi thời RMI sử dụng phép ánh xạ để thực hiện việc kết nối tới cácđối tượng dịch vụ từ xa thay cho Skeleton
các tham chiếu tới các đối tượng dịch vụ từ xa Ở JDK1.1, tầngnày thực hiện két nối theo cơ chế điểm – tới - điểm Đến Java 2SDK, tầng này được cải tiến để nâng cao việc hỗ trợ để kích hoạtcác đối tượng dịch vu từ xa đang chờ thực hiện thông qua ROA,
đó là cách kết nối Client/Server
mạng Ngay cả khi hai chương trình chạy trên hai JVM trong cùngmột máy, chúng cũng thực hiện kết nối thông qua TCP/IP củachính máy đó Tầng giao vận RMI được thiết kế để thiết lập mộtkết nối giữa máy Client với máy Server
Giả sử, ta có đối tượng C1 được cài đặt chạy trên máy phục vụ C.RMI của Java giúp ta tạo ra hai lớp trung gian C1_Skel (không cầnthiết đối với Java 2 SDK) và C1_Stub Lớp C1_Stub sẽ được nạp vềmáy khách B Khi đối tượng B1 trên máy B triệu gọi C1, máy ảo Java
sẽ chuyển lời gọi đến lớp C1_Stub C1_Stub sẽ chịu trách nhiệmđóng gói các tham số và chuyển chúng qua mạng đến cho máy C Tạimáy C, lớp C1_Skel (C1_Stub được nạp về và thay thế ở Java 2SDK) sẽ nhận tham số để chuyển vào không gian địa chỉ tương thích vớiđối tượng C1 sau đó gọi phương thức tương ứng để thực hiện Kết quảnếu có do phương thức của đối tượng C1 trả về sẽ được lớp C1_Skel(C1_Stub thay thế ở Java 2 SDK) đóng gói trả ngược choC1_Stub C1_Stub chuyển giao kết quả cuối cùng cho B1 Theo cơchế này, có thể hình dung như B1 đang trao đổi trực tiếp với đối tượng C1ngay trên cùng một máy Ngoài ra, với sự trợ giúp của lớp trung gianC1_Stub, khi kết nối mạng gặp sự cố, lớp trung gian Stub sẽ luôn biếtcách thông báo lỗi đến đối tượng B1
Thực tế có một câu hỏi là: Làm thế nào để B1 tham chiếu được đếnC1 khi không có lớp C1 nào được cài đặt ở máy B? C1_Stub trên máy Bchỉ làm lớp trung gian chuyển đổi tham số và thực hiện các giao thức mạng,
nó không phải là hình ảnh của đối tượng C1 Để làm được điều đó, lớp của
Trang 6đối tượng C1 cần cung cấp một giao diện tương ứng, được gọi là giao diện
từ xa với các phương thức cho phép đối tượng B1 gọi nó trên máy B
Stub thường trực trên máy khách, không ở trên máy chủ Nó có vai trò
đóng gói các thông tin bao gồm:
Định danh đối tượng từ xa cần sử dụng
Mô tả về phương thức cần triệu gọi
Mã hoá các tham số và truyền cho Skel
Stub sẽ chuyển những thông tin trên cho máy chủ Ở phía máy chủ, đốitượng Skel nhận thực hiện những công việc sau để gọi phương thức từxa:
Giải mã các tham số
Xác định đối tượng để thực hiện lời gọi hàm tương ứng
Thực hiện lời gọi phương thức theo yêu cầu
Tập hợp kết quả để trả lời hoặc thông báo các lỗi ngoại lệ
Gửi trả lời gói các dữ liệu kết quả cho Stub ở trên máy khách
Hình trên mô tả quá trình tổ chức gói các tham số, các dữ liệu trả lời
và sự trao đổi giữa các đối tượng trung gian trong kỹ thuật triệu gọi từxa
c: Client
Gọi hàm cục
bộ ở Stub
Trả lại giá trị
hoặc ngoại lệ
Gọi hàm cục
bộ ở Server
Chuyển các gói các tham số
Gửi trả lại kết quả hoặc ngoại lệ Hình 3: Sự trao đổi giữa đối tượng khách và phục vụ thông qua đối
tượng trung gian
Trang 73 Thiết lập môi trường triệu gọi từ xa
3.1 Trên máy phục vụ (Server)
(a) Thiết lập giao diện từ xa
Trong Java, đối tượng từ xa là thể hiện của một lớp cài đặt giao diện Remote Tất cả các phương thức của các giao diện từ xa phải được
khai báo public để các máy JVM khác có thể gọi được Các giao diện từ
xa phải đảm bảo những tính chất sau:
Giao diện từ xa phải khai báo public.
Giao diện từ xa kế thừa java.rmi.Remote
Mọi phương thức phải khai báo với mệnh đề throws để kiểmsoát các ngoại lệ java.rmi.RemoteException
Kiểu dữ liệu của các đối tượng từ xa được truyền đi và giá trịnhận về phải được khai báo như là kiểu giao diện Remote,không phải là lớp
(b) Xây dựng các lớp cài đặt các giao diện từ xa
Ở phía máy chủ, chúng ta phải xây dựng lớp cài đặt các phươngthức được khai báo trong giao diện từ xa
Nói chung, các lớp các cài đặt đối tượng từ xa cần phải:
Khai báo rằng nó cài đặt ít nhất một giao diện từ xa
Định nghĩa đối tượng từ xa
Cài đặt các phương thức để có thể triệu gọi được từ xa
(c) Cài đặt các phương thức từ xa
Lớp cài đặt các đối tượng từ xa phải cài đặt tất cả các phương thức
đã được khai báo trong giao diện từ xa
Các tham số, các giá trị trả về của phương thức từ xa có thể là kiểu dữliệu bất kỳ của Java, kể cả các đối tượng
(d) Xác định các đối tượng dịch vụ
Để truy cập được đối tượng từ xa trên máy phục vụ, khách hàngcần có được đối tượng đại diện tại nơi đó Khách yêu cầu đối tượng đónhư thế nào? Phương thức chung là gọi phương thức từ xa của một đốitượng phục vụ và tạo ra một đối tượng đại diện để nhận kết quả trả lời
(e) Bộ đăng ký RMI registry
Trang 8Chương trình dịch vụ của chúng ta hoàn toàn chưa sẵn sàng thựchiện Vấn đề chính của chúng ta là cài đặt đối tượng của ProductImpltrên một máy và ở một máy khác (chương trình khác) muốn gọi phươngthức getDescription() để biết được thông tin mô tả và giá bán của các sảnphẩm có trên chương trình phục vụ
3.2 Trên máy khách (Client)
Viết chương trình ở trên máy khách (chương trình khách) để yêucầu chương trình phục vụ cung cấp những thông tin về các sản phẩm từcác đối tượng đã đăng ký
Với Java, tất cả các thao tác kết nối và sao chép các tệp tin từ mộtmáy tính về máy khách đều phải thông qua lớp bảo vệ gọi là RMISecurity Manager
Trang 9PHẦN II BÀI TOÁN: NGƯỜI SẢN XUẤT – NGƯỜI TIÊU THỤ
1 Hướng Giải quyết bài toán
Ứng dụng lý thuyết lập trình mạng và RMI đã đề cập ở trên để xâydựng chương trình nhằm giải quyết bài toán
Trong bài toán này ta xét hai trạm là trạm sản xuất, ký hiệu là PS
Tương tự, trên trạm CS ta đặt một công tơ NP’ Giá trị của công tơ
sự kiện NP’ được tăng lên một đơn vị khi trạm CS nhận được thông điệp
từ trạm PS thông báo đã có một sản phẩm vừa được sản xuất
Để giải quyết bài toán đã nêu ra, ta sử dụng một số hàm nguyênthủy sau:
tang(E) : tăng giá trị công tơ lên một đơn vị
cho(E,i) : treo cho đến khi giá trị của công tơ sự kiện E lớn hơn
hoặc bằng i
send(S): gửi thông điệp đến trạm S.
receive(S): nhận thông điệp từ trạm S.
Theo giả thiết của bài toán, trạm sản xuất PS chỉ có thể sản xuấtsản phẩm nếu:
Trang 10NC: số lượng sản phẩm đã tiêu thụ bởi trạm CS
NC’: công tơ sự kiện tiêu thụ đặt trên trạm sản xuất PS
NP’: công tơ sự kiện sản xuất đặt trên trạm tiêu thụ CS
Ta gọi Pi là sản xuất thứ i và Ci là tiêu thụ thứ i
Ta thấy rằng:
Pi → Pi+1 → Pi+N : tuân theo trật tự cục bộ của trạm sản xuất PS
Pi → Ci : tuân theo mối quan hệ nhân quả
Vấn đề của bài toán đến đây là cần phải chứng minh: Ci →
Pi+N
Trạm sản xuất PS chỉ sản xuất thêm sản phẩm nếu hiện tại sốlượng còn lại (tức là lượng sản phẩm đã sản xuất nhưng chưa tiêu thụđược) nhỏ hơn N, tức là:
(send(CS))để báo cho biết có một sản phẩm vừa được sản xuất.
Tại trạm CS, khi nhận được thông điệp từ trạm PS thông báo có
sản phẩm vừa được sản xuất (receive(PS)), trạm CS sẽ tăng giá trị công
tơ sự kiện NP’ thêm một đơn vị (tang(NP’))
Trạm tiêu thụ CS chỉ có thể tiêu thụ sản phẩm nếu vẫn còn sảnphẩm, nghĩa là:
Trang 11Sau khi nhận được thông báo từ trạm CS (receive(CS)), trạm sản
xuất PS sẽ tăng giá trị của công tơ sự kiện NC’ thêm một đơn vị
tieu_thu()
send(PS)
NC = NC + 1
Kết thúc vòng lặp
Trang 122 Chương trình và kết quả demo
// Server1.java (chua cac lenh sau)
// Server1 dong vai tro la Tram San Xuat
// khai bao interface cho Server1
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Server1 extends java.rmi.Remote {
public abstract int sanxuatso()
throws java.rmi.RemoteException;
// Set thong tin den tram San xuat
public abstract void setmessSX(java.lang.String message)
// Server2Impl.java (chua cac lenh sau)
// Server1 dong vai tro la Tram San Xuat
// Thuc hien Implement cho Server1
Trang 13static int congtosukienSX=0;
static Message mesinSX;
// +++++
public synchronized int sanxuatso() {
// thu ham random
// voi bien congtosukien
public synchronized void setcongtosukienSX(int ctsk) {
mesinSX.setcongtosukien(ctsk);
Trang 14}
public synchronized int getcongtosukienSX() {
return mesinSX.getcongtosukien();
}
// voi bien num
public synchronized void setnumSX(int number) {
Trang 15String text = tramtt.getmessTT();
// lay gia tri congtosukien o tram TT de so sanh
int ctskTT= tramtt.getcongtosukienTT(); // get ctsk otram tieuthu
System.out.println(" CongToSuKien o Tram TT la:
mesinSX.setcongtosukien(congtosukienSX); //set laigia tri cho ctsk o tr SX
tramtt.setcongtosukienTT(congtosukienSX); // set laicho bien ctsk o tr TT
mesinSX.setmess("tieuthu"); //de yeu cau tram tieuthu tieu thu
int tong= tramtt.gettongTT();
System.out.println("^^^ Gia tri tong o tram TT tra vela: "+tong);
}else tramtt.setmessTT("sanxuat");
Trang 16if (mesinSX.getmess().compareToIgnoreCase("quit")==0)thr.stop();
public static void main(java.lang.String args[]) {
java.lang.System.out.println("Creating Registry Server1 ");
try {
// ***** Khoi tao va Start Server o tram SX ****
//Server1 tao ra doi tuong server1impl va dang ky no de san sàngcho viec goi tu xa
java.rmi.registry.LocateRegistry.createRegistry(1999);
Server1Impl server1impl = new Server1Impl();
java.rmi.Naming.rebind("rmi://" + args[0] + ":1999/Server1",server1impl);
java.lang.System.out.println("Server1 Ready");
System.out.println("====**************************====");
Trang 17// Server2.java (chua cac lenh sau)
// Server2 dong vai tro la Tram Tieu Thu
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Server2 extends java.rmi.Remote {
public abstract void tieuthuso()
throws java.rmi.RemoteException;
// Set thong tin den tram Tieu Thu
public abstract void setmessTT(java.lang.String message)
Trang 18// Server2Impl.java (chua cac lenh sau)
// Server2 dong vai tro la Tram Tieu Thu
static Server1 tramsx ;
static int congtosukienTT=0;
// voi bien congtosukien
public synchronized void setcongtosukienTT(int ctsk) {
// voi bien num
public synchronized void setnumTT(int number) {
Trang 19int tam = mesinTT.gettong();
int num = tramsx.getnumSX();
tam= tam + num;
Trang 20//******* Cai dat thuat toan cho tram SX ******
Trang 21
mesinTT.setcongtosukien(congtosukienTT);//set lai value ctsk oTT
tramsx.setcongtosukienSX(congtosukienTT); mesinTT.setmess("sanxuat");
}
else tramsx.setmessSX("tieuthu");
}
if (mesinTT.getmess().compareToIgnoreCase("stop")==0)mesinTT.settong(0);
public static void main(java.lang.String args[]) {
java.lang.System.out.println("Creating Registry Server2 ");
try {
// ***** Khoi tao va Start Server o tram SX ****
//Server2 tao ra doi tuong server2impl và dang ký nó de san sàngcho viec goi tu xa
java.rmi.registry.LocateRegistry.createRegistry(1099);
Server2Impl server2impl = new Server2Impl();
Trang 22java.rmi.Naming.rebind("rmi://" + args[0] + ":1099/Server2",server2impl);
java.lang.System.out.println("Server2 Ready");
System.out.println("====**************************====");
public class Message {
int idmess; //id cua thong diep (muc dich de de quan ly)
private java.lang.String mess;
private int tong;
private boolean kiemtra;
private int num;
private int congtosukien;
Trang 23public Message() {
mess="ok";
tong = 0;
}
// voi bien congtosukien
public void setcongtosukien(int ctsk) {
System.out.println("vua set gia tri cua cong to su kien la: "+ctsk); this.congtosukien=ctsk;
}
public int getcongtosukien() {
System.out.println("vua get gia tri cua cong to su kien la:
"+congtosukien);
return this.congtosukien;
}
// voi bien num
public void setnum(int number) {
// voi bien mess
public void setmess(java.lang.String message) {
// voi bien tong
public int gettong() {
return this.tong;
}
public void settong(int total) {