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

tiểu luận lập trình mạng phân tán đảm bảo gắn bó dữ liệu khi cập nhật trong các cơ sở dữ liệu tập trung tại các ngân hàng

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 (269 KB, 23 trang )

Tiểu luận: Lập trình mạng
ĐẠI HỌC ĐÀ NẴNG
======
TIỂU LUẬN
LẬP TRÌNH MẠNG PHÂN TÁN
Đề tài:
ĐẢM BẢO GẮN BÓ DỮ LIỆU KHI CẬP
NHẬT TRONG CÁC CƠ SỞ DỮ LIỆU TẬP
TRUNG TẠI CÁC NGÂN HÀNG
GVHD: PGS.TS. Lê Văn Sơn
Học viên: Đỗ Trường Linh
Chuyên ngành: Khoa học máy tính_ Khóa 24
Học viên: Đỗ Trường Linh Trang 1
Tiểu luận: Lập trình mạng
MỞ ĐẦU
Hệ tin học phân tán là một trong những lĩnh vực tri thức vừa mang tính chất cơ sở
vừa mang tính chất tiên tiến của chuyên ngành công nghệ thông tin mà việc nắm bắt
và vận dụng tốt các nguyên lý của nó sẽ mang lại cho các hê thống thực tiễn những
hứa hẹn rất lớn về hiệu năng khai thác thiết bị trong các ứng dụng tin học. Nó còn là
hệ thống tin học hiện đại, đa dạng, phức tạp và đang trên đà phát triển, được nhiều
trường đại học, nhiều viện nghiên cứu, nhiều chuyên gia công nghệ thông tin, quan
tâm nghiên cứu với nhiều công trình khoa học có giá trị về mặt nguyên lý, phương
pháp cũng như ứng dụng trong thực tế.
Việc lập trình giải quyết một bài toán hay giải quyết một yêu cầu xử lý phân tán
các đối tượng vẫn là một vấn đề nóng bỏng của công nghệ ngày nay. Trong khuôn khổ
môn học Lập trình mạng phân tán, tiểu luận trình bày về vấn đề lập trình phân tán giải
quyết một bài toán cụ thể, đó là:
Viết chương trình đảm bảo gắn bó dữ liệu khi cập nhật trong các CSDL tập
trung tại các ngân hàng.
Bài làm này tìm hiểu và vận dụng JAVA để lập trình giải quyết bài toán theo hai
cách là sử dụng đa tuyến và giả lập server. Trong đó giả lập server theo hướng một


server tập trung để trao đổi dữ liệu với nhau.
Tiểu luận gồm hai chương:
Chương 1 . Tìm hiểu về lập trình phân tán trong môi trường Java.
Chương 2. Giao tiếp theo mô hình Client/ Server và khái niệm Socket
Chương 3. Cài đặt bài toán đã nêu bằng ngôn ngữ Java để minh họa.
Học viên: Đỗ Trường Linh Trang 2
Tiểu luận: Lập trình mạng
CHƯƠNG 1
TÌM HIỂU VỀ LẬP TRÌNH PHÂN TÁN TRONG JAVA
1.1. RMI và lập trình phân tán đối tượng
Thông thường các chương trình của chúng ta được viết dưới dạng thủ tục hay hàm
gọi. Mã lệnh của hàm hay thủ tục được nạp thẳng vào ký ức và thực thi ngay trên máy
cục bộ. Đối với các hàm (hoặc đối tượng) thư viện như System.out.println() chẳng hạn
bạn thường không cần phải quan tâm đến cách thức mà hàm thư viện được cài đặt.
Điều mà hầu hết các lập trình viên quan tâm là đối số truyền cho hàm và kết quả trả
về. Vậy thì có cách nào tập nội dung của hàm hay đối tượng ở một máy nào đó và gọi
chúng từ một máy khác hay không? Đây chính là nội dung của lập trình phân tán mã
lệnh. RMI (Remote Method Invoke) – mang ý nghĩa triệu gọi phương thức từ xa – là
cách thức giao tiếp giữa các đối tượng Java có mã lệnh cài đặt (bao gồm phương thức
và thuộc tính) nằm trên các máy khác nhau có thể triệu gọi lẫn nhau.
Hình 1-1: Mô hình triệu gọi các đối tượng từ xa
Hình 1-1 cho thấy mô hình triệu gọi đối tượng phân tán. Trên máy A các đối
tượng A1, A2 gọi phương thức của nhau được gọi là triệu gọi phương thức cục bộ
(local method Invoke) đây là cách mà lập trình hướng đối tượng truyền thống vẫn sử
dụng. Tương tự, tương tác giữa C1, C2, C3 là tương tác cục bộ.
Tuy nhiên, đối tượng Java có thể gọi phương thức của đối tượng nằm trên một máy
khác dựa vào giao thức triệu gọi từ xa RMI (như A1 gọi C1, A2 gọi B1, C3 gọi B1).
Học viên: Đỗ Trường Linh Trang 3
Computer A
A2

A1
Computer C
C1
C2
Computer B
B1
C3
Tiểu luận: Lập trình mạng
1.2. Gọi phương thức từ xa và các vấn đề phát sinh
Việc gọi phương thức của đối tượng từ xa thoạt nhìn có vẻ đơn giản nhưng thực
tế lại phức tạp hơn triệu gọi phương thức cục bộ. Các đối tượng trên hai máy khác
nhau hoạt động trên hai tiến trình (hay không gian địa chỉ) khác nhau cho nên việc
tham chiếu biến, địa chỉ đối tượng là hoàn toàn khác nhau. Ví dụ, khi bạn truyền con
trỏ cho một phương thức ở xa, trên máy bạn con trỏ này tồn tại nhưng trên máy khác
(nơi có đối tượng thực thi phương thức) sẽ không có bất kỳ vùng nhớ nào được cấp
phát dành cho con trỏ. Lời gọi các phương thức cục bộ thường luôn trả về kết quả
trong khi lời gọi các phương thức từ xa phải thông qua kết nối mạng và luôn có thể bị
ngắt ngang do mạng gặp sự cố.
Đối với lời gọi hàm trên máy cục bộ, các tham số truyền cho hàm thường được đặt vào
ngăn xếp (stack) trong khi tham số truyền cho phương thức của các đối tượng ở xa
phải đươc đóng gói và chuyển qua mạng để đến đươc với phương thức thực sự.
1.3. Vai trò các lớp trung gian (Stub và Skeletion)
Để giải quyết các vấn đề trên, đối tượng Java trên hai máy khác nhau không gọi
nhau trực tiếp mà thông qua lớp trung gian. Lớp trung gian này tồn tại ở cả hai phía
máy khách (Client - nơi gọi phương thức của đối tượng ở xa) và máy chủ (Server – nơi
đối tượng thực sự được cài đặt để thực thi mã lệnh của phương thức). Phía máy khách
lớp trung gian này được gọi là Stub (lớp móc), phía máy chủ lớp trung gian này được
gọi là Skeletion (lớp nối).
Hình 1 – 2: Gọi phương thức của các đối tượng thông qua lớp trung gian
Ví dụ, đối tượng C1 được cài đặt chạy trên máy C. Trình Java sẽ tạo ra hai lớp

trung gian C1_Skel và C1_Stub. Lớp C1_Stub sẽ được đem về máy Computer A. Khi
Học viên: Đỗ Trường Linh Trang 4
Computer A
A2
A1
Computer C
Computer B
B1
C1
C1_stub
B1_stub
C1_skel
B1_skel
Tiểu luận: Lập trình mạng
A1 trên máy computer 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 Computer C. Trên
máy Computer C lớp nối C1_Skel sẽ nhận tham số chuyển vào vùng 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. 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 đóng gói trả ngược về
cho C1_Stub. C1_Stub chuyển giao kết quả cuối cùng lại cho A1. Bằng cơ chế này,
A1 luôn nghĩ rằng nó đang hoạt động trực tiếp với đối tượng C1 ngay trên máy cục bộ.
Hơn nữa, nhờ sự giúp đỡ của lớp trung gian C1_Stub, khi kết nối mạng gặp sự cố lớp
trung gian stub sẽ luôn biết cách thông báo lỗi đến đối tượng A1.
Thực tế làm thế nào A1 tham chiếu đươc đến C1, một khi không có lớp C1 nào
được cài đặt ở máy A? C1_Stub trên máy A chỉ làm lớp nền 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 này, đối tượng C1 cần cung cấp một giao tiếp interface tương ứng
với các phương thức cho phép đối tượng A1 gọi nó trên máy A.
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ủ, đối tượ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.
1.4. Cài đặt ứng dụng phân tán RMI
Sau đây là một ví dụ về cách làm việc của các đối tượng RMI. Chương trình là
một hệ đối tượng phân tán (hình 1 – 3). Đối tượng Calculator chạy trên máy tính
Computer 2 sẽ được gọi bởi đối tượng CalculatorClient chạy trên máy tính Computer
1.
Hình 1-3: Triệu gọi đối tượng RMI giữa trình khách (Client) và
đối tượng chủ (Server) ở xa
Học viên: Đỗ Trường Linh Trang 5
Computer 1
CalculatorClient
Calculator_Stub
Computer 2
Calculator
Calculator_Skel
RMI
Tiểu luận: Lập trình mạng
Muốn Calculator có khả năng giao tiếp được với các đối tượng ở xa thì phải báo cho
Java biết Calculator là một đối tượng có khả năng Remote. Tất cả các phương thức
trong giao tiếp Calculator muốn được gọi từ xa đều phải có khả năng ném ra ngoại lệ
RemoteException vì khi triệu gọi từ xa có rất nhiều nguyên nhân làm nó thất bại,

ví dụ, máy chủ, kết nối mạng không sẵn sàng và nhiều vấn đề không bình thường,
ngoại lệ khác gặp phải trên mạng. Mã nguồn đầy đủ của giao tiếp Calculator như sau:
Calculator.java
import java.rmi.*;
public interface Calculator extends Remote {
public int addNumber (int x, int y)throws RemoteException;
}
Lớp giao tiếp Remote thật ra chỉ là một interface rỗng, được dùng để đánh dấu cho
máy ảo Java biết được đặc tính có khả năng “nói chuyện” với các đối tượng ở xa của
Calculator.
CalculatorImpl.java
import java.rmi.*;
public class CalculatorImpl implements Calculator {
public int addNumber (int x, int y)throws RemoteException{
System.out.println(“Client request to calculator”);
Return (x+y);
}
}
Sau khi biên dịch, đối tượng Calculator bao gồm hai lớp: lớp CalculatorImpl.class
chứa cài đặt của đối tượng và lớp Calculator.class chứa đặc tả để giao tiếp với lớp đối
tượng thật sự CalculatorImpl.class.
Dựa vào lớp cài đặt CalculatorImpl.class, trình biên dịch rmic.exe của Java sẽ
cung cấp hai lớp trung gian Stub và Skel bằng lệnh sau:
C:\ javac CalculatorImpl.class
Kết quả thu được hai file CalculatorImpl_Stub.class và CalculatorImpl_Skel.class.
Chương trình CalculatorServer để cài đặt đối tượng Calculator trên một máy:
CalculatorServer.java
import java.rmi.server.*;
//Để sử dụng được lớp UnicastRemoteObject
import java.rmi.*;

public class CalculatorServer {
public static void main(String args[]){
try{
//Tạo đối tượng Calculator thật sự
CalculatorImpl c=new CalculatorImpl();
System.out.println(“Exporting Calculator…”);
//Thông báo sư hiện diện của đối tượng cho máy ảo Java
UnicastRemoteObject.exportObject(c);
//đăng ký đối tượng với bộ quản lý rmi
System.out.println(“Register Calculator!”);
Học viên: Đỗ Trường Linh Trang 6
Tiểu luận: Lập trình mạng
}catch (Exception){
System.out.println(e);
}
}
}
Chương trình Calculator làm việc như sau:
- Đối tượng CalculatorImpl được tạo ra
CalculatorImpl c=new CalculatorImpl();
- Calculator gọi phương thức tĩnh exportObject() của lớp
UnicastRemoteObject để máy ảo Java nhận diện được đối tượng c (Calculator) là đối
tượng có khả năng truy xuất từ xa.
UnicastRemoteObject.exportObject(c);
- Đặt cho đối tượng Calculator một tên gợi nhớ và đăng ký tên này với bộ
quản lý rmi. Phương thức tĩnh bind() của lớp Naming sẽ thực hiện điều này:
Naming.bind(“rmi://localhost/MyCalculator”, c);
Phương thức bind() nhận hai đối số: đối số thứ nhất là chuỗi định vị URL và đối số
thứ hai là bản thân đối tượng cần đăng ký. Chuỗi URL có định dạng như sau:
rmi://hostname:port/Object

rmi là tên giao thức dùng để đăng ký; hostname, port là địa chỉ IP và số hiệu
cổng của máy chủ nơi bộ đăng ký đối tượng rmi đang chạy. Objectname là tên gợi
nhớ bất kỳ đặt cho đối tượng. Các chương trình máy khách sẽ dựa vào tên này để truy
tìm tham chiếu đến đối tượng cần dùng. Để đăng ký, chạy chương trình
rmiregistry.exe trong thư mục \jdk1.3\bin. Mặc định
rmiregistry.exe lắng nghe các kết nối gửi đến cổng 1099.
Chương trình CalculatorClient phía máy khách có khả năng gọi và sử dụng đối
tượng Calculator trên máy chủ như sau:
import java.rmi.*;
public class CalculatorClient{
public static void main(String args[]){
try{
//Tìm đối tượng cần truy xuất theo tên
System.out.println(“Finding object…”);
Calculatorc=(Calculator)Naming.lookup(rmi://localhost/MyCal”);
//Gọi phương thức của đối tượng
System.out.println(“c.addNum(12,1));
}catch (Exception){
System.out.println(e);
}
}
}
Học viên: Đỗ Trường Linh Trang 7
Tiểu luận: Lập trình mạng
Để truy tìm đối tượng ở xa, chương trình máy khách gọi phương thức tĩnh
Naming.lookup(). Phương thức này chỉ yêu cầu đối số là chuỗi định dạng cho
biết địa chỉ máy chủ và tên đăng ký của đối tượng.
Calculatorc=Calculator)Naming.lookup(rmi://localhost/MyCal”);
Địa chỉ máy chủ là localhost và tên của đối tượng là MyCal.
Trên mô hình Client/ Server, máy server sẽ cần đến lớp CalculatorImpl.class,

CalculatorImpl_Skel.class để cài đặt đối tượng; máy client chỉ cần dùng đến lớp
Calculator.class và CalculatorImpl_Stub.class để gọi phương thức của đối tượng.
Hình 1-4 diễn đạt cơ chế gọi hàm từ xa của các đối tượng RMI một cách tổng quát:
1. Đối tượng cài đặt các phương thức và gọi hàm Naming.bind() để đăng ký với
bộ quản lý rmiregistry trên máy chủ.
2. Đối tượng trên máy khách muốn gọi phương thức của đối tượng trên máy chủ
trước hết cần gọi hàm Naming.lookup() để truy tìm tham chiếu đến đối
tượng ở xa theo tên.
3. Bộ đăng ký rmiregistry sẽ trả về tham chiếu đến đối tượng ở xa thông qua lớp
giao tiếp interface mà đối tượng ở xa cung cấp.
4. Dựa vào lớp giao tiếp interface đối tượng ở máy khách sẽ gọi các phương thức
của đối tượng trên máy chủ.
5. Khi một phương thức được gọi, lời goi sẽ được chuyển tiếp đến lớp trung
gian_Stub. Xử lý chuyển tham số của phương thức gọi đến lớp_Skel trên máy
chủ.
6. Lớp trung gian_Skel trên máy chủ sẽ trực tiếp yêu cầu đối tượng thực thi
phương thức và chuyển trả kết quả về cho máy khách. Các bước cài đặt và thiết
kế đối tượng RMI có thể được tóm tắt như sau:
7. Đặc tả lớp giao tiếp của đối tượng (Calculator.java)
8. Dựa vào lớp đặc tả cài đặt chi tiết đối tượng (CalculatorImpl.java)
9. Biên dịch đối tượng (CalculatorImpl.class). Dựa vào đối tượng vừa cài
đặt dùng trình rmi.exe (chương trình này nằm trong thư mục \jdk.3\bin) tạo ra
hai lớp trung gian Calculator_Stub và Calculator_Skel.
10.Viết chương trình (CalculatorServer.class) cài đặt đối tượng trên máy
chủ. Chú ý phải gọi phương thức UnicastRemoteObject.exportObject() để
thông báo cho java nhận dạng được sư tồn tại của đối tượng ở dạng truy xuất
được từ xa bởi các đối tượng khác.
11.Sử dụng lớp giao tiếp (Calculator.class) và CalculatorImpl_Stub từ
máy khách để gọi các phương thức của đối tượng trên máy chủ.
Học viên: Đỗ Trường Linh Trang 8

Tiểu luận: Lập trình mạng

Hình 1-4: Cơ chế RMI gọi phương thức của đối tượng từ xa
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. Chương trình minh họa bao gồm các tập tin sau:
Tên lớp Mục đích Sử dụng trên
Calculator.class
CalculatorImpl.class
CalculatorImpl_Skel.class
CalculatorImpl_Stub.class
CalculatorServer.class
CalculatorClient.class
Lớp đặc tả phương thức giao tiếp
của đối tượng.
Phần cài đặt của bản thân đối
tượng.
Lớp giao tiếp trung gian do trình
biên dịch rmic.exe tạo ra.
Lớp giao tiếp trung gian do trình
biên dịch rmic tạo ra.
Chương trình dùng chạy trên máy
chủ dùng tạo ra đối tượng và đăng
ký đối tượng với rmiregistry.
Chương trình chạy trên máy khách
gọi các phương thức của đối tượng
trên máy chủ.
Máy khách và máy chủ.
Máy chủ
Máy chủ
Máy khách và máy chủ

Máy chủ
Máy khách
Học viên: Đỗ Trường Linh Trang 9
Computer 1



Computer 2


CalculatorClient
Calculator
CalculatorImpl_Stub
CalculatorImpl
rmiregistry
CalculatorImpl_Skel
Tiểu luận: Lập trình mạng
CHƯƠNG 2
GIAO TIẾP THEO MÔ HÌNH CLIENT/SERVER
VÀ KHÁI NIỆM SOCKET
2.1. Giao tiếp theo mô hình khách/ chủ (Client/ Server)
Có rất nhiều dịch vụ hỗ trợ trên Internet như e-mail, nhóm tin (newgroup), file
transfer, đăng nhập từ xa (remote login), truy tìm các trang Web… Những dịch vụ này
đươc tổ chức và kiến trúc theo mô hình khách/ chủ (Client/ Server). Các chương trình
ở máy khách (client) sẽ tạo ra kết nối (connection) với một máy chủ ở xa (server) sau
đó gửi các yêu cầu đến máy chủ, các chương trình dịch vụ trên máy chủ sẽ xử lý các
yêu cầu này và gửi kết quả ngược về cho máy khách. Thông thường một dịch vụ trên
máy chủ phục vụ cho rất nhiều máy khách.
1.5.2. Lập trình mạng thông qua Socket
Trước khi yêu cầu một dịch vụ trên máy chủ thực hiện điều gì đó, máy khách

(client) phải có khả năng kết nối được với máy chủ (server). Quá trình kết nối này
được Java thực hiện thông qua môt cơ chế trừu tượng hóa gọi là Socket (tạm dịch là
“cơ chế ổ cắm”).
Nếu kết nối socket thành công thì máy khách và máy chủ có thể trao đổi sữ liệu với
nhau thực hiện các yêu cầu về dịch vụ trên máy chủ. Việc kết nối theo cơ chế socket
cần biết hai thông tin chủ yếu đó là địa chỉ của máy cần kết nối và số hiệu cổng của
chương trình dịch vụ. Java cung cấp lớp Socket (thường được dùng cho máy khách)
và lớp ServerSocket (thường được đặt trên máy chủ). Hai lớp này được đăt trong
gói thư viện Java.net.
Tuy nhiên, lớp Socket có thể được dùng kết nối chung cho cả máy khách và máy
chủ nhưng ta vẫn thường dùng lớp ServerSocket để thực hiện việc quản lý kết
nối đăt riêng ở máy chủ hơn.
2.2. Lớp Socket
Lớp Socket dùng tạo kết nối từ phía máy khách với máy chủ thường được khởi
động bằng các phương thức sau:
• Public Socket(String host,int port) throws
UnknownHostException, IOException
Tạo ra một socket kết nối máy có tên theo địa chỉ host và số cổng port.
• Public Socket(InetAddress address, int port) throws IOException
Tạo ra một socket kết nối từ địa chỉ là đối tượng InetAddress và số cổng port.
• Public Socket(String host, int port, boolean stream) throws
IOException
Tạo ra một socket kết nối theo địa chỉ host và số cổng port, tham số tream cuối cùng
để quy định kết nối theo TCP (stream=true) hay UDP (stream=false).
Các phương thức khác hỗ trợ cho lớp Socket từ phía máy khách bao gồm:
• InputStream getInputStream()throws IOException
Lấy về luồng nhập để máy khách có thể đọc dữ liệu trả về từ phía máy chủ.
Học viên: Đỗ Trường Linh Trang 10
Tiểu luận: Lập trình mạng
• OutputStream getOutputStream()throws IOException

Lấy về luồng xuất để máy khách có thể ghi dữ liệu gửi đến máy chủ.
• InetAddress getInetAddress()
Lấy địa chỉ kết nối socket của máy chủ.
• Int getPort()
Lấy về số cổng dùng kết nối của máy chủ.
• Synchronized void close () throws IOException
Cắt đứt kết nối với máy chủ.
Ví dụ đoạn mã sau sẽ thực hiện kết nối với máy chủ có địa chỉ
“my.testing.server” và mở ra hai luồng xuất nhập để đọc và gửi thông tin đến
máy chủ có theo số cổng 1234:
try{
Socket me=new Socket(“my.testing.server”, 1234);
//Luồng nhập để đọc thông tin trả về từ máy chủ kết nối
DataInputStream in =
New DataInputStream(me.getInputStream());
//Luồng xuất để ghi thông tin gửi đến máy chủ
DataOutputStream out=new DataOutputStream(me.getOutputStream());
Catch (Exception e){
System.out.println(e);
}
2.3. Lớp ServerSocket
Lớp ServerSocket dùng tao kết nối từ phía máy chủ với các máy khách. Đối
tượng ServerSocket được tạo ra trên máy chủ và lắng nghe những kết nối từ phía máy
khách gửi đến theo một số cổng định trước. Đối tượng ServerSocket được khởi dựng
từ phương thức sau:
• Public ServerSocket(int port)throws IOEXception
port là số hiệu cổng mà đối tượng ServerSocket phải lắng nghe để nhận biết những kết
nối từ phía máy khách gửi đến.
Để chờ đợi kết nối từ các máy khách gửi đến đối tương ServerSocket thường đến phương
thức accept như sau:

• Socket accept()throws IOEXception
Phương thức này thực sự dừng lại chờ đợi cho đến khi nhận được thông tin kết nối sẽ trả về
đối tượng socket của máy khách nơi có yêu cầu nối vào máy chủ.
Cuối cùng máy chủ có thể cắt đứt mọi kết nối bằng cách gọi phương thức close của đối
tượng ServerSocket:
• Public void close()throws IOEXception
Ví dụ đoạn mã sau sẽ tạo ra một đối tượng ServerSocket trên máy chủ luôn lắng
nghe kết nối từ máy khách gửi đến qua số cổng 1234
try{
ServerSocket server=new ServerSocket (1234);
Socket client;
//Chương trình server sẽ dừng lại ở đây để chờ đợi sự kết nối
Học viên: Đỗ Trường Linh Trang 11
Tiểu luận: Lập trình mạng
Client=server.accept()
//Có một kết nối gửi đến từ phía máy khách
System.out.println(“Accept connect”);
//Xử lý các yêu cầu về dịch vụ
//…
//Cắt đứt các kết nối
client.close();
server.close();
catch (Exception e){
System.out.println(e);
}
Học viên: Đỗ Trường Linh Trang 12
Tiểu luận: Lập trình mạng
CHƯƠNG 3
BÀI TOÁN ĐẢM BẢO GẮN BÓ DỮ LIỆU KHI CẬP NHẬT
TRONG CÁC CSDL TẬP TRUNG TẠI CÁC NGÂN HÀNG

BẰNG NGÔN NGỮ JAVA
3.1. Mô tả yêu cầu của bài toán
Bài toán xây dựng một bộ phân phối tải (Bộ cung cấp tài nguyên - Server). Bộ
cung cấp tài nguyên căn cứ vào tài nguyên hiện có của mạng (Khả năng đáp ứng yêu
cầu dịch vụ của Client) mà chấp nhận phục vụ hay từ chối yêu cầu cung cấp dịch vụ
từ Client.
Yêu cầu dịch vụ từ Client ở đây được mô tả bằng cách Client gởi số tiền hoặc
rút tiền ra từ tài khoản (cập nhật ngẫu nhiên ) đến Server, yêu cầu Server kiểm tra tài
khoản gửi đến và gởi trả lại số tiền hiện tại trong tài khoản.
Trong quá trình vận hành hệ thống, Server phải biết được tình trạng hiện tại của
hệ thống như: Số Client yêu cầu cung cấp dịch vụ hiện tại; Số thông điệp (Message)
của các Client đã gởi đến cho Server; Client nào đã kết thúc yêu cầu kết nối đến
Server; Tình trạng của Server (Có khả năng đáp ứng hay từ chối yêu cầu của Client
(quá tải)…
Hệ thống chỉ từ chối yêu cầu của các Client khi quá tải, các yêu cầu từ các
Client khác vẫn được phục vụ bình thường. Khi hệ thống giảm tải (do các Client
không yêu cầu tài nguyên nữa) thì các Client khác có thể sử dụng tài nguyên hệ thống
bình thường.
3.2. Tổ chức chương trình
Chương trình sử dụng cơ chế đa luồng và socket trong java để thiết lập kết nối từ
Client đến Server để trao đổi thông tin:
Học viên: Đỗ Trường Linh Trang 13
Server
Client 1
Client n
Socket lắng nghe trên cổng
Một socket
cho một client
Kết nối qua socket
Tiểu luận: Lập trình mạng

Chương trình trên Server :
Hoạt động như một bộ phân phối tải tổng quát, tạo ra các cổng (Socket) cho
phép Client kết nối đến, lắng nghe yêu cầu kết nối của Client qua các cổng, chấp nhận
hay từ chối yêu cầu cung cấp dịch vụ từ Client tùy theo tình trạng của mạng.
/** BankDBServer.java

import java.io.*;
import java.net.*;
import java.util.*;
[
public class BankDBServer {
public static HashMap accounts = new HashMap();
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Usage: java BankDBServer port
maxConnection");
System.exit(0);
}
int port = 2096;
int maxConnection = 50;
try {
port = Integer.parseInt(args[0]);
maxConnection = Integer.parseInt(args[1]);
}
catch (NumberFormatException nfe) {
System.err.println("number format invalid !");
System.exit(1);
}
try {
Account account = null;

for ( int i = 0; i < 10 ; i++ ) {
account = new Account(String.valueOf(i), 0);
accounts.put(String.valueOf(i), account);
}
ServerSocket s = new ServerSocket(port, maxConnection);
while (true) {
Socket client = s.accept();
Runnable r = new BankService(client, accounts);
Thread t = new Thread(r);
t.start();
}
}
catch (IOException ioe) {
ioe.printStackTrace();
Học viên: Đỗ Trường Linh Trang 14
Tiểu luận: Lập trình mạng
}
}
}
/** BankService.java
import java.io.*;
import java.net.*;
import java.util.*;
public class BankService implements Runnable {
Socket client;
HashMap accounts;
/*
* constructor
*/
public BankService(Socket client, HashMap accounts) {

this.client = client;
this.accounts = accounts;
}
/*
* Thread nay se tinh toan, tra ve so tai khoan cho client khi
clien ket noi vao
* Thread nay duoc sinh ra tuong ung voi moi ket noi
*/
public void run() {
try {
finally {
InputStream inStream = client.getInputStream();
OutputStream outStream = client.getOutputStream();
Scanner in = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream, true);
while (in.hasNextLine()) {
// chua dinh dang: accountID(+/-)atm
String line = in.nextLine();
if (line.equals("exit"))
break;
boolean isSuccess = true;
String[] s = new String[2];
Account account = null;
int index = -1;
if ((index = line.indexOf('+')) != -1 ) {
// accountID
s[0] = line.substring(0, index);
// so tien (atm)
Học viên: Đỗ Trường Linh Trang 15
Tiểu luận: Lập trình mạng

s[1] = line.substring(index + 1, line.length());
account = (Account) accounts.get(s[0]);
account.deposit(Integer.parseInt(s[1]));
}
else if ((index = line.indexOf('-')) != -1 ) {
// accountID
s[0] = line.substring(0, index);
// so tien (atm)
s[1] = line.substring(index + 1, line.length());
account = (Account) accounts.get(s[0]);
isSuccess = account.withdraw(Integer.parseInt(s[1]));
}
String logMsg = null;
if ( isSuccess ) {
// thao tac xu ly thanh cong
logMsg = "So du cua tai khoan [" + s[0] + "] la: " +
account.getBalance();
}
else {
// thao tac thuc hien khong thanh cong
logMsg = "Ban khong the rut tien tu tai khoan [" +
s[0] + "]: So du tai khoan phai lon hon so tien can rut";
}
out.println(logMsg);
out.flush();
System.out.println(logMsg);
}
}
}
catch (IOException ioe) {

ioe.printStackTrace();
}
catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
}
}
/** Account.java
public class Account {
//so tai khoan
int balance;
//id cua tai khoan
String accountID;
Học viên: Đỗ Trường Linh Trang 16
Tiểu luận: Lập trình mạng
public Account(String accountID, int balance) {
this.accountID = accountID;
this.balance = balance;
}
public void setAccountID(String accountID) {
this.accountID = accountID;
}
public String getAccountID() {
return accountID;
}
/*
* tra ve so tai khoan
*/
public int getBalance() {
return balance;

}
/*
* thiet lap so tai khoan moi
*/
public void setBalance(int balance) {
this.balance = balance;
}
/*
* gui tien (amt) vao tai khoan
*/
public synchronized boolean deposit(int amt) {
balance += amt;
return true;
}
/*
* rut tien ra khoi tai khoan
*/
public synchronized boolean withdraw(int amt) {
if (amt > balance) {
System.out.println("Khong the rut tien !");
return false;
}
else {
balance -= amt;
return true;
}
}
}
Học viên: Đỗ Trường Linh Trang 17
Tiểu luận: Lập trình mạng

Chương trình trên Client:
Client có nhiệm vụ nhập vào số tiền cho tài khoản, kết nối với Server, gởi số
tiền cho Server yêu cầu Server tính giá trị trong tài khoản và nhận kết quả từ Server.
Chương trình sử dụng vòng lặp để tạo ra n Client cho phép kết nối đồng thời tới
Server.
Chương trình trên Client như sau:
/** BankClient.java
import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.Integer;
public class BankClient {
public static void main(String[] args) {
if (args.length != 5) {
System.out.println("Usage: java BankClient host
port id operater value");
System.exit(0);
}
System.out.println("Client");
String host = args[0];
int id=0;
char operator='+';
int value=0;
int port = 2096;
try{
port = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe){
System.out.println("port error");
}
try {

id = Integer.parseInt(args[2]);
}
catch (NumberFormatException nfe){
System.out.println("id error");
}
try{
operator = args[3].charAt(0);
}
catch (NumberFormatException nfe){
System.out.println("operator error");
}
Học viên: Đỗ Trường Linh Trang 18
Tiểu luận: Lập trình mạng
try{
value = Integer.parseInt(args[4]);
}
catch (NumberFormatException nfe){
System.out.println("value error");
}
try{
AccountClient accountClient = new AccountClient(host,
port,String.valueOf(id) ,operator, value, (int) id);
Thread t = new Thread(accountClient);
t.start();
}
catch (Exception e) {
System.err.println(e);
}
}
}

/** AccountClient.java
import java.io.*;
import java.net.*;
import java.util.*;
public class AccountClient implements Runnable {
String host;
int port;
String accountID;
char operator;
int atm;
int random;
public AccountClient(String host, int port, String accountID,
char operator, int atm, int random) {
this.host = host;
this.port = port;
this.accountID = accountID;
this.operator = operator;
this.atm = atm;
this.random = random;
}
public void run() {
Socket s = null;
PrintWriter out = null;
Scanner in = null;
try {
Học viên: Đỗ Trường Linh Trang 19
Tiểu luận: Lập trình mạng
s = new Socket(host, port);
out = new PrintWriter(s.getOutputStream());
in = new Scanner(s.getInputStream());

StringBuffer msg = new StringBuffer();
msg.append(accountID);
msg.append(operator);
msg.append(String.valueOf(atm));
switch (random % 5) {
case 0:
Thread.sleep(40);
break;
case 1:
Thread.sleep(24);
break;
case 2:
Thread.sleep(35);
break;
case 3:
Thread.sleep(15);
break;
case 4:
Thread.sleep(10);
}
out.println(msg);
out.flush();
String result = in.nextLine();
System.out.println("msg from server: " + result);
out.println("exit");
out.flush();
}
catch (Exception e) {
System.err.println(e);
}

finally {
if ( s != null ) {
try {
s.close();
}
catch (Exception e) {
System.err.println(e);
}
}
}
}
}
Học viên: Đỗ Trường Linh Trang 20
Tiểu luận: Lập trình mạng
3.3. Giao diện chương trình
Chương trình Server:
Chương trình Client:
Học viên: Đỗ Trường Linh Trang 21
Tiểu luận: Lập trình mạng
KẾT LUẬN
Qua thời gian tìm hiểu về lập trình phân tán nói chung và thực hiện bài toán đảm
bảo gắn bó khi cập nhật trong các CSDL tập trung tại các ngân hàng, đề tài đã đạt
được một số yêu cầu sau:
Tìm hiểu và trình bày các vấn đề về quản lý CSDL mạng ngân hàng.
Tìm hiểu và sử dụng ngôn ngữ lập trình Java, đặc biệt là sử dụng môi trường
lập trình phân tán của Java.
Tuy nhiên do thời gian và khả năng còn hạn chế nên đề tài chỉ dừng lại ở mức độ
mô phỏng, chưa triển khai điều khiển trên các hệ thống thực và chưa giải quyết được
bài toán quản lý tải phân tán.
Tôi xin chân thành cảm ơn ý kiến đóng góp của thầy giáo PGS. TS.Lê Văn Sơn và

các bạn quan tâm để đề tài được hoàn thiện hơn.
TÀI LIỆU THAM KHẢO
1. Hệ tin học phân tán – TS. Lê Văn Sơn, NXB Đại học quốc gia TP HCM- 2002.
2. Java lập trình mạng - Nguyễn Phương Lan, Hoàng Đức Hải- NXB Lao động xã hội
– 2006.
3. Giáo trình lý thuyết và bài tập Java – Trần Tiến Dũng – NXB Giáo dục.
4. DISTRIBUTED SYSTEMS – CONCEPTS AND DESIGN – George Coulouris,
Jean Dollimore and Tim Kindberg
5. Lập trình hướng đối tượng với Java- Ts. Đoàn Văn Ban – Nhà xuất bản khoa học
và kỹ thuật – 2005.
Học viên: Đỗ Trường Linh Trang 22
Tiểu luận: Lập trình mạng
MỤC LỤC
MỞ ĐẦU 2
CHƯƠNG 1 3
TÌM HIỂU VỀ LẬP TRÌNH PHÂN TÁN TRONG JAVA 3
1.1. RMI và lập trình phân tán đối tượng 3
1.2. Gọi phương thức từ xa và các vấn đề phát sinh 4
1.3. Vai trò các lớp trung gian (Stub và Skeletion) 4
1.4. Cài đặt ứng dụng phân tán RMI 5
CHƯƠNG 2 10
CHƯƠNG 3 13
BÀI TOÁN ĐẢM BẢO GẮN BÓ DỮ LIỆU KHI CẬP NHẬT TRONG CÁC CSDL
TẬP TRUNG TẠI CÁC NGÂN HÀNG BẰNG NGÔN NGỮ JAVA 13
3.1. Mô tả yêu cầu của bài toán 13
3.2. Tổ chức chương trình 13
Chương trình Client: 21
21
KẾT LUẬN 22
Học viên: Đỗ Trường Linh Trang 23

×