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.
1.2. Khả tuần tự (Serializable)
Chỉ có đối tượng thực thi giao diện Serializable mới có thể được ghi lại
hóa.
public class Point implements Serializable
{
private double x,y;
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(){
System.out.println("Toa do cua diem la:");
System.out.println("Toa do x="+x);
System.out.println("Toa do y="+y);
}
}
1.4. Cơ chế đọc và ghi đối tượng trên thiết bị lưu trữ ngoài
Chúng ta đều biết rằng tất cả các thao tác nhập và xuất dữ liệu trong
Java thực chất là việc đọc và ghi trên các luồng dữ liệu vào và luồng dữ liệu
ra. Việc đọc và ghi đối tượng trên thiết bị lưu trữ ngoài cũng không phải là
một ngoại lệ. Chúng ta có thể thấy được cơ chế này qua hình 4.
Serializable Object
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.
2.1. Lớp Socket
Lớp Socket của Java được sử dụng bởi cả client và server, nó có các phương
thức tương ứng với bốn thao tác đầu tiên. Ba thao tác cuối chỉ cần cho server để
chờ các client liên kết với chúng. Các thao tác này được cài đặt bởi lớp
ServerSocket. Các Socket cho client thường được sử dụng theo mô hình sau:
1. Một Socket mới được tạo ra bằng cách sử dụng hàm dựng Socket().
2. Socket cố gắng liên kết với một host ở xa.
3. Mỗi khi liên kết được thiết lập, các host ở xa nhận các luồng vào và luồng
ra từ Socket, và sử dụng các luồng này để gửi dữ liệu cho nhau. Kiểu liên
kết này được gọi là song công (full-duplex), các host có thể nhận và gửi dữ
liệu đồng thời. Ý nghĩa của dữ liệu phụ thuộc vào từng giao thức.
4. Khi việc truyền dữ liệu hoàn thành, một hoặc cả hai phía ngắt liên kết. Một
số giao thức, như HTTP, đòi hỏi mỗi liên kết phải bị đóng sau mỗi khi yêu
cầu được phục vụ. Các giao thức khác, chẳng hạn như FTP, cho phép
nhiều yêu cầu được xử lý trong một liên kết đơn.
2.2. Lớp ServerSocket
Lớp ServerSocket có đủ mọi thứ ta cần để viết các server bằng Java. Nó
có các constructor để tạo các đối tượng ServerSocket mới, các phương thức để
lắng nghe các liên kết trên một cổng xác định và các phương thức trả về một
Socket khi liên kết được thiết lập, vì vậy ta có thể gửi và nhận dữ liệu.
Vòng đời của một server
1. Một ServerSocket mới được tạo ra trên một cổng xác định bằng cách sử
dụng một constructor ServerSocket.
2. ServerSocket lắng nghe liên kết đến trên cổng đó bằng cách sử dụng
phương thức accept(). Phương thức accept() phong tỏa cho tới khi một