Tải bản đầy đủ

ĐỒ ÁN LẬP TRÌNH MẠNG

MỤC LỤC
MỤC LỤC.................................................................................................................................................... 0
PHẦN 1: HỆ ĐIỀU HÀNH ........................................................................................................................ 1
CHƯƠNG 1: CƠ SỞ LÝ THUYẾT ...................................................................................................... 1
1.

GIỚI THIỆU ............................................................................................................................... 1

2.

CÁC TRẠNG THÁI CỦA TIẾN TRÌNH ................................................................................. 2

3.

CẤU TRÚC CỦA TIẾN TRÌNH ............................................................................................... 3

4.

TẠO LẬP TIẾN TRÌNH ............................................................................................................ 5

5. GIAO TIẾP GIỮA CÁC TIẾN TRÌNH ....................................................................................... 8

CHƯƠNG 2: PHÂN TÍCH THIẾT KẾ .............................................................................................. 11
1.

MÔ HÌNH CÀI ĐẶT THUẬT TOÁN..................................................................................... 11

CHƯƠNG 3: TRIỂN KHAI VÀ DEMO............................................................................................. 13
CHƯƠNG 4: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN ................................................................... 14
1.

NHỮNG KẾT QUẢ ĐẠT ĐƯỢC ............................................................................................ 14

2.

HƯỚNG PHÁT TRIỂN ........................................................................................................... 14

PHẦN 2: LẬP TRÌNH MẠNG ................................................................................................................ 15
CHƯƠNG 1: CƠ SỞ LÝ THUYẾT .................................................................................................... 15
1.

TỔNG QUAN VỀ RMI( REMOTE INVOKE METHOD) ................................................... 15

2.

CƠ CHẾ THỰC THI CỦA MỘT ỨNG DỤNG RMI............................................................ 19

CHƯƠNG 2: PHÂN TÍCH THIẾT KẾ .............................................................................................. 21
1.

PHÂN TÍCH KIẾN TRÚC HỆ THỐNG ................................................................................ 21

2.

THIẾT KẾ HỆ THỐNG........................................................................................................... 21

CHƯƠNG 3: TRIỂN KHAI ................................................................................................................. 22
1.

MÔI TRƯỜNG CÀI ĐẶT........................................................................................................ 22

2.

KẾT QUẢ THỰC HIỆN CÁC CHỨC NĂNG ....................................................................... 22

CHƯƠNG 4: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN ................................................................... 23
1.

NHỮNG KẾT QUẢ ĐẠT ĐƯỢC ............................................................................................ 23

2.

HƯỚNG PHÁT TRIỂN ........................................................................................................... 23

TÀI LIỆU THAM KHẢO ........................................................................................................................ 24


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

PHẦN 1: HỆ ĐIỀU HÀNH
TIÊU ĐỀ: TÌM HIỂU CƠ CHẾ GIAO TIẾP GIỮA 2 QUÁ TRÌNH DÙNG
MESSAGE QUEUE
CHƯƠNG 1: CƠ SỞ LÝ THUYẾT
1. GIỚI THIỆU
1.1. Tiến trình trong Linux
- Một trong những đặc điểm nổi bật của Linux là khả năng chạy đồng thời nhiều
chương trình. Hệ Điều Hành xem mỗi đơn thể mã lệnh mà nó điều khiển là tiến trình
(process). Một chương trình có thể bao gồm nhiều tiến trình kết hợp với nhau.
- Đối với Hệ Điều Hành, các tiến trình cùng hoạt động chia sẻ tốc độ xử lý của
CPU, cùng dùng chung vùng nhớ và tài nguyên hệ thống khác. Các tiến trình được
điều phối xoay vòng bởi Hệ Điều Hành. Một chương trình của chúng ta nếu mở rộng
dần ra, sẽ có lúc cần phải tách ra thành nhiều tiến trình để xử lý những công việc độc
lập với nhau. Các lệnh của Linux thực tế là những lệnh riêng lẻ có khả năng kết hợp
và truyền dữ liệu cho nhau thông qua các cơ chế như: hang đợi thông điệp, đường ống
pipe, chuyển hướng xuất nhập (redirect), phát sinh tín hiệu (signal), … Chúng được
gọi là cơ chế giao tiếp liên tiến trình (IPC – Inter Process Comunication). Đối với tiến
trình, chúng ta sẽ tìm hiểu cách tạo, hủy, tạm dừng tiến trình, đồng bộ hóa tiến trình
và giao tiếp giữa các tiến trình với nhau.
- Xây dựng ứng dụng trong môi trường đa tiến trình như Linux là công việc khó
khăn. Không như môi trường đơn nhiệm, trong môi trường đa nhiệm tiến trình có tài
nguyên rất hạn hẹp. Tiến trình của chúng ta khi hoạt động phải luôn ở trạng thái tôn
trọng và sẵn sàng nhường quyền xử lý CPU cho các tiến trình khác ở bất kỳ thời điểm
nào, khi hệ thống có yêu cầu. Nếu tiến trình của chúng ta được xây dựng không tốt,
khi đổ vỡ và gây ra lỗi, nó có thể làm treo các tiến trình khác trong hệ thống hay thậm
chí phá vỡ (crash) Hệ Điều Hành.
- Định nghĩa của tiến trình: là một thực thể điều khiển đoạn mã lệnh có riêng
một không gian địa chỉ, có ngăn xếp stack riêng rẽ, có bảng chứa các thông số mô tả
file được mở cùng tiến trình và đặc biệt có một định danh PID (Process Identify) duy
nhất trong toàn bộ hệ thống vào thời điểm tiến trình đang chạy. Như chúng ta đã thấy,

Trịnh Minh An – 14T2

1


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

tiến trình không phải là một chương trình (tuy đôi lúc một chương trình đơn giản chỉ
cấn một tiến trình duy nhất để hoàn thành tác vụ, trong trường hợp này thì chúng ta có
thể xem tiến trình và chương trình là một). Rất nhiều tiến trình có thể thực thi trên
cùng một máy với cùng một Hệ Điều Hành, cùng một người dùng hoặc nhiều người
dùng đăng nhập khác nhau. Ví dụ shell bash là một tiến trình có thể thực thi lệnh ls
hay cp. Bản thân ls, cp lại là những tiến trình có thể hoạt động tách biệt khác.
- Trong Linux, tiến trình được cấp không gian địa chỉ bộ nhớ phẳng là 4GB. Dữ
liệu của tiến trình này không thể đọc và truy xuất được bởi các tiến trình khác. Hai
tiến trình khác nhau không thể xâm phạm biến của nhau. Tuy nhiên, nếu chúng ta
muốn chia sẻ dữ liệu giữa hai tiến trình, Linux có thể cung cấp cho chúng ta một vùng
không gian địa chỉ chung để làm điều này.
1.2. Các đặc điểm tiến trình
Điều phối hoạt động của các tiến trình là một vấn đề rất phức tạp, đòi hỏi hệ điều
hành khi giải quyết phải xem xét nhiều yếu tố khác nhau để có thể đạt được những
mục tiêu đề ra. Một số đặc tính của tiến trình cần được quan tâm như tiêu chuẩn điều
phối:
- Tính hướng nhập/xuất của tiến trình.
- Tính hướng xử lý của tiến trình.
- Tiến trình tương tác hay xử lý theo lô.
- Độ ưu tiên của tiến trình.
- Thời gian đã xử dụng CPU của tiến trình.
- Thời gian còn lại tiến trình cần để hoàn tất.
2. CÁC TRẠNG THÁI CỦA TIẾN TRÌNH
- Khi 1 chương trình đang chạy từ dòng lệnh, chúng ta có thể nhấn phím Ctrl+z để tạm
dùng chương trình và đưa nó vào hoạt động phía hậu trường (background). Tiến trình của
Linux có các trạng thái:
 Đang chạy (running) : đây là lúc tiến trình chiếm quyền xử lý CPU dùng tính toán
hay thực các công việc của mình.
 Chờ (waiting) : tiến trình bị Hệ Điều Hành tước quyền xử lý CPU, và chờ đến
lược cấp phát khác.

Trịnh Minh An – 14T2

2


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

 Tạm dừng (suspend) : Hệ Điều Hành tạm dừng tiến trình. Tiến trình được đưa vào
trạng thái ngủ (sleep). Khi cần thiết và có nhu cầu, Hệ Điều Hành sẽ đánh thức
(wake up) hay nạp lại mã lệnh của tiến trình vào bộ nhớ. Cấp phát tài nguyên CPU
để tiến trình tiếp tục hoạt động.
- Trên dòng lệnh, thay vì dùng lệnh Ctrl+z, chúng ta có thể sử dụng lệnh bg để đưa một
tiến trình vào hoạt động phía hậu trường. Chúng ta cũng có thể yêu cầu 1 tiến trình chạy
nền bằng cú pháp &. Ví dụ: $ls –R & Lệnh fg sẽ đem tiến trình trở về hoạt động ưu tiên
phía trước. Thực tế khi chúng ta đăng nhập vào hệ thống và tương tác trên dòng lệnh,
cũng là lúc chúng ta đang ở trong tiến trình shell của bash. Khi gọi một lệnh có nghĩa là
chúng ta đã yêu cầu bash tạo thêm một tiến trình con thực thi khác. Về mặt lập trình,
chúng ta có thể dùng lệnh fork() để nhân bản tiến trình mới từ tiến trình cũ. Hoặc dùng
lệnh system() để triệu gọi một tiến trình của Hệ Điều Hành. Hàm exec() cũng có khả
năng tạo ra tiến trình mới khác.
3. CẤU TRÚC CỦA TIẾN TRÌNH
- Chúng ta hãy xem Hệ Điều
Hành quản lý tiến trình như thế
nào? Nếu có hai người dùng: user1
và user2 cùng đăng nhập vào chạy
chương trình grep đồng thời. Thực
tế, Hệ Điều Hành sẽ quản lý và nạp
mã của chương trình grep vào hai
vùng nhớ khác nhau và gọi mỗi
phân vùng như vậy là tiến trình.
Hình sau cho thấy cách phân chia
chương trình grep thành hai tiến
trình cho hai người khác nhau sử
dụng Trong hình này, user1 chạy
chương trình grep tìm chuỗi abc
trong tập tin file1. “ $grep abc file1 ”, user2 chạy chương trình grep và tìm chuỗi cde
trong tập tin file2. “$grep cde file2”.
Chúng ta cần ta cần nhớ là hai người dùng user1 và user2 có thể ở hai máy tính khác
nhau đăng nhập vào máy chủ Linux và gọi grep chạy đồng thời. Hình trên là hiện trạng
không gian bộ nhớ Hệ Điều Hành Linux khi chương trình grep phục vụ người dùng.
- Nếu dùng lệnh ps, hệ thống sẽ liệt kê cho chúng ta thông tin về các tiến trình mà Hệ
Điều Hành đang kiểm soát, Ví dụ: $ps –af Mỗi tiến trình được gán cho một định danh để
nhận dạng gọi là PID (process identify). PID thường là số nguyên dương có giá trị từ 2-

Trịnh Minh An – 14T2

3


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

32768. Khi một tiến trình mới yêu cầu khởi động, Hệ Điều Hành sẽ chọn lấy một số
(chưa bị tiến trình nào đang chạy chiếm giữ) trong khoảng số nguyên trên và cấp phát cho
tiến trình mới. Khi tiến trình chấm dứt, hệ thống sẽ thu hồi số PID để cấp phát cho tiến
trình khác trong lần sau. PID bắt đầu từ giá trị 2 bởi vì giá trị 1 được dành cho tiến trình
đầu tiên gọi là init. Tiến trình init được và chạy ngay khi chúng ta khởi động Hệ Điều
Hành. init là tiến trình quản lý và tạo ra mọi tiến trình con khác. Ở ví dụ trên, chúng ta
thấy lệnh ps –af sẽ hiển thị 2 tiến trình grep chạy bởi user1 và user2 với số PID lần lượt
là 101 và 102.
- Mã lệnh thực thi của lệnh grep chứa trong tập tin chương trình nằm trên đĩa cứng
được Hệ Điều Hành nạp vào vùng nhớ. Như chúng ta đã thấy ở lược đồ trên, mỗi tiến
trình được Hệ Điều hành phân chia rõ ràng: vùng chứa mã lệnh (code) và vùng chứa dữ
liệu (data). Mã lệnh thường là giống nhau và có thể sử dụng chung. Linux quản lý cho
phép tiến trình của cùng một chương trình có thể sử dụng chung mã lệnh của nhau. Thư
viện cũng vậy. Trừ những thư viện đặc thù còn thì các thư viện chuẩn sẽ được Hệ Điều
Hành cho phép chia sẻ và dùng chung bởi mọi tiến trình trong hệ thống. Bằng cách chia
sẻ thư viện, kích thước chương trình giảm đi đáng kể. Mã lệnh của chương trình khi chạy
trong hệ thống ở dạng tiến trình cũng sẽ đỡ tốn bộ nhớ hơn.
- Trừ mã lệnh và thư viện có thể chia sẻ, còn dữ liệu thì không thể chia sẻ bởi các tiến
trình. Mỗi tiến trình sở hữu phân đoạn dữ liệu riêng. Ví dụ tiến trình grep do user1 nắm
giữ lưu giữ biến s có giá trị là 'abc', trong khi grep do user2 nắm giữ lại có biến s với giá
trị là 'cde'. Mỗi tiến trình cũng được hệ thống dành riêng cho một bảng mô tả file (file
description table). Bảng này chứa các số mô tả áp đặt cho các file đang được mở. Khi
mỗi tiến trình khởi động, thường Hệ Điều Hành sẽ mở sẳn cho chúng ta 3 file : stdin (số
mô tả 0), stdout (số mô tả 1), và stderr (số mô tả 2). Các file này tượng trưng cho các
thiết bị nhập, xuất, và thông báo lỗi. Chúng ta có thể mở thêm các file khác. Ví dụ user1
mở file file1, và user2 mở file file2. Hệ Điều Hành cấp phát số mô tả file cho mỗi tiến
trình và lưu riêng chúng trong bảng mô tả file của tiến trình đó.
- Ngoài ra, mỗi tiến trình có riêng ngăn xếp stack để lưu biến cục bộ và các giá trị trả
về sau lời gọi hàm. Tiến trình cũng được dành cho khoảng không gian riêng để lưu các
biến môi trường. Chúng ta sẽ dùng lệnh putenv và getenv để đặt riêng biến môi trường
cho tiến trình.
a) Bảng thông tin tiến trình: Hệ Điều Hành lưu giữ một cấu trúc danh sách bên
trong hệ thống gọi là bảng tiến trình (process table). Bảng tiến trình quản lý tất cả PID
của hệ thống cùng với thông tin chi tiết về các tiến trình đang chạy. Ví dụng khi chúng ta
gọi lệnh ps, Linux thường đọc thông tin trong bảng tiến trình này và hiển thị những lệnh
hay tên tiến trình được gọi: thời gian chiếm giữ CPU của tiến trình, tên người sử dụng
tiến trình, …

Trịnh Minh An – 14T2

4


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

b) Xem thông tin của tiến trình: Lệnh ps của Hệ Điều Hành dùng để hiển thị thông
tin chi tiết về tiến trình. Tùy theo tham số, ps sẽ cho biết thông tin về tiến trình người
dùng, tiến trình của hệ thống hoặc tất cả các tiến trình đang chạy. Ví dụ ps sẽ đưa ra chi
tiết bằng tham số -af. Trong các thông tin do ps trả về, UID là tên của người dùng đã gọi
tiến trình, PID là số định danh mà hệ thống cấp cho tiến trình, PPID là số định danh của
tiến trình cha (parent PID). Ở đây chúng ta sẽ gặp một số tiến trình có định danh PPID
là 1, là định danh của tiến trình init, được gọi chạy khi hệ thống khởi động. Nếu chúng ta
hủy tiến trình init thì Hệ Điều Hành sẽ chấm dứt phiên làm việc. STIME là thời điểm
tiến trình được đưa vào sử dụng. TIME là thời gian chiếm dụng CPU của tiến trình.
CMD là toàn bộ dòng lệnh khi tiến trình được triệu gọi. TTY là màn hình terminal ảo nơi
gọi thực thi tiến trình. Như chúng ta đã biết, người dùng có thể đăng nhập vào hệ thống
Linux từ rất nhiều terminal khác nhau để gọi tiến trình. Để liệt kê các tiến trình hệ thống,
chúng ta sử dụng lệnh: $ps –ax
4. TẠO LẬP TIẾN TRÌNH
a) Gọi tiến trình mới bằng hàm system()
Chúng ta có thể gọi một tiến trình khác bên trong một chương trình đang thực thi
bằng hàm system(). Có nghĩa là chúng ta có thể tạo ra một tiến trình mới từ một tiến
trình đang chạy. Hàm system() được khai báo như sau:
#include
int system( const char (cmdstr) )

Hàm này gọi chuỗi lệnh cmdstr thực thi và chờ lệnh chấm dứt mới quay về nơi
gọi hàm. Nó tương đương với việc bạn gọi shell thực thi lệnh của hệ thống: $sh –c
cmdstr system() sẽ trả về mã lỗi 127 nếu như không khởi động được shell để gọi lệnh
cmdstr. Mã lỗi -1 nếu gặp các lỗi khác. Còn lại, mã trả về của system() là mã lỗi do
cmdstr sau khi lệnh được gọi trả về. Ví dụ sử dụng hàm system(), system.c
#include
#include
int main() {
printf( "Thuc thi lenh ps voi system\n" );
system( "ps –ax" ); system(“mkdir daihoc”);
system(“mkdir caodang”);
printf( "Thuc hien xong. \n" );
exit( 0 );
}

Hàm system() của chúng ta được sử dụng để gọi lệnh “ps –ax” của Hệ Điều Hành.

Trịnh Minh An – 14T2

5


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

b) Nhân bản tiến trình với hàm fork()
- Thay thế tiến trình đôi khi bất lợi với
chúng ta. Đó là tiến trình mới chiếm
giữ toàn bộ không gian của tiến trình
cũ và chúng ta sẽ không có khả năng
kiểm soát cũng như điều khiển tiếp
tiến trình hiện hành của mình sau khi
gọi hàm exec nữa. Cách đơn giản mà
các chương trình Linux thường dùng
đó là sử dụng hàm fork() để nhân bản
hay tạo bản sao mới của tiến trình.
fork() là một hàm khá đặc biệt, khi
thực thi, nó sẽ trả về 2 giá trị khác
nhau trong lần thực thi, so với hàm
bình thường chỉ trả về 1 giá trị trong
lần thực thi. Khai báo của hàm fork()
như sau:
#include
#include
pid_t fork()

Cơ chế phân chia tiến trình của fork()
- Nếu thành công, fork() sẽ tách tiến trình hiện hành 2 tiến trình (dĩ nhiên
Hệ Điều Hành phải cấp phát thêm không gian bộ nhớ để tiến trình mới hoạt động).
Tiến trình ban đầu gọi là tiến trình cha (parent process) trong khi tiến trình mới gọi
là tiến trình con (child process). Tiến trình con sẽ có một số định danh PID riêng
biệt. ngoài ra, tiến trình con còn mang thêm một định danh PPID là số định danh
PID của tiến trình cha.
- Sau khi tách tiến trình, mã lệnh thực thi ở cả hai tiến trình được sao chép
là hoàn toàn giống nhau. Chỉ có một dấu hiệu để chúng ta có thể nhận dạng tiến
trình cha và tiến trình con, đó là trị trả về của hàm fork(). Bên trong tiến trình con,
hàm fork() sẽ trả về trị 0. Trong khi bên trong tiến trình cha, hàm fork() sẽ trả về
trị số nguyên chỉ là PID của tiến trình con vừa tạo. Trường hợp không tách được
tiến trình, fork() sẽ trả về trị -1. Kiểu pid_t được khai báo và định nghĩa trong
uinstd.h là kiểu số nguyên (int).
- Đoạn mã điều khiển và sử dụng hàm fork() thường có dạng chuẩn sau:

Trịnh Minh An – 14T2

6


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

pid_t new_pid;
new_pid = fork(); // tách ti ế n trình
switch (new_pid) {
case -1: printf( "Khong the tao tien trinh moi" ); break;
case 0: printf( "Day la tien trinh con" );
// mã l ệ nh dành cho ti ế n trình con đ ặ t ở đây
break;
default: printf( "Day la tien trinh cha" );
// mã l ệ nh dành cho ti ế n trình cha đ ặ t ở đây
break;
}

c) Kiểm soát và đợi tiến trình con
- Khi fork() tách tiến trình chính thành hai tiến trình cha và con, trên thực tế cả hai
tiến trình cha lẫn tiến trình con đều hoạt động độc lập. Đôi lúc tiến trình cha cần phải
đợi tiến trình con thực hiện xong tác vụ thì mới tiếp tục thực thi. Ở ví dụ trên, khi thực
thi, chúng ta sẽ thấy rằng tiến trình cha đã kết thúc mà tiến trình con vẫn in thông báo
và cả tiến trình cha và tiến trình con đều tranh nhau gởi kết quả ra màn hình. Chúng ta
không muốn điều này, chúng ta muốn rằng khi tiến trình cha kết thúc thì tiến trình con
cũng hoàn tất thao tác của nó. Hơn nữa, chương trình con cần thực hiện xong tác vụ
của nó thì mới đến chương trình cha. Để làm được việc này, chúng ta hãy sử dụng
hàm wait():
#include
#include
pid_t wait(int &stat_loc);

Hàm wait() khi được gọi sẽ yêu cầu tiến trình cha dừng lại chờ tiến trình con kết
thúc trước khi thực hiện tiếp các lệnh điều khiển trong tiến trình cha. wait() làm cho
sự liên hệ giữa tiến trình cha và tiến trình con trở nên tuần tự. Khi tiến trình con kết
thúc, hàm sẽ trả về số PID tương ứng của tiến trình con. Nếu chúng ta truyền thêm
đối số stat_loc khác NULL cho hàm thì wait() cũng sẽ trả về trạng thái mà tiến trình
con kết thúc trong biến stat_loc. Chúng ta có thể sử dụng các macro khai báo sẵn
trong sys/wait.h như sau:
WIFEXITED (stat_loc) Trả về trị khác 0 nếu tiến trình con kết thúc bình thường.
WEXITSTATUS (stat_loc) Nếu WIFEXITED trả về trị khác 0, macro này sẽ trả về
mã lỗi của tiến trình con.
WIFSIGNALED (stat_loc) Trả về trị khác 0 nếu tiến trình con kết thúc bởi một tín
hiệu gửi đến.
WTERMSIG(stat_loc) Nếu WIFSIGNALED khác 0, macro này sẽ cho biết số tín
hiệu đã hủy tiến trình con.

Trịnh Minh An – 14T2

7


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

WIFSTOPPED(stat_loc) Trả về trị khác 0 nếu tiến trình con đã dừng.
WSTOPSIG(stat_loc) Nếu WIFSTOPPED trả về trị khác 0, macro này trả về số
hiệu của signal.
5. GIAO TIẾP GIỮA CÁC TIẾN TRÌNH

 Linux cung cấp một số cơ chế giao tiếp giữa các tiến trình gọi là IPC (InterProcess Communication):
o Trao đổi bằng tín hiệu (signals handling).
o Trao đổi bằng cơ chế đường ống (pipe).
o Trao đổi thông qua hàng đợi thông điệp (message queue).
o Trao đổi bằng phân đoạn nhớ chung (shared memory segment).
o Giao tiếp đồng bộ dùng semaphore.
o Giao tiếp thông qua socket
 (Inter-Process Communication) Cơ chế cho phép các tiến trình giao tiếp với nhau
và đồng bộ hóa hành động của chúng
 Hệ thống thông điệp – các tiến trình giao tiếp với nhau không cần phải qua các
biến dùng chung
 IPC cung cấp hai thao tác cơ bản:
o send(message)
o receive(message)
 Nếu tiến trình P và Q muốn giao tiếp với nhau, chúng phải:
o tạo một đường giao tiếp giữa chúng
o trao đổi các thông điệp thông qua send/receive.
 Các tiến trình đang thực thi có thể là độc lập hay hợp tác.
 Các tiến trình hợp tác phải có phương tiện giao tiếp với nhau: chia sẻ bộ nhớ,
truyền thông điệp.
 Phương pháp chia sẻ bộ nhớ yêu cầu các tiến trình giao tiếp chia sẻ một số biến.
Các tiến trình trao đổi thông tin thông qua việc sử dụng các biến dùng chung này.
a. Trao đổi thông qua hàng đợi thông điệp (message queue):
Ý tưởng cơ bản về hàng đợi thông điệp
là một hàng đợi đơn giản. Hai (hoặc
nhiều) tiến trình có thể trao đổi thông tin
thông qua truy cập vào một hàng đợi
thông điệp hệ thống được sử dụng chung
cho các tiến trình. Các thông điệp
được gửi vào một hàng đợi và cùng lúc
có thể được đọc bởi một tiến trình
khác. Mỗi thông điệp được nhận dạng và
phân loại để các tiến trình có thể chọn

Trịnh Minh An – 14T2

8


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

thông điệp thích hợp. Các tiến trình phải chia sẻ khóa chung(key) để có quyền truy
cập vào các thông điệp của nhau trên hàng đợi ở vị trí đầu tiên.
b. Khởi tạo hàng đợi thông điệp:
Hàm msgget() khởi tạo một hàng đợi tin nhắn mới,
#include ;
#include ;
...
int msqid = msgget(key_t key, int msgflg);
Và nó cũng có thể trả về ID của hàng đợi thông điệp (msqid) của hàng đợi tương
ứng với đối số khóa(key). Giá trị được truyền dưới dạng đối số msgflg phải là một
số nguyên đại diện của các cài đặt cho quyền và cờ điều khiển của hàng đợi.
c. Kiểm soát hang đợi thông điệp:
Hàm msgctl () thay đổi các quyền và các đặc tính khác của hàng đợi thông
điệp. Chủ sở hữu hoặc người tạo hàng đợi có thể thay đổi quyền sở hữu hoặc
quyền của nó bằng cách sử dụng msgctl(). Ngoài ra, bất kỳ tiến trình nào có quyền
làm như vậy đều có thể sử dụng msgctl() cho các hoạt động kiểm soát.
Hàm msgctl () nguyên mẫu như sau:
int msgctl (int msqid, int cmd, struct msqid_ds * buf)
Đối số msqid phải là ID của hàng đợi thông điệp hiện có.
Đối số cmd là một trong số sau:
 IPC_STAT: Đặt thông tin về trạng thái của hàng đợi trong cấu trúc dữ liệu
được chỉ ra bởi buf. Tiến trình phải có quyền đọc để lời gọi hàm này thành
công.
 IPC_SET: Đặt ID người dùng và ID nhóm người dùng của chủ sở hữu,
quyền và kích thước (số byte) của hàng đợi tin nhắn. Quá trình phải có ID
người dùng của chủ sở hữu, người tạo hàng đợi hoặc siêu người dùng để lời
gọi hàm này thành công.
 IPC_RMID: Xóa hàng đợi tin nhắn được chỉ định bởi đối số msqid.

d. Gửi và nhận thông điệp:
Hàm msgsnd() và msgrcv() gửi và nhận tin nhắn tương ứng:
int msgsnd(int msqid, const void *msgp, size_t msgsz,
int msgflg);
int msgrcv(int msqid, void *msgp, size_t msgsz, long
msgtyp,int msgflg);
Đối số msqid phải là ID của hàng đợi thông điệp hiện có.
Đối số msgp là một con trỏ trỏ đến một cấu trúc chứa kiểu tin nhắn và văn bản của
nó.
Đối số msgsz chỉ định chiều dài của thông điệp theo byte.

Trịnh Minh An – 14T2

9


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

Cấu trúc thành viên msgtyp là kiểu thông điệp nhận được theo quy định của quá
trình gửi.
Đối số msgflg chỉ định hành động cần thực hiện nếu một hoặc nhiều điều sau đây
là đúng:
 Số byte đã có trên hàng đợi bằng msg_qbytes.
 Tổng số tin nhắn trên tất cả các hàng đợi trên toàn hệ thống bằng với giới
hạn do hệ thống áp đặt.
Những hành động này như sau:
 Nếu ( msgflg & IPC_NOWAIT ) khác 0, tin nhắn sẽ không được gửi và
quá trình gọi sẽ trở lại ngay lập tức.
 Nếu ( msgflg & IPC_NOWAIT ) bằng 0, quá trình gọi sẽ tạm ngừng thực
hiện cho đến khi một trong những điều sau xảy ra:
o Điều kiện chịu trách nhiệm cho việc tạm ngưng không còn tồn tại,
trong trường hợp này, tin nhắn được gửi đi.
o Mã nhận dạng hàng đợi tin nhắn msqid bị xóa khỏi hệ thống; khi
điều này xảy ra, errno được đặt bằng EIDRM và -1 được trả về.
o Quá trình gọi sẽ nhận được tín hiệu bị bắt; trong trường hợp này, tin
nhắn không được gửi đi và quá trình gọi lại tiếp tục thực hiện.
Sau khi hoàn tất thành công, các hành động sau đây được thực hiện đối với cấu
trúc dữ liệu được liên kết với msqid:
 msg_qnum được tăng thêm 1.
 msg_lspid được đặt bằng ID tiến trình của quá trình gọi.
 msg_stime được đặt bằng thời gian hiện tại.

Trịnh Minh An – 14T2

10


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

CHƯƠNG 2: PHÂN TÍCH THIẾT KẾ
1. MÔ HÌNH CÀI ĐẶT THUẬT TOÁN
1.1. Ý tưởng
 Chương trình gồm có:
o 2 tiến trình writer và reader
o 2 file: input(chứa dữ liệu đầu vào) và output(chứa dữ liệu đầu ra)
 Trình từ thực hiện của từng tiến trình
Tiến trình 1(writer)

Tiến trình 2(reader)

Khai báo cấu trúc cho MessageQue

Khai báo cấu trúc cho MessageQue
giống với tiến trình 1

Đăng ký MessageQueue với khóa thứ
nhất để gửi dữ liệu lên

Đăng ký MessageQueue với khóa mà
tiến trình 1 đã đăng ký

Đọc file input lấy từng dòng dữ
Lấy dữ liệu từ MessageQueue mà tiến
liệu(Gồm toán tử và toán hạng) sau đó
trình 1 gửi lên, sau đó sử dụng thuật toán
gửi từng dòng dữ liệu lên MessageQueue
ký pháp Ba Lan(Prefix/Postfix) xử lý
từng dòng thông điệp lấy kết quả và gửi
với ID đã đăng ký
lại lên MessageQueue
Lấy dữ liệu đã được xử lý từ tiến trình 1
về từ MessageQueue sau đó ghi ra file
output

Đóng tiến trình

Đóng tiến trình
 Sau khi tiến trình 1(writer) đọc dữ liệu từ input và gửi lên MessageQueue ta sử
dụng hàm fork() để tạo ra một tiến trình con. Và ở tiến trình con này ta gọi
thực thi tiến trình 2(reader) để xử lý. Sau khi kết thực tiến trình con ta tiếp tục
thực hiện các công việc còn lại của tiến trình 1(writer).
1.2. Thuật toán ký pháp Ba Lan
Ký pháp Ba Lan được nhà toán học Jan Lukasiewicz đề xuất vào năm 1920.
Đây là thuật toán biểu diễn biểu thức bằng cách đặt các toán tử lên phía trước (ví
dụ như a + b sẽ thành + a b). Đây được gọi là Biểu thức tiền tố (Prefix). Khác
hẳn với biểu thức thông thường ta được học (Biểu thức trung tố – infix), Prefix
loại bỏ hoàn toàn các dấu ngoặc ( ), giảm bớt được độ phiền nhiễu của thứ tự các
phép toán.

Trịnh Minh An – 14T2

11


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

Trái ngược lại với Prefix là Biểu thức hậu tố (Postfix). Nếu Prefix biểu
diễn toán tử phía trước các toán hạng, thì Postfix sẽ biểu diễn đằng sau (a +
b thành a b +). Postfix được nhà khoa học máy tính Charles Hamblin phát minh
vào năm 1950, trước đó sử dụng tên gọi là RPN (Reverse Polish Notation). Thuật
toán như sau: Ta cho vòng lặp chạy hết chuỗi:
 Nếu là số hạng, ta Push vào mảng Output
 Nếu là toán tử:
o Thực viện vòng lặp kiểm tra, nếu ở đỉnh Stack là toán tử, mà nó có độ
ưu tiên lớn hơn hoặc bằng toán tử hiện tại thì ta lấy toán tử đó ra (Pop)
khỏi mảng Stack và Push vào mảng Output.
o Push toán tử hiện tại vào mảng Stack.
 Nếu là dấu “(“: ta Push vào mảng Stack
 Nếu là dấu “)”: Pop các phần tử trong Stack và add vào mảng Output cho đến
khi gặp dấu “(” (tất nhiên cũng phải Pop “(”).
Hoàn tất vòng lặp, nếu vẫn còn phần tử trong Stack thì ta lần lượt Pop các phần tử
đó trong mảng Stack và Push vào Output. Ví dụ minh họa:
Chuyển đổi biểu thức 5.5/2 + 3*(4/8 – 2) sang Postfix

Trịnh Minh An – 14T2

12


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

CHƯƠNG 3: TRIỂN KHAI VÀ DEMO

File input.txt chứa dữ liệu đầu vào

Thực thi tiến trình writer

Trịnh Minh An – 14T2

13


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

File output.txt chứa kết quả sau khi thực thi tiến trình
CHƯƠNG 4: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
1. NHỮNG KẾT QUẢ ĐẠT ĐƯỢC
- Hiểu được như thế nào là tiến trình trong Linux
- Nắm bắt được các trạng thái của tiến trình, cách xử lý các tiến trình bằng hàm
System(), giao tiếp giữa các tiến trình bằng hàng đợi thông điệp.
- Biết cách tạo ra tiến trình con(đa tiến trình) bằng cách sử dụng hàm fork().
- Nắm bắt được thuật toán ký pháp Ba Lan
2. HƯỚNG PHÁT TRIỂN
- Xây dựng giao diện cho chương trình bắt mắt và trực quan hơn.

Trịnh Minh An – 14T2

14


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

PHẦN 2: LẬP TRÌNH MẠNG
TIÊU ĐỀ: TÌM HIỂU VỀ RMI. ỨNG DỤNG XÂY DỰNG CHƯƠNG TRÌNH
GIÁM SÁT HỆ THỐNG MẠNG LAN
CHƯƠNG 1: CƠ SỞ LÝ THUYẾT
1. TỔNG QUAN VỀ RMI( REMOTE INVOKE METHOD)
1.1. RMI là gì?
RMI là một công nghệ của các hệ thống phân tán cho phép một máy ảo
Java(JVM) gọi những phương thức của đối tượng nằm trên máy ảo Java khác ở trong
cũng một mạng.
RMI tạo ra các ứng dụng phân tán có độ tin cậy một cách rất dễ dàng nhưng chỉ là
cơ chế danh riêng cho ngono ngữ Java.
1.2. RMI làm việc như thế nào?
Các hệ thống sử dụng RMI cho việc truyền thông tiêu biểu được phân thành 2 loại:
Client và Server. Server cung cấp dịch vụ RMI và Client gọi các phương thức do
Server cung cấp. RMI Server phải đăng ký một dịch vụ tìm kiếm, cho phép các Client
tìm thấy thông tin Server cung cấp, hoặc chúng có thể tham chiếu tới dịch vụ khác.
Một ứng dụng chạy nền cho RMI có tên là rmiregistry. Ứng dụng này chạy và xử lý
độc lập với các chương trình RMI, nó cho phép các đối tượng trên Server đăng ký tên
của mình. Mỗi lần một đối tượng được đăng ký xong, nó sẽ đợi sau đó lời gọi từ phía
Client.

Nhiều dịch vụ đăng ký với một bộ đăng ký
Các đối tượng trên Client sẽ gửi nhưng thông điệp tới nhưng phương thức ở xa.
Trước khi một phương thức ở xa được thực thi Client phải có tham chiếu của nó trên
Server. Điều đó được thực hiện bởi một dịch vụ tìm kiếm trong bộ đăng ký RMI. Đối

Trịnh Minh An – 14T2

15


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

tượng trên Client yêu cầu một tên dịch vụ và sẽ nhận được một URL. Nên nhớ nhưng
URL không phải cho HTTP, hầu hết các giao thức có thể đại diện sử dụng các cú
pháp của URL. Định dạng được sử dụng bởi RMI để đại diện cho một đối tượng tham
chiếu từ xa như sau:
rmi://hostname:port/servicename

Đối tượng stub gọi đối tượng skeletion.
Trong đó hostname tên của Server hoặc địa chỉ IP của Server, port số hiệu của
cổng cung cấp dịch vụ, servicename là một chuỗi mô tả dịch vụ. Những thông tin chi
tiết của hoạt động mạng thì luôn trong suốt với người phát triển ứng dụng khi làm
việc với các đối tượng ở xa, việc đó trở nên đơn giản như khi làm việc với đối tượng
tại máy cục bộ. Điều này được thực hiện nhơ một phép chia thông minh của hệ thộng
RMI thành 2 thành phần, một là stub và một là skeleton.
Tại RMI Server, đối tượng skeleton có nhiệm vụ lắng nghe những yêu cầu và
chuyển các yêu cầu đó tới dịch vụ RMI. Sau khi người phát triển tạo ra một giao diện
RMI, người đó còn phải định nghĩa cụ thể giao diện đó. Đối tượng được định nghĩa
này sẽ được gọi là đối tượng skeleton.
1.3. Kiến trúc của chương trình RMI
Kiến trúc của một chương trình theo cơ chế RMI được mô tả như hình sau:

Kiến trúc của chương trình RMI

Trịnh Minh An – 14T2

16


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

Trong đó:
 Server là chương trình cung cấp đối tượng có thể được gọi từ xa.
 Client là chương trình có tham chiếu đến các phương thức của các đối tương ở
xa trên Server.
 Stub chứa các tham chiếu đến các phương thức ở xa trên Server.
 Skeleton đón nhận các tham chiếu từ Stub để kích hoạt phương thức tương ứng
trên Server.
 Remote Reference Layer là hệ thống truyền thông của RMI.
 Transport là tầng giao vận được dựa trên giao thức TCP/IP giữa các máy trong
mạng.
Bằng cách sử dụng kiến trúc phân tầng như trên mà mỗi tầng có thể phân cấp hoặc
thay thế mà không ảnh hưởng tới các tầng còn lại của hệ thống.
1.4. Lớp Stub và Skeleton trong truyền tin với RMI

Stub: (dùng ở phía Client) một đối tượng ủy quyền, truyền tải yêu cầu đối tượng
tới server RMI.
Người phát triển không cần quan tâm đến tài nguyên RMI nằm ở đâu, nó đang
chạy trên nền nào, nó đáp ứng đầy đủ yêu cầu như thế nào
Client RMI gọi một phương thức ở Server dựa trên một đối tượng ủy quyền.
Skeleton: (Dùng ở phía Server) Skeleton không cung cấp bản cài đặt của dịch vụ
RMI. Nó chỉ đóng vai trò như là chương trình nhận các yêu cầu, và truyền các yêu
cầu.
 JAVA sử dụng rmic.exe để tạo ra các lớp trung gian này.

Trịnh Minh An – 14T2

17


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

Giao tiếp giữa các lớp Stub và skeleton trong RMI

1.5. Các cơ chế liên quan trong một ứng dụng RMI
Trong một ứng dụng phân tán cần có các cơ chế sau:
 Cơ chế định vị đối tượng ở xa(Lacate remote object).
 Cơ chế giao tiếp với các đối tượng ở xa(Communicate with remote object).
 Tải các lớp danh bytecodes cho các lớp mà nó được chuyển tải qua lại giữa các
máy ảo(Load class bytecodes for object that are passed around).

Trịnh Minh An – 14T2

18


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

Dịch vụ ánh xạ tên của RMI
Trong đó:
 Server đăng ký (bind) cho đối tượng có thể được gọi từ xa của mình với
dịch vụ ánh xạ tên (Registry Server).
 Client tìm đối tượng ở xa thông qua tên đã đăng ký trên Registry Server
(lookup) và tiếp đó gọi các phương thức ở xa.
2. CƠ CHẾ THỰC THI CỦA MỘT ỨNG DỤNG RMI
2.1. Tiến trình thực thi của ứng dụng RMI
 Bước 0: Server tạo các đối tượng cho phép gọi từ xa cùng với Stub và Skeleton
của chúng.
 Bước 1: Server sử dụng lớp Naming để đăng ký tên cho một đối tượng từ xa.
 Bước 2: Naming đăng ký Stub của đối tượng từ xa với Registry Server.
 Bước 3: Registry Server sẵn sang cung cấp tham chiếu đến đối tượng từ xa khi
có yêu cầu.
 Bước 4: Client yêu cầu Naming định vị đối tượng ở xa thông qua tên đã được
đăng ký(phương thức lookup) với dịch vụ tên.
 Bước 5: Naming tải Stub của đối tượng ở xa từ dịch vụ tên mà đối tượng đã
đăng ký về Client.
 Bước 6: Cài đặt đối tượng Stub và trả về tham chiếu đối tượng ở xa cho Client.
 Bước 7: Client thực thi một lời gọi phương thức ở xa thông qua đối tượng Stub

Trịnh Minh An – 14T2

19


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

Tiến trình thực thi của ứng dụng RMI
2.2. Các bước phát triển và triển khai ứng dụng RMI
1) Định nghĩa một giao diện remote
2) Phát triển đối tượng remote, đối tượng này thực thi giao diện remote.
3) Phát triển chương trình Client.
4) Biên dịch source codes.
5) Tạo các client stubs và các server skeletons
6) Khởi động RMI registry
7) Khời động các đối tượng server remote
8) Chạy chương trình Client

Trịnh Minh An – 14T2

20


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

CHƯƠNG 2: PHÂN TÍCH THIẾT KẾ
1. PHÂN TÍCH KIẾN TRÚC HỆ THỐNG
2. THIẾT KẾ HỆ THỐNG
2.1. Sơ đồ Usecase
2.2. Sơ đồ lớp

Sơ đồ lớp
2.3. Thiết kế Database
2.3.1. Khu vực(Zone)

Hình 1: Bảng Khu vực(Zone)
2.3.2. Phòng máy(Lab)

Hình 2: Bảng Phòng máy(Lab)
2.3.3. Computer

Bảng máy tính(Computer)

Trịnh Minh An – 14T2

21


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

CHƯƠNG 3: TRIỂN KHAI
1. MÔI TRƯỜNG CÀI ĐẶT
1.1. Ngôn ngữ: Java RMI
1.2. Database: MySQL
1.3. Công cụ hỗ trợ: Eclipse, Netbean
2. KẾT QUẢ THỰC HIỆN CÁC CHỨC NĂNG
 Khời động Server:

 Khởi động giao diện Client:

Trịnh Minh An – 14T2

22


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

CHƯƠNG 4: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
1. NHỮNG KẾT QUẢ ĐẠT ĐƯỢC
- Nắm được như thế nào là lập trình phân tán.
- Phương thức triệu gọi từ xa, vai trò các lớp trung gian(Stub và Skeleton)
- Cài đặt ứng dụng phân tán RMI ứng dụng vào xây dựng chương trình giám sát hệ
thống mạng LAN.
2. HƯỚNG PHÁT TRIỂN
- Xây dựng giao diện cho chương trình bắt mắt và trực quan hơn.

Trịnh Minh An – 14T2

23


Đồ án cơ sở ngành mạng

GVHD: Ths. Nguyễn Văn Nguyên

TÀI LIỆU THAM KHẢO
1. Bài giảng môn học “Lập Trình Mạng” – Thầy Mai Văn Hà
2. TS. Lê Văn Sơn - Hệ tin học phân tán - Nhà xuất bản Đại học quốc gia Thành phố
Hồ Chí Minh - 2002.
3. Nguyễn Bá Hùng, Nguyễn Huy Công, Giáo trình lập trình mạng và truyền thông

Trịnh Minh An – 14T2

24


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay

×

×