Sưu tầm bởi: www.daihoc.com.vn
Chương 10
TUẦN TỰ HÓA ĐỐI TƯỢNG VÀ ỨNG DỤNG TRONG
LẬP TRÌNH MẠNG
1. Tuần tự hóa đối tượng
1.1. Khái niệm
Tuần tự hóa là quá trình chuyển tập hợp các thể hiện đối tượng chứa
các tham chiếu tới các đối tượng khác thành một luồng byte tuyến tính,
luồng này có thể được gửi đi qua một Socket, được lưu vào tệp tin hoặc
được xử lý dưới dạng một luồng dữ liệu. Tuần tự hóa là cơ chế được sử
dụng bởi RMI để truyền các đối tượng giữa các máy ảo JVM hoặc dưới
dạng các tham số trong lời gọi phương thức từ client tới server hoặc là các
giá trị trả về từ một lời gọi phương thức.
Tuần tự hóa là một cơ chế đã được xây dựng và được đưa vào các
lớp thư viện Java căn bản để chuyển một đồ thị các đối tượng thành các
luồng dữ liệu. Luồng dữ liệu này sau đó có thể được xử lý bằng cách lập
trình và ta có thể tạo lại các bản sao của đối tượng ban đầu nhờ quá trình
ngược lại được gọi là giải tuần tự hóa.
Tuần tự hóa có ba mục đích chính sau
Cơ chế ổn định: Nếu luồng được sử dụng là FileOuputStream, thì dữ
liệu sẽ được tự động ghi vào tệp.
Cơ chế sao chép: Nếu luồng được sử dụng là ByteArrayObjectOuput,
thì dữ liệu sẽ được ghi vào một mảng byte trong bộ nhớ. Mảng byte
này sau đó có thể được sử dụng để tạo ra các bản sao của các đối
tượng ban đầu.
Nếu luồng đang được sử dụng xuất phát từ một Socket thì dữ liệu sẽ
được tự động gửi đi tới Socket nhận, khi đó một chương trình khác
sẽ quyết định phải làm gì đối với dữ liệu nhận được.
Một điều quan trọng khác cần chú ý là việc sử dụng tuần tự hóa độc lập
với thuật toán tuần tự hóa.
Khi đó kết quả hiển thị là Class java.net.Socket is not Serializable (Lớp
java.net.Socket không khả tuần tự). 1.3. Xây dựng lớp một lớp khả tuần tự
Đối với các lớp do người lập trình định nghĩa ta phải khai báo để báo
hiệu cho hệ thống biết nó có khả tuần tự hay không. Một lớp do người dùng
định nghĩa có khả năng tuần tự hóa khi lớp đó thực thi giao diện
Serializable. Trong ví dụ dưới đây ta định nghĩa lớp Point để lớp này có khả
năng tuần tự hóa.
public class Point implements Serializable
{
private double x,y;
Sưu tầm bởi: www.daihoc.com.vn
public Point(double x,double y){
this.x=x;
this.y=y;
}
public double getX(){
return x;
}
public double getY(){
return y;
}
public void move(double dx,double dy){
x+=dx;
y+=dy;
}
public void print(){
thuộc tính khả tuần tự cho nó.
Cơ chế ghi đối tượng được tiến hành rất đơn giản: Trước tiên ta tạo
ra một tệp để ghi thông tin, thực chất là tạo ra đối tượng FileOuputStream,
sau đó ta tạo ra một luồng ghi đối tượng ObjectOuputStream gắn với luồng
ghi tệp và gắn kết hai luồng với nhau. Việc ghi đối tượng được thực hiện
bởi phương thức writeObject().
FileOuputStream fos=new FileOuputStream("date.out");
ObjectOuputStream oos=new ObjectOuputStream(fos);
Date d=new Date();
oos.writeObject(d);
Quá trình trên được gọi là quá trình tuần tự hóa.
Chúng ta nhận thấy rằng để phục hồi lại trạng thái của một đối tượng
ta phải mở một tệp để đọc dữ liệu. Nhưng ta không thể đọc được trực tiếp
mà phải thông qua luồng nhập đối tượng ObjectInputStream gắn với luồng
nhập tệp tin FileInputStream. Việc đọc lại trạng thái đối tượng được tiến
hành nhờ phương thức readObject()
FileInputStream fis=new FileInputStream("date.out");
ObjectInputStream ois=new ObjectInputStream(fis);
Date d=(Date)ois.readObject();
Quá trình trên còn được gọi là giải tuần tự hóa
Công việc đọc và ghi trạng thái của đối tượng khả tuần tự do người
lập trình định nghĩa được tiến hành hoàn toàn tương tự như trên.
2. Truyền các đối tượng thông qua Socket
Chúng ta đã biết cách ghi và đọc các đối tượng từ các luồng vào ra
trong một tiến trình đơn, bây giờ chúng ta sẽ xem xét cách truyền đối tượng
thông qua Socket.
Mô hình lập trình Socket cho giao thức TCP là mô hình rất phổ biến
trong lập trình mạng. Để lập chương trình client/server trong Java ta cần hai
lớp Socket và ServerSocket.
getOuputStream() hoặc cả hai được gọi để nhận các luồng vào ra phục vụ
cho việc truyền tin với client.
4. Server và client tương tác theo một giao thức thỏa thuận sẵn cho tới khi
ngắt liên kết.
5. Server, client hoặc cả hai ngắt liên kết
Server trở về bước hai và đợi liên kết tiếp theo.
2.3. Truyền và nhận dữ liệu trong mô hình lập trình Socket
Việc truyền và nhận dữ liệu thực chất là các thao tác đọc và ghi dữ
trên Socket. Ta có thể thấy điều này qua sơ đồ dưới đây:
Hình 5
Giả sử s là một đối tượng Socket. Nếu chương trình nhận dữ liệu thì
ta sẽ lấy dữ liệu từ luồng nhập đến từ Socket:
Program
Socket
InputStream
ObjectOuput