TÓM TẮT NỘI DUNG ĐỒ ÁN
Đồ án này bao gồm năm chương. Nội dung trình bày mỗi chương được tóm tắt như sau:
- Chương I: Giới thiệu tổng quan về đề tài. Giới thiệu hiện trạng sử dụng hệ điều hành Linux, khả năng giao tiếp giữa các máy qua mạng Linux và đặt vấn đề cần giải quyết của đề tài.
- Chương II: Trình bày các cơ sở lý thuyết có liên quan đến đồ án như ngôn ngữ C, ngôn ngữ tcl/tk và khả năng xây dựng ứng dụng mạng.
- Chương III: Xây dựng hệ thống chatting bao gồm chương trình server bằng ngôn ngữ C sử dụng đa tiến trình và chương trình client bằng ngôn ngữ tcl/tk trên X Window. Đặt vấn đề giao tiếp giưac hai chương trình.
- Chương IV: Thử nghiệm chương trình trên các máy sử dụng Linux.
- Chương V: Kết luận. Nêu các vấn đề đã đạt được trên lý thuyết, tính khả thi và hương phát triển đề tài.
MỤC LỤC
MỤC LỤC 7
TỔNG QUAN ĐỀ TÀI 9
I. Hệ điều hành Linux 9
II. Giao tiếp giữa các máy có sử dụng hệ điều hành Linux 9
II.1.Giới thiệu một số tiện ích giao tiếp qua mạng Linux 10
a) Lệnh gọi hệ thống talk 10
b) Lệnh gọi hệ thống mail 10
III. Giới thiệu nội dung đề tài 10
CƠ SỞ LÝ THUYẾT 12
I. Ngôn ngữ C 12
I.1. Giới thiệu sơ lược 12
I.1.1. Lập trình C trên Linux 12
I.1.2. Một chương trình C đơn giản 12
I.1.3. Biên dịch và thực hiện chương trình 13
I.2.Quản lý đa tiến trình bằng ngôn ngữ C 14
I.2.1. Tiến trình và đa tiến trình 14
a) Khái niệm tiến trình 14
b) Trạng thái của các tiến trình 15
I.2.2. Các dấu hiệu nhận biết tiến trình 15
I.2.3. Tạo ra một tiến trình 16
I.2.4. Chấm dứt một tiến trình 16
I.3. Trao đổi thông tin giữa các tiến trình 17
I.3.1. Liên lạc bằng các tín hiệu 17
a) Khái niệm 17
b) Một số tín hiệu thường gặp 18
c) Liên lạc bằng các tín hiệu 18
d) Một số giới hạn khi sử dụng tín hiệu 20
I.3.2. Liên lạc bằng ống dẫn 20
a) Khái niệm 20
b) Các đặc điểm của ống dẫn 21
c) Khởi tạo và liên lạc bằng ống dẫn 21
I.3.3. Trao đổi thông tin giữa các tiến trình bằng hệ thống IPC 24
a) Khái niệm 24
b) Khởi tạo dãy thông báo 25
c) Gởi thông tin lên dãy thông báo 26
d) Nhận thông tin từ dãy thông báo 27
I.4. Giao tiếp mạng 29
I.4.1. Khái niệm socket và port 29
I.4.2. Tạo ra một socket 29
I.4.3. Chờ đợi một kết nối từ client(server) 31
I.4.4. Thực hiện kết nối đến server (client) 32
I.4.5. Ví dụ mẫu mô hình client/server 33
a) Mã lệnh chương trình server 33
b) Mã lệnh chương trình client 34
II. Ngôn ngữ tcl/tk 36
II.1.Khái niệm 36
II.1.1. Khái niệm 36
II.1.2. Các thành phần cơ bản của tcl/tk 36
a) Cấu trúc lệnh 36
b) Biến và giá trị của biến 37
c) Các cấu trúc lặp 38
d) Chương trình con 39
II.2. Một chương trình đơn giản bằng tcl/tk 39
II.2.1. Cấu trúc chương trình 39
II.2.2. Thực hiện chương trình 40
II.3. Sử dụng socket trong tcl/tk 40
XÂY DỰNG MÔ HÌNH CLIENT/SERVER 42
I. Xây dựng chương trình sever 42
I.1. Nguyên tắc hoạt động 42
I.2. Sơ đồ thuật toán thành phầnchờ đợi kết nối 43
I.2.1. Khởi tạo socket 43
I.2.2. Khởi tạo dãy thông báo 44
I.2.3. Đợi một kết nối từ client 45
I.3. Sơ đồ thuật toán thành phần xử lý thông tin trao đổi 46
I.3.1. Phân tích tham số đầu vào 47
I.3.2. Khởi tạo socket và tìm kiếm dãy thông báo 47
I.3.3. Đợi một kết nối từ client 47
I.3.4. Thực hiện trao đổi thông tin 47
I.4. Cấu trúc dữ liệu 47
I.5. Cổng giao tiếp với các client: 48
I.6. Quản lý trao đổi thông tin 49
II. Chương trình client 50
II.1. Nguyên tắc hoạt động 50
II.2 Sơ đồ thuật toán 51
II.3 Thiết lập kết nối đến chương trình server 51
II.4 Phân loại thông tin nhận được từ máy chủ 52
CHƯƠNG IV 53
THỬ NGHIỆM CHƯƠNG TRÌNH 53
I. Trình tự sử dụng chương trình 53
II. 53
III. Kết quả 53
KẾT LUẬN 54
I. Kết quả đạt được 54
I.1.Chương trình server 54
I.2. Chương trình client 54
I.3. Tính khả thi 54
II. Hạn chế 54
III. Hướng phát triển đề tài 55
TÀI LIỆU THAM KHẢO 56
CHƯƠNG 1
TỔNG QUAN ĐỀ TÀI
I. Hệ điều hành Linux
Hệ điều hành Linux bắt đầu phát triển từ năm 1991. Tác giả ban đầu của hệ điều hành này là một sinh viên trường đại học tổng hợp Helsinki, Linus B. Torvalds. Linux là từ viết tắt của Linus (tên tác giả) và Unix. Phiên bản đầu tiên của Linux gọi là phiên bản 0.01 được phát hành vào tháng 8 năm 1991.
Hiện nay, tại phòng thực hành số 1 trường đại học kỹ thuật Đà Nẵng có cài đặt hệ điều hành Linux để các sinh viên chuyên ngành Tin học cũng như các ngành khác có thể tiếp cận và học hỏi trên hệ điều hành này. Ngoài ra, hệ điều hành Linux đã được đưa vào chương trình học của sinh viên chuyên ngành thành một môn bắt buộc. Điều này sẽ giúp cho sinh viên có được cái nhìn tổng quát hơn về hệ điều hành, có đièu kiện đánh gía và so sánh với hệ điều hành đang được sử dụng phổ biến MS DOS và Microsoft Windows.
Đưa hệ điều hành Linux vào giảng dạy và nghiên cứu sẽ mở ra thêm một hướng đi mới cho sinh viên chuyên ngành. Cuộc chiến thị phần giữa các hệ điều hành có đi đến kết cuộc như thế nào thì việc biết thêm một hệ điều hành, lập trình được trên đó sẽ làm vững tin hơn cho các sinh viên sau khi tốt nghiệp.
Về phía sinh viên, Microsoft Windows là hệ điều hành rất thân thiện với người sử dụng và từ lâu nay đã được sử dụng rất nhiều. Microsoft Windows có khả năng nối mạng cùng chung hệ điều hành rất dể dàng. Vậy đối với Linux thì sao? Khi đã có được hệ thống mạng dùng Linux thì việc giao tiếp giữa các máy Linux với nhau có gì khác với hệ điều hành Microsoft Windows.
II. Giao tiếp giữa các máy có sử dụng hệ điều hành Linux
Hệ điều hành Linux được thừa kế Unix nên có rất nhiều tính năng mạnh về mạng máy tính và giao tiếp giữa các máy trong mạng, thậm chí chúng được cụ thể hóa bằng các lệnh gọi hệ thống, hay nói ngắn gọn hơn: chỉ là các thao tác đơn giản. Với các lệnh gọi hệ thống này có thể được dùng để trao đổi một số thông tin đơn giản giữa các user hay giữa hai máy với nhau như lệnh talk, mail, write,
II.1. Giới thiệu một số tiện ích giao tiếp qua mạng Linux
a) Lệnh gọi hệ thống talk
Lệnh gọi hệ thống talk cho phép hai user đang đăng nhập có thể trao đổi thông tin trực tiếp với nhau. Lệnh talk được gọi với tham số là một user khác đang tồn tại trong hệ thống. Sau đó, màn hình hệ thống được chia làm hai phần, phần dưới dành hiễn thị các dòng thông báo của user đối thoại và phần trên dành cho người đang sử dụng. Nếu user chưa đăng nhập, talk sẽ thông báo lỗi về việc user không tồn tại và trở lại dấu nhắc của shell.
Một khi sử dụng lệnh gọi hệ thống talk, tất cả những gì chúng ta gõ vào đều được hiễn thị ở user kia. Tuy nhiên chúng ta không thể làm gì khác cho đến khi thoát khỏi talk. Một điều quan trọng là talk chỉ cho phép hai trao đổi giữa hai user.
b) Lệnh gọi hệ thống mail
Lệnh mail cho phép chúng ta gởi các đoạn nhắn đến các user trên máy tính hoặc các user trên mạng nếu chúng ta biết tên miền của user đó. So với talk, sử dụng mail linh hoạt hơn nhưng thông tin trao đổi không mang tính tức thời. Chúng ta có thể kiểm tra mail và trả lời bất kỳ khi nào chúng ta muốn dẫn đến thông tin sẽ không cập nhật kịp thời. Khó khăn lớn nhất của mail là chúng la luôn phải nhớ chính xác tên user và tên miền của đích đến.
III. Giới thiệu nội dung đề tài
Linux là hệ điều hành đa nhiệm, đa người sử dụng, Một người bất kỳ cũng có thể hiểu được các khái niệm trên một khi họ đã đọc lướt qua một quyển sách, một tờ báo nào đó có nói đến Linux hay Unix chẳng hạn. Vậy chúng ta phải nhắc đến điều gì trong khi đó là những đặc trưng của Linux ?
Đối với một sinh viên chuyên ngành tin học chúng ta không thể đánh giá vấn đề theo hướng " Nó là gì ?" mà phải biết nhận xét "Nó làm việc như thế nào ?" và quan trọng hơn có thể là " Làm thế nào để sử dụng nó như công cụ của mình ?". Từ đó chúng ta thử quay lại với các khái niệm trên với một số vấn đề đặt ra:
- Linux quản lý hệ thống bằng cách quản lý các tiến trình. Nếu chúng ta có một chương trình có sử dụng đa tiến trình thì chúng ta sẽ quản lý chúng như thế nào?
- Linux đã cung cấp một số lệnh gọi hệ thống cho phép truyền thông (có hạn chế) trên mạng liệu có hỗ trợ cho chúng ta lập trình trên mạng dể dàng hay không?
Nói tóm lại, vấn đề đặt ra ở đây không phải là chúng ta sử dụng Linux mà là chúng ta tận dụng các đặc trưng của hệ điều hành để ứng dụng chúng vào việc lập trình trên hệ điều hành này.
Từ những hạn chế của một số lệnh kể trên, các tính năng của một hệ đa tiến trình tôi đã nảy ra ý tưởng xây dựng một chương trình cho phép các máy sử dụng Linux (có thể cả MS Windows) có thể giao tiếp với nhau cùng một lúc, qua đó các sinh viên có thể sử dụng máy để trao đổi trực tiếp các thông tin tức thời cho nhau. Ngoài ra có thêm một chương trình để tham khảo khi bắt đầu lập trình trên Linux và X Window cũng tốt.
Tôi đã dựa theo ý tưởng này để đưa ra quyết định chọn đề tài "LẬP TRÌNH ĐA TIẾN TRÌNH XÂY DỰNG CHƯƠNG TRÌNH CHATTING TRÊN MẠNG LINUX" làm đề tài tốt nghiệp của mình. Mô hình chatting gồm có hai chương trình, một chương trình phục vụ (server) và một chương trình khách (client).
+ Chương trình server là một chương trình được viết bằng ngôn ngữ C sử dụng đa tiến trình, trao đổi thông tin giữa các tiến trình và giao tiếp với các chương trình client qua mạng. Chương trình server có hai thành phần chính, một thành phần luôn chờ đợi các kết nối của các chương trình client từ máy trạm và một thành phần tạo ra một tiến trình mới mỗi khi có một client kết nối đến. Tiến trình mới này trực tiếp trao đổi thông tin với chương trình client vừa kết nối.
+ Chương trình client được xây dựng bằng ngôn ngữ tcl/tk, một ngôn ngữ thông dịch, tạo giao diện với người sử dụng trên X Window. Chương trình này sử dụng các giao tiếp qua mạng để truyền và nhận thông tin với các chương trình client khác qua chương trình server.
54 trang |
Chia sẻ: lvcdongnoi | Lượt xem: 2908 | Lượt tải: 1
Bạn đang xem trước 20 trang tài liệu Đề tài Lập trình đa tiến trình xây dựng chương trình chatting trên mạng linux, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
û xaïo träün khi tiãún trçnh xæí lyï xong tên hiãûu vaì quay tråí laûi våïi cäng viãûc træïc âoï. Mäüt âiãöu khäng âæåüc mong muäún trong liãn laûc.
Liãn laûc bàòng äúng dáùn
Khaïi niãûm
ÄÚng dáùn laì mäüt cå chãú cå baín âãø liãn laûc giaïn tiãún giæîa caïc tiãún trçnh. Âoï laì caïc táûp tin FIFO âàûc biãût (vaìo træåïc ra træåïc), åí âoï thäng tçn âæåüc truyãön vaìo mäüt hæåïng vaì âæåüc láúy ra åí mäüt hæåïng khaïc.
Tiãún trçnh A
Tiãún trçnh B
Så âäö mä taí hoaût âäüng cuía äúng dáùn
Tiãún trçnh A vaì B phaíi coï mäúi quan hãû hoü haìng
Caïc âàûc âiãøm cuía äúng dáùn
Caïc äúng dáùn liãn laûc laì khäng coï tãn nãn chuïng chè mang tênh cháút taûm thåìi. Chuïng täön taûi trong thåìi gian thæûc hiãûn cuía tiãún trçnh taûo ra chuïng.
Viãûc taûo ra äúng dáùn phaíi duìng mäüt haìm âàûc biãût pipe (chuïng ta seî xeït âãún pháön sau).
Nhiãöu tiãún trçnh coï thãø cuìng ghi âoüc âäöng thåìi trãn mäüt äúng dáùn nhæîng laûi khäng coï cå chãú phán biãût caïc thäng tin åí âáöu ra, chuïng laì nhæ nhau.
Dung læåüng äúng daîn bë haûn chãú (vaìo khoaíng 4096 byte). Nãúu ta tiãúp tuûc ghi vaìo mäüt äúng dáùn âaî âáöy seî xaíy ra hiãûn tæåüng tàõc ngheîn thäng tin trong äúng.
Caïc tiãún trçnh liãn laûc qua äúng dáùn phaíi coï mäúi quan hãû hoü haìng (cha con . .con) vaì caïc äúng dáùn phaíi âæåüc taûo ra træåïc khi taûo ra mäüt tiãún trçnh con.
Khäng thãø tæû thay âäøi vë trê caïc thäng tin trong äúng.
Khåíi taûo vaì liãn laûc bàòng äúng dáùn
Âãø khåíi taûo mäüt äúng dáùn ta sæí duûng haìm pipe coï khai baïo nhæ sau:
int p_inf[2];
int pipe(p_inf);
Haìm traí vãö giaï trë 0 khäng nãúu khåíi taûo thaình cäng, nãúu gàûp läùi traí vãö giaï trë -1.
Haìm pipe sæí duûng mäüt âäúi säú laì mäüt baíng gäöm hai thaình pháön chênh laì p_inf[0] vaì p_inf[1]. Hai thaình pháön naìy chæïa bäü mä taí âáöu vaìo hay âáöu ra cuía thäng tin cho caïc tiãún trçnh sæí duûng noï.
p_inf[0] : Chæïa bäü mä taí âáöu ra cuía äúng dáùn.
p_inf[0] : Chæïa bäü mä taí âáöu vaìo cuía äúng dáùn.
Caïc äúng dáùn âæåüc quaín lyï thäúng nháút våïi hãû thäúng táûp tin. Viãûc truy xuáút âãún caïc äúng dáùn âæåüc thæûc hiãûn bàòng caïc bäü mä taí vaìo ra cuía äúng dáùn. Caïc thao taïc duìng âãø truy cáûp thäng tin cuía äúng dáùn âæåüc duìng bàòng caïc haìm nháûp xuáút chuáùn nhæ read, write, ..
Sau khi taûo ra äúng dáùn, sæí duûng äúng dáùn laìm phæång tiãûn truyãön thäng bàòng caïch taûo ra caïc tiãún trçnh con. Khi mäüt tiãún trçnh con âæåüc taûo ra, noï âæåüc thæìa kãú caí nhæîng thäng tin vãö caïc bäü mä taí vaìo ra cuía caïc äúng dáùn maì tiãún trçnh cha cuía noï âaî taûo ra. Tæì âoï mäüt tiãún trçnh con coï thãø sæí duûng äúng dáùn âãø truyãön thäng våïi tiãún trçnh âaî taûo ra noï. Âiãöu quan troüng laì thæûc hiãûn nhæîng thaotaïc naìy theo thæï tæû. Do âoï âãø truyãön thäng mäüt caïch chênh xaïc, caïc tiãún trçnh nãn choün mäüt hæåïng truyãön trãn äúng dáùn, mäüt tiãún trçnh chè âoüc vaì tiãún trçnh kia chè ghi trãn äúng dáùn. Caïc bäü mä taí khäng sæí duûng coï thãø âæåüc âoïng laûi bàòng haìm chuáùn close().
Dæåïi âáy laì mäüt vê duû cho viãûc truyãön thäng giæîa hai tiãún trçnh cha vaì tiãún trçnh con thäng qua äúng dáùn.
#include
#include
void tt_con(int number)
{
int fd;
int nread;
char text[100];
fd=number;
printf("Dau hieu mo ta la: %d\n", fd);
switch (nread=read(fd, text, sizeof(text))) {
case -1:
printf("Loi khi doc trong ong dan.");
case 0:
printf("Ong dan rong.");
default:
printf(" Co %d ky tu trong ong la: %s \n", nread, text);
}
}
/***********************************/
main()
{
int fd[2];
if (pipe(fd)== -1)
printf("Loi khoi tao ong dan.");
switch (fork()) {
case -1:
printf("Loi fork().");
case 0:
tt_con( fd[0] );
}
close(fd[0]);
if (write(fd[1], "Hello", 6) == -1)
printf("Loi ong dan.");
}
Kãút quaí cuía chæång trçnh máùu trãn:
Dau hieu mo ta la: 3
Co 6 ky tu tro ong laì: Hello
Qua chæång trçnh ngàõn trãn chuïng ta coï thãø hiãøu âæåüc nguyãn tàõc taûo ra mäüt äúng dáùn, kãút håüp äúng dáùn våïi viãûc taûo ra mäüt tiãún trçnh con vaì thæûc hiãûn trao âäøi thäng tin giæîa tiãún trçnh cha vaìtiãún trçnh con. ÅÍ âáy chuïng ta chè måïi xem xeït theo mäüt hæåïng, thäng tin truyãön tæì tiãún trçnh cha âãún tiãún trçnh con, ngoaìi ra chuïng ta coï thãø truyãön theo hai hæåïng trong äúng dáùn âaî taûo ra bàòng caïch âoüc trong p_inf[0] vaì ghi trong p_inf[1]. Âãø truyãön âæåüc theo hai huåïng âäüc láûp thç viãûc ghi vaì âoüc cuía hai tiãún trçnh phaíi diãùn ra tuáön tæû.
Vê duû trãn bàõt âáöu taûo mäüt äúng dáùn bàòng haìm pipe( p_inf ). Sau âoï chæång trçnh tiãúp tuûc taûo ra mäüt tiãún trçnh con bàòng haìm fork(). Luïc naìy chuïng ta âaî coï hai tiãún trçnh cha con vaì mäüt äúng dáùn maì caí hai tiãún trçnh âãöu coï quyãön truy cáûp. Tiãún trçnh con sau khi âæåüc taûo ra seî goüi haìm tt_con( int ), truyãön cho haìm bäü mä taí âoüc cuía äúng dáùn. Haìm tt_con(int) coï nhiãûm vuû âoüc thäng äúng dáùn vaì in näüi dung. Tiãún trçnh cha sau khi taûo ra tiãún trçnh con seî ghi vaìo äúng dáùn mäüt âoaûn thäng baïo vaì chåì âåüi tiãún trçnh con kãút thuïc.
So våïi viãûc liãn laûc giæîa caïc tiãún trçnh bàòng tên hiãûu, caïc tiãún trçnh âaî coï thãø sæí duûng caïc äúng dáùn âãø truyãön caïc thäng tin cho nhau mäüt caïc dãø daìng hån. Nhæng âäúi våïi mäüt hãû thäúng bao gäöm nhiãöu tiãún trçnh hoaût âäüng âäüc láûp thç tçnh phæïc taûp cuía caïc äúng dáùn seî khäng âaïp æïng âæåüc. Màût khaïc caïc äúng dáùn coï giåïi haûn vãö dung læåüng thäng tin vaì chè nhæîng tiãún trçnh coï quan hãû "hoü haìng" måïi coï quyãön truy cáûp âãún caïc äúng dáùn.
Trao âäøi thäng tin giæîa caïc tiãún trçnh bàòng hãû thäúng IPC
IPC: Inter Process Comunication (truyãön thäng âa tiãún trçnh).
Khaïi niãûm
Caïc IPC khäng chè cho pheïp trao âäøi vaì duìng chung dæî liãûu maì coìn cho pheïp âäöng bäü caïc tiãún trçnh. Caïc IPC bàõt âáöu âæåüc sæí duûng tæì phiãn baín System V cuía Unix. Ngaìy nay, caïc IPC âaî âæåüc sæí duûng trãn táút caí caïc hãû biãún âäøi cuía Unix. Caïc IPC cho pheïp xæí lyï táút caí caïc kiãøu dæî liãûu, gåíi dæû liãûu tæì tiãún trçnh naìy âãún tiãún trçnh khaïc hoàûc cho pheïp duìng chung dæî liãûu. Trong thæûc tãú, caïc IPC gäöm coï ba cå chãú:
+ Caïc daîy thäng baïo: Mäüt daîy thäng baïo coï thãø âæåüc xem nhæ laì mäüt häüp thæ. Âiãöu naìy coï nghéa laì nãúu coï quyãön truy cáûp cáön thiãút, mäüt trçnh æïng duûng coï thãø gåíi mäüt thäng baïo âãún âoï (säú, mäüt xáu chuäùi, hay tháûm chê caí näüi dung cuía mäüt cáúu truïc dæî liãûu, ...) vaì caïc trçnh æïng duûng khaïc coï thãø âoüc thäng baïo naìy.
+ Bäü nhåï duìng chung: Viãûc quaín lyï bäü nhåï duìng chung cho pheïp nhiãöu trçnh æïng duûng sæí duûng chung mäüt vuìng bäü nhåï. Thäng thæåìng khi mäüt vuìng bäü nhåï âæåüc cáúp phaït thç noï thuäüc vaìo mäüt tiãún trçnh vaì caïc tiãún trçnh khaïc âang laìm viãûc trãn hãû thäúng khäng thãø truy cáûp âãún vuìng nhåï naìy. Viãûc quaín lyï bäü nhåï duìng chung cho pheïp nhiãöu tiãún trçnh coï thãø truy cáûp âãn svuìng nhåï âãø âoüc hay ghi lã âoï.
+ Caïc dáúu hiãûu (semaphore): Caïc dáúu hiãûu giuïp khàõc mäüt trong nhæîng khoï khàn låïn nháút âäúi våïi mäüt hãû thäúng âa tiãún trçnh: âoï laì sæû âäüng bäü hoïa tiãún trçnh. Tháût váûy, nhiãöu tiãún trçnh cuìng hoaût âäüng vaìo mäüt thåìi âiãøm vaì coï thãø truy cáûp cuìng mäüt dæî liãûu. Âiãöu naìy coï thãø gáy ra nhæîng khoï khàn nháút âënh nhæ truy cáûp âäöng thåìi vaìo dæî liãûu, gáy tàõc ngheîn ...
Trong âäö aïn naìy chuïng ta chè xeït caïch sæí duûng caïc daîy thäng baïo âãø truyãön thäng giæîa caïc tiãún trçnh. Mäüt âàûc træng cuía caïc IPC laì màûc duì coï sæí duûng caïc táûp tin nhæng laûi khäng sæí duûng hãû thäúng quaín lyï tãûp. Khi mäüt IPC âæåüc taûo ra hay xæí lyï noï khäng âæåüc sæí duûng giäúng nhæ mäüt táûp tin, do âoï khäng sæí duûng caïc haìm vaìo ra chuáùn nhæ read, open, ...
Caïc IPC dæûa vaìo mäüt cå chãú quaín lyï âàûc biãût laì quaín lyï khoïa. Khoïa laì mäüt säú nháûn daûng cho mäüt IPC åí mæïc âäü hãû thäúng. Do âoï âãø taûo ra hay chè âãø truy cáûp mäüt IPC cuîng cáön phaíi biãút âãún khoïa cuía IPC âoï.
Khåíi taûo daîy thäng baïo
Nhæ âaî nãu trong pháön trãn, caïc IPC âæåüc quaín lyï dæûa vaìo mäüt cå chãú âàûc biãût laì quaí lyï khoïa. Do âoï træåïc tiãn chuïng ta phaíi taûo ra khoïa cho mäùi IPC træåïc khi sæí duûng âãún noï.
#include
key_t ftok(char *pathname, char prg);
Haìm traí vãö mäüt nháûn daûng cho IPC âæåüc taûo ra tæì file trong âäúi säú thæï nháút. Haìm trãn dæûa vaìo täø håüp caïc nháûn daûng file nhæ säú inode file, säú thiãút bë taûo ra file, kãút håüp våïi tham säú thæï hai laì mäüt kyï tæû âãø taûo ra mäüt khoïa âäüc nháút cho IPC.
Sau khi taûo khoïa cho IPC, tæì khoïa nháûn daûng væìa coï chuïng ta coìn âënh nghéa mäüt daîy thäng baïo træåïc khi sæí duûng chuïng.
Caïc daîy thäng baïo thæåìng âæåüc so saïnh våïi hãû thäúng caïc häüp thæ. Âiãöu naìy coï nghéa laì mäüt tiãún trçnh báút kyì coï quyãön truy cáûp daîy thäng baïo coï thãø gåíi lãn daîy thäng baïo caïc thäng tin cuía mçnh cáön tryãön vaì caïc tiãún trçnh khaïc seî truy cáûp âãún daîy thäng baïo âãø nháûn láúy thäng tin coï kiãøu maì tiãún trçnh âoï cáön theo thæï tæû âãún cuía thäng baïo.
Haìm khåíi taûo hoàûc tçm kiãúm mäüt daîy thäng baïo âæåüc âënh nghéa nhæ sau:
#include
#include
#include
int msgget(key_t key, int option);
Âäúi säú thæï nháút laì khoïa cuía daîy thäng baïo âaî täön taûi hay sàõp âæåüc taûo ra. Âäúi säú thæï hai laì sæû læûa choün giæîa caïc hàòng trong baíng sau:
TÃN HÀÒNG
GIAÏ TRË
IPC_CREAT
01000
IPC_EXCL
02000
Nãúu âäúi säú thæï hai coï giaï trë laì IPC_CREAT thç daîy thäng baïo seî âæåüc taûo ra. Nãúu âäúi säú coï giaï trë khaïc seî coï hai khaí nàng âæåüc thæûc hiãûn:
Nãúu khoïa chæa âæåüc sæí duûng båíi daîy thäng baïo naìo thç mäüt daîy thäng baïo seî âæåüc taûo ra cuìng våïi khoïa âæåüc truyãön. IPC_CREAT âæåüc xem laì ngáöm âënh.
Nãúu khoïa âang âæåüc sæí duûng båíi mäüt daîy thäng baïo khaïc. Luïc naìy hoàûc IPC_CREAT hoàûc IPC_EXCL âæåüc duìng laìm tham säú vaì tiãún trçnh coï thãø sæí duûng daîy thäng baïo âaî coï âãø ghi, âoüc caïc thäng baïo trãn daîy.
Haìm seî traí vãö dáúu hiãûu nháûn daûng daîy thäng baïo âãø tiãún trçnh sæí duûng khi cáön gåíi thäng tin lãn daîy thäng baïo hay tçm kiãúm thäng tin trãn âoï.
Gåíi thäng tin lãn daîy thäng baïo
Gåíi thäng tin lãn daîy thäng baïo hay goüi laì gåíi mäüt thäng baïo lãn daîy. Âãø gåíi thäng baïo lãn daîy, chuïng ta phaíi coï bäü nháûn daûng daîy thäng baïo do chuïng ta khåíi taûo hay sæí duûng mäüt daîy thäng baïo âaî coï sàôn tæì træåïc. Haìm msgsnd() sau âáy cho pheïp gåíi mäüt thäng baïo âãún daîy thäng baïo:
#include
#include
#include
int msgsnd(int msgid, struct msgbuf *msgp, int msgsize, int msgopt);
Âäúi säú thæï nháút laì nháûn daûng cuía daîy thäng baïo cáön gåíi âãún. Âäúi säú tiãúp theo chênh laì thäng baïo cáön gåíi. trong cáúu truïc cuía thäng baïo gäöm coï hai thaình pháön nhæ sau:
struct msgbuf {
long type; /*Kiãøu thäng baïo*/
char *msgtext; /*Caïc näüi dung thäng baïo*/
};
Thäng thæåìng chuïng ta khäng sæí duûng hoaìn toaìn nguyãn máùu theo cáúu truïc naìy âãø truyãön caïc thäng tin lãn daîy thäng baïo. Tuy nhiãn thaình pháön âáöu tiãn cuía cáúu truïc thäng baïo âæåüc truyãön phaíi laì mäüt træåìng kiãøu long vaì tiãúp sau âoï laì caïc näüi dung cuía thäng baïo. Chênh træåìng kiãøu long seî quy âënh kiãøu cuía thäng baïo trãn daîy, caïc tiãún trçnh seî càn cæï vaìo âáy âãø læûa choün caïc thäng baïo cáön thiãút.
Nãúu tuìy choün IPC_NOWAIT âæåüc truyãön cho âäúi säú msgopt thç khi daîy thäng baïo bë âáöy haìm váùn âæåüc thæûc hiãûn nhæng läùi EAGAIN âæåüc traí vãö. Sau âáy laì danh saïch caïc läùi coï thãø gàûp phaíi khi gåíi thäng baïo:
Läùi
YÏ nghéa
EAGAIN
Khäng thãø gåíi thäng baïo do daîy âaî âáöy vaì IPC_WAIT âaî xaïc láûp
EACCES
Khäng coï quyãön ghi lãn daîy thäng baïo
EFAULT
Âëa chè do msgp chè âãún khäng truy cáûp âæåüc
EIDRM
Daîy khäng coìn næîa
EINTR
Tiãún trçnh nháûn mäüt tên hiãûu laìm ngàõt quaï trçnh gåíi
EINVAL
Nháûn daûng daîy khäng âuïng
ENOMEM
Khäng âuí bäü nhåï.
Nháûn thäng tin tæì daîy thäng baïo
Haìm cho pheïp nháûn mäüt thäng baïo tæì daîy coï kiãøu xaïc âënh:
#include
#include
#include
int msgrcv(int msgid, struct msgbuf *msgp, int msgsize, long type, int msgflg);
Thäng baïo nhán âæåüc chæïa trong näüi dung bäü nhåï do msgp troí âãún. Vuìng nhåï coï cåí låïn nháút laì msgsize . Haìm naìy chè nháûn láúy thäng baïo coï kiãøu âæåïc xaïc âënh båíi type.
type = 0: Thäng baïo thæï nháút cuía daîy (cuí nháút) cho duì thuäüc loaûi naìo seî âæåüc âoüc ra.
type < 0: Thäng baïo âáöu tiãu coï kiãøu nhoí hån hoàûc bàòng trë tuyãût âäúicuía type seî âæåüc âoüc.
type > 0: Thäng baïo âáöu tiãn coï kiãøu chênh xaïc bàòng type âæåüc âoüc ra.
Træåìng msgflg coï hai giaï trë:
MSG_NOERROR: Nãúu kêch cåí thäng baïo låïn hån âäü räng do træåìng msgsize quy âënh thç thäng baïo seî bë càõt båït, pháön bë càõt seî máút âi. Nãúu khäng thäng baïo seî khäng âæåüc âæa ra khoíi daîy, lãûnh khäng thæûc hiãûn âæåüc vaì traí vãö läùi.
IPC_NOWAIT: Cho pheïp traïnh tçnh traûng chåì hoaût âäüng. Nãúu daîy träúng, seî coï läùi traí vãö. Nãúu khäng coï tuìy choün naìy, haìm seî chåì âåüi cho âãún khi coï thäng baïo phuì håüp yãu cáöu.
Caïc läùi coï thãø xaíy ra khi nháûn thäng baïo tæì daîy:
Läùi
YÏ nghéa
EINVAL
Bäü nháûn daûng daîy thäng baïo khäng âuïng, hoàûc msgsize ám hay låïn hån kêch thæåïc daîy quy âënh.
EFAULT
Vuìng bäü nhåï do msgp chè âãún khäng truy cáûp âæåüc.
EACCES
Tiãún trçnh khäng âuí quyãön truy cáûp daîy thäng baïo.
ENOMSG
Tuìy choün IPC_NOWAIT âaî xaïc láûp vaì khäng tçm tháúy thäng baïo trong daîy.
EINTR
Tiãún trçnh nháûn mäüt tên hiãûu ngàõt khi âang chåì mäüt thäng baïo.
Giao tiãúp maûng
Khaïi niãûm socket vaì port
Caïc socket âæåüc duìng trong láûp trçnh maûng âãø truy cáûp vaì truyãön thäng tin. Coï thãø hiãøu mäüt caïch khaïi quaït vãö socket nhæ cå cáúu truy cáûp file trãn Unix âæåüc cung cáúp cho mäüt âiãøm cuäúi cuía kãút näúi. Tæång tæû nhæ viãûc truy cáûp file, mäüt æïng duûng coï thãø yãu cáöu hãû thäúng cung cáúp mäüt socket khi noï cáön. Hãû âiãöu haình seî traí vãö mäüt säú nguyãn maì æïng duûng coï thãø thäng qua âoï truy cáûp âãún socket måïi âæåüc taûo ra theo yãu cáöu.
Háöu hãút caïc æïng duûng trãn maûng sæí duûng hai giao thæïc chênh laì: TCP (Transmission Control Protocol) hoàûc UDP (User Datagram Protocol). Caïc säú hiãûu cäøng daình cho caïc æïng duûng maûng seî âãø daìng cho hãû âiãöu haình biãút âæåüc caïc æïng duûng sæí duûng caïc taìi nguyãn hãû thäúng vaì caïc dëch vuû âæåüc pheïp nhæ thãú naìo.
Socket laì täø håüp cuía hai thaình pháön laì âëa chè IP cuía maïy tênh vaì säú hiãûu cäøng âæåüc sæí duûng båíi pháön mãöm duìng giao thæïc TCP. Båíi vç phaíi coï êt nháút hai maïy kãút näúi truyãön thäng trãn maûng, nãn phaíi coï mäüt socket cho caí maïy nháûn vaì maïy gåíi thäng tin. Âëa chè IP cuía mäùi maïy laì âån nháút vaì säú hiãûu cäøng laì mäüt säú âån nháút trãn mäùi maïy nãn socket cuîng laì âån nháút trãn maûng. Âiãöu naìy cho pheïp mäüt æïng duûng trao âäøi thäng tin våïi mäüt æïng duûng khaïc quan hãû thäúng maûng mäüt caïch troün veûn thäng qua socket.
Linux häù tråü caí hai caïch láûp trçnh våïi socket laì âënh hæåïng kãút näúi (connection oriented) vaì liãn laûc khäng kãút näúi (connectionless communication). Âäúi våïi liãn laûc âënh hæåïng kãút näúi, caí server vaì client phaíi thiãút láûp kãút näúi træåïc khi truyãön dæî liãûu. Âäúi våïi liãn laûc khäng kãút näúi, thç server vaì client khäng cáön thiãút láûp kãút näúi træåïc do âoï dæî liãûu âæåüc truyãön nhæ mäüt thaình pháön cuía caïc thäng baïo truyãön qua maûng. Tuy nhiãn trong caí hai caïch trãn thç server luän âæåüc khåíi âäüng træåïc, raìng buäüc noï vaìo mäüt socket vaì chåì âåüi mäüt kãút näúi âãún tæì client.
Taûo ra mäüt socket
Âãø taûo ra mäüt socket, chuïng ta sæí duûng haìm socket() âæåüc âënh nghéa nhæ sau:
#include
#include
int socket(int family, int type, int protocol);
Âäúi våïi hoü Unix, family coï giaï trë laì PF_UNIX, våïi hoü TCP/IP internet laì PF_INET, Xerox Corporation PUP internet laì PF_PUP hay våïi maûng Apple Computer Incorporated Appletalk laì PF_APPLETALK. Tham säú type coï mäüt trong hai giaï trë laì SOCK_STREAM daình cho mäüt kãút näúi coï tin cáûy cao nhæng ttäúc âäü truyãön thäng tháúp, hoàûc laì SOCK_DGRAM coï täúc âäü truyãön thäng cao hån nhæng âäü tin cáûy cuía kãút näúi tháúp hån. Riãng tham säú protocol thæåìng âæoüc quy âënh laì IPPROTO_TCP âäúi våïi SOCK_STREAM vaì IPPROTO_UDP cho giaï trë SOCK_DGRAM cuía tham säú thæï hai.
Haìm traí vãö giaï trë -1 nãúu khäng thãø taûo ra mäüt socket. Nãúu thaình cäng, giaï trë seî laì bäü mä taí socket. Chuïng ta seî sæí duûng bäü mä taí socket âãø tham chiãúu âãún socket væìa taûo ra cho táút caí caïc lãûnh coï sæí duûng socket tiãúp theo trong chæång trçnh.
Khi âæåüc khåíi taûo, mäüt socket chæa âæåüc liãn kãút våïi mäüt âëa chè cuûc bäü hay âëa chè âêch naìo caí. Âäúi våïi TCP/IP, âiãöu naìy coï nghéa laì chæa mäüt cäøng giao thæïc cuûc bäü naìo âæåüc gaïn vaì khäng coï mäüt cäøng âêch hay âëa chè IP cuû thãø. Mäüt khi coï socket âæåüc taûo ra, chæång trçnh server seî duìng haìm bind âãø âàût cho noï mäüt âë chè cuûc bäü. Haìm bind() âæåüc âënh nghéa nhæ sau:
#include
#include
int bind(int sockfd, struct sockaddr *saddr, int addrlen)
Tham säú âáöu tiãn laì bäü mä taí socket, tiãúp theo laì mäüt cáúu truïc chæïa âëa chè cuûc bäü vaì tham säú cuäúi laì âäü låïn cuía cáúu truïc træåïc âoï. Cáúu truïc sockaddr gäöm caïc thaình pháön:
typedef unsigned char u_char;
struct sockaddr{
u_char sa_len; /* Täøng âäü daìi cuía âëa chè */
u_char sa_family; /* doìng (family) cuía âëa chè */
char sa_data[14]; /* näüi dung âëa chè */
};
Træåìng sa_len chè âäü daìi cuía âëa chè, træåìng thæï hai sa_family chè ra âëa chè thuäüc vãö mäüt hoü giao thæïc cuû thãø (vê duû nhæ hàòng PF_INET âaûi diãûn cho TCP/IP). Thám säú cuäúi cuìng chæïa caïc byte näüi dung cuía âëa chè.
Mäùi hoü giao thæïc âãöu coï âënh nghéa mäüt caïch chênh xaïc âënh daûng cuía âëa chè sæí duûng trong træåìng sa_data cuía cáúu truïc sockaddr. Vê duû giao thæïc TCP/IP sæí duûng cáúu truïc sockaddr_in âãø âënh nghéa âëa chè nhæ sau:
struct sockaddr_in {
u_char sin_len;
u_char sin_family;
u_short sin_port; /* Cäøng säú cuía giao thæïc */
struct in_addr sin_addr; /* Âëa chè IP cuía maïy*/
char sin_zero[8]; /* khäng sæí duûng */
};
Trong cáúu truïc trãn, hai træåìng âáöu tiãn hoaìn toaìn giäúng cáúu truïc sockaddr, træåìng thæï ba chæïa cäøng giao thæïc daình cho æïng duûng, træåìng sin_addr chæïa âëa chè IP cuía maïy cuûc bäü. Cáúu truïc naìy coï træåìng sin_zero[8] khäng duìng âãún vç häü giao thæïc TCP/IP chè cáön saïu byte âãø chæïa âëa chè maïy vaì cäøng cho æïng duûng. Nhæ váûy âãø cáúu truïc naìy âäöng nháút kêch thæåïc våïi cáúu truïc sockaddr, cáön coï thãm taïm byte khäng sæí duûng.
Chåì âåüi mäüt kãút näúi tæì client(server)
Sau khi cuû thãø mäüt cäøng cho socket, chæång trçnh server phaíi cung cáúp cho hãû âiãöu haình chuyãøn socket vaìo chãú âäü thuû âäüng âãø coï thãø chåì âåüi mäüt tiãúp xuïc tæì mäüt chæång trçnh client. Chuïng ta duìng haìm listen âãø thæûc hiãûn bæåïc naìy. Haìm listen chè âæåüc goüi båíi chæång trçnh server.
#include
#include
int listen(int sockfd, int backlog);
sockfd laì bäü mä taí socket, backlog laì mäüt säú biãøu thë thåìi gian chåì âåüi mäüt kãút näúi træåïc khi loaûi boí. Haìm traí vãö giaï trë nhoí hån 1 nãúu gàûp läùi. Nãúu coï mäüt kãút näúi âãún trong thåìi gian chåì âåüi, luïc naìy chuïng ta seî chuyãøn sang bæåïc kãú tiãúp âãø thæûc hiãûn mäüt kãút näúi âãún client.
Haìm accept âæåüc server sæí duûng âãø nháûn láúy báút kyì thäng baïo naìo gåíi âãún tæì haìm connect() tæì chæång trçnh client.
#include
#include
int accept(int sockfd, struct sockaddr *peeraddr, int addrlen)
Caïc tham säú tæång tæû nhæ haìm bind() âaî xeït, tuy nhiãn peeraddr laì mäüt con troí chæïa thäng tin vãö maïy khaïch âaî coï yãu cáöu kãút näúi.
Thæûc hiãûn kãút näúi âãún server (client)
Âãø coï âæåüc mäüt kãút näúi âãún mäüt server âang åí chãú âäü chåì kãút näúi, thç træåïc hãút chæång trçnh client phaío taûo ra mäüt sock coï caïc thaình pháön tham säú giäúng nhæ socket maì server âaî raìng buäüc vaìo âoï. Sau âoï thæûc hiãûn haìm connect() mäüt khi chàõc chàõn ràòng server âang chåì âåüi kãút näúi âãún.
#include
#include
int connect(int sockfd, struct sockaddr *servsaddr, int addrlen)
Caïc tham säú tæång tæû trong haìm bind(). Ngoaûi træì con troí servsaddr våïi cáúu truïc struct sockaddr (thæûc cháút chuïng ta duìng struct sockaddr_in ) chæïa caïc thäng tin vãö chæång trçnh server taûi maïy chuí nhæ âëa chè IP, säú cäøng cuía giao thæïc, ...
Coï thãø noïi ngàõn goün ràòng haìm connect() laì mäüt cäng cuû âãø chæång trçnh client tiãúp xuïc våïi chuång trçnh server, gåíi caïc thäng tin cuía client âãún maïy chuí. Vaì chæång trçnh server traí låìi haình âäüng tiãúp xuïc naìy bàòng haìm accept() vaì sau âoï kãút näúi âæåüc thiãút láûp.
Sau khi kãút näúi âæåüc thiãút láûp, server vaì client coï thãø thæûc hiãûn viãûc trao âäøi thäng tin cho nhau cho âãún khi mäüt trong hai phêa âoïng kãút näúi bàòng haìm:
close(int socket);
hoàûc mäüt trong hai bãn bë ngàõt âäüt ngäüt båíi hãû thäúng.
Vê duû máùu mä hçnh client/server
Maî lãûnh chæång trçnh server
Trong vê duû dæåïi âáy chæång trçnh server thæûc hiãûn caïc bæåïc thiãút láûp cho viãûc chåì âåüi mäüt tiãúp xuïc tæì chæång trçnh client. Sau khi thiãút láûp kãút näúi våïi client, caí hai thæûc hiãûn mäüt säú thao taïc truyãön vaì nháûn thäng tin räöi kãút thuïc chæång trçnh.
Taûo ra mäüt socket våïi haìm socket().
Raìng buäüc sockket våïi mäüt âëa chè bàòng haìm bind().
Duìng haìm listen() âãø chåì âåüi mäüt kãút näúi.
Nháûn báút kyì thäng tin naìo yãu cáöu kãút näúi bàòng haìm accept().
Nháûn caïc thäng baïo gåíi âãún bàòng haìm read() vaì gåíi thäng baïo dãún client bàòng haìm write().
#include
#include
#include
#include
#define MY_PORT 6545
main(int argc, char *argv[ ])
{
int sockfd, newfd;
int cpid;
struct sockaddr_in servaddr;
struct sockaddr_in clientInfo;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0) < 0) {
myabort("Unable to create socket");
}
bzero((char *)&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_family = htons(MY_PORT);
if (bind(sockfd,(struct sockaddr *)&servaddr,sizeof(struct sockaddr))< 0)
{
myabort("Unable to bind socket");
}
listen(sockfd,5);
for (;;)
{
newfd=accept(sockfd,(struct sockaddr *)&clientInfo, sizeof(struct sockaddr);
if (newfd < 0) {
myabort("Unable to accept on socket");
}
if ((cpid = fork()) < 0) {
myabort("Unable to fork on accept");
}
else if (cpid = = 0) { /* child */
close(sockfd); /* no need for original */
do_your_thing(newfd);
exit(0);
}
close(newfd); /* in the parent */
}
}
Maî lãûnh chæång trçnh client
Tæì chæång trçnh client, âãø thæûc hiãûn âæåüc mäüt kãút näúi âãún server vaì truyãön nháûn thäng tin chè cáön thæûc hiãûn hai bæåïc cå baín nhæ sau:
Taûo mäüt socket tæång æïng våïi chæång trçnh server cuû thãø.
Yãu cáöu âãún server thæûc hiãûn kãút näúi bàòng caïch goüi haìm connect().
Nãúu mäüt kãút näúi âæåüc taûo ra, client coï thãø gåíi caïc yãu cáöu bàòng haìng write() vaì nháûn caïc häöi ám tråí laûi våïi haìm read().
Trong caí hai chæång trçnh naìy caïc haìm truyãön nháûn thäng tin chæa âæåüc thiãút kãú caïc lãûnh thaình pháön mäüt caïch cuû thãø, pháön naìy daình cho caïc baûn láûp trçnh cáön tçm hiãøu âãún.
#include
#include
#include
#include
#define MY_PORT 6545
#define MY_HOST_ADDR "204.25.13.1"
int getServerSocketId()
{
int fd, len;
struct sockaddr_in unix_addr;
/* create a Unix domain stream socket */
if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
return(-1);
}
/* fill socket address structure w/our address */
memset(&unix_addr, 0, sizeof(unix_addr));
unix_addr.sin_family = AF_INET;
/* convert internet address to binary value*/
unix_addr.sin_addr.s_addr = inet_addr(MY_HOST_ADDR);
unix_addr.sin_family = htons(MY_PORT);
if (bind(fd, (struct sockaddr *) &unix_addr, len) < 0)
return(-2);
memset(&unix_addr, 0, sizeof(unix_addr));
if (connect(fd, (struct sockaddr *) &unix_addr, len) < 0)
return(-3);
return(fd);
}
Ngän ngæî tcl/tk
Khaïi niãûm
Khaïi niãûm
tcl (tool command language) laì mäüt ngän ngæî thäng dëch âån giaíîn cuía låïp voî (shell) Linux. tk (toolkit) laì bäü cäng cuû sæí duûng cuï phaïp tcl taûo ra caïc giao diãûn ngæåìi sæí duûng bàòng âäö hoüa (GUI) håüp thaình tæì caïc thaình pháön nhæ caïc nuït báúm, thanh træåüt, häüp thoaûi, caïc cæía säø, ... Khi thæûc hiãûn mäüt chæång trçnh tcl thç tcl shell (tclsh) hoàûc windowing shell (wish) seî âæåüc goüi. Caí tclsh vaì wish âãöu laì nhæîng shell chuáùn cuía Linux, caí hai âãöu cho pheïp thæûc hiãûn lãûnh åí chãú âäü tæång taïc hoàûc âæåüc âoüc ra tæì mäüt táûp tin. Trong thæûc tãú, chãú âäü tæång taïc træûc tiãúp hiãúm khi âæåüc sæí duûng vaì khaí nàng cuía chãú âäü naìy ráút haûn chãú.
Tuy caí tclsh vaì wish âãöu coï thãø thæûc hiãûn mäüt chæång trçnh tcl, nhæîng giæîa chuïng coï âiãøm khaïc nhau cå baín laì tclsh chè coï thãø hiãøu caïc lãûnh tcl, trong khi wish coï thãø hiãøu caí caïc lãûnh tcl vaì tk.
Caïc thaình pháön cå baín cuía tcl/tk
Cáúu truïc lãûnh
Cáúu truïc cå baín cuía mäüt lãûnh tcl laì:
tãnlãûnh tham_säú
Tãn lãûnh laì kyï hiãûu lãûnh cuía tcl âãø thæûc thi, tham_säú laì nhæîng âäúi säú læûa choün cuía cáu lãûnh âoï. Caí hai thaình pháön trãn âæåüc goüi laì lãûnh. Mäüt lãnh âæåüc kãút thæûc bàòng mäüt kyï tæû xuäúng haìng (\n) hay mäüt dáúùu cháúm pháøy (;). Nãúu trãn mäüt doìng chè coï mäüt lenh thç khäng cáön phaíi coï dáúu cháúm pháøy.
set foo 0;
set bar 1
Trãn âáy laì hai lãûnh minh hoüa cho ngän ngæî tcl. Hai lãûnh trãn coï taïc duûng nhæ lãûnh gaïn trong C, foo = 0 vaì bar = 1.
Biãún vaì giaï trë cuía biãún
Trong tcl caïc biãún khäng âæåüc phán loaûi thaình nhiãöu kiãøu nhæ kiãøu säú nguyãn, säú thæûc, kiãøu kyï tæû, .... Caïc biãún coï thãø âæåüc gaïn caïc giaï trë laì säú, kyï tæû hay xáu chuäùi trong caïc láön sæí duûng khaïc nhau trong cuìng mäüt chæång trçnh.
Âäúi våïi tcl, caïc biãún âæåüc xem nhæ caïc xau chuäùi. Khi biãún cáön âæåüc sæí duûng, tcl cho pheïp caïc giaï trë säú âæåüc láúy theo khuän máùu chuáùn cuía ANSI C. Caïc giaï trë coï thãø âæåüc hiãøu nhæ sau:
74 säú nguyãn
0112 säú cå säú 8, bàõt âáöu bàòng säú 0
0x4a säú cå säú 8, bàõt âáöu bàòng säú 0x
74. säú thæûc
74.0 säú thæûc
7.4e1 säú thæûc
7.4e+1 säú thæûc
tcl âënh nghéa hai loaûi biãún laì biãún vä hæåïng vaì maíng. Âãø taûo ra mäüt biãún vä hæåïng vaì gaïn cho noï mäüt giaï trë ta duìng lãûnh set nhæ âaî gàûp åí pháön trãn:
set temp 1;
Lãûnh naûo taûo ra biãún temp vaì gaïn cho noï giaï trë laì 1. Muäún thay âäøi giaï trë cuía temp thaình mäüt giaï trë khaïc ta laûi sæí duûng lãûnh set.
set temp "Hello everybody";
Giaï trë cuía temp báy giåì laì mät xáu chuäùi, càûp nhaïy keïp chè cho tcl nháûn biãút âáy laì mäüt daîy caïc kyï tæû.
Ngæåüc våïi lãûnh set, lãûnh puts laûi coï taïc duûng láúy giaï trë cuía biãún vaì chuyãøn âãún thiãút bë xuáút, trong træåìg håüp dæåïi âáy laì maìn hçnh.
puts $banana;
Kyï tæû $ træåïc tãn biãún chè ra ràòng tcl truy cáûp âãún giaï trë cuía biãún theo sau. Quy æåïc naìy cuîng giäúng nhæ viãûc coï thãø thay âäøi kiãøu giaï trë cuía biãún laì nhæîng quy æåïc sæí duûng trong caïc shell cuía Unix.
Caïc cáúu truïc làûp
Ngän ngæî tcl häù tråü ba cáúu truïc làûp laì for, foreach vaì while. Ngoaìi ra coìn coï hai lãûnh âiãöu khiãøn làûp laì contunue vaì break. Sau âáy chuïng ta cuìng xem xeït cuï phaïp cuía tæìng cáúp truïc làûp âoï.
while {biãøu thæïc} {lãûnh thaình pháön}
Làûp caïc lãûnh thaình pháön cho âãún khi biãøn thæïc âiãöu kiãûn nháûn giaï tri sai.
foreach biãún {ds_giaï trë} {lãûnh thaình pháön}
Làûp caïc lãûnh thaình pháön våïi täøng säú láön laì täúng säú pháön tæí trong ds_giaï trë, tæång æïng mäùi láön làûp biãún âæåüc nháûn mäüt giaï trë trong ds_giaï trë cho âãún hãút.
for {biãún khåíi âáöu} {biãøu thæïc} {dk_tàng} {lãûnh thaình pháön}
Làûp caïc lãûnh thaình pháön cho âãún khi biãún khåíi âáöu sau mäüt säú láön thay âäøi giaï trë vaì khäng coìn thoía maîn biãøu thæïc.
Mäüt säú vê duû caïc cáúu truïc làûp:
set x 0;
while {$x < 10} {
incr x;
puts $x;
}
Âoaûn chæång trçnh trãn khåíi taûo giaï trë 0 cho x, thæûc hiãûn làûp x tæì 0 âãún 9 vaì in giaï trë cuía x ra maìn hçnh.
foreach element {o c n p li} {
switch $element {
o - {puts gas;}
c -
p -
li- {puts solid;}
}
}
Âoaûn chæång trçnh trãn láön læåüt thay giaï trë cuía element la o, c, p, li âãø thæûc hiãûn lãûnh reî nhaïnh switch trong lãûnh thaình pháön.
Tæång tæû nhæ cáúu truïc làûp while åí trãn, vê duû cuía cáúu truïc for dæåïi âáy cuîng thæûc hiãûn làûp biãún x tæì 0 âãún 9 vaì in giaï trë cuía noï ra maìn hçnh.
for {set i 0} {$i <= 10} {incr i} { puts $i; }
Chæång trçnh con
Mäüt thuí tuûc trong tcl gäöm coï caïc thaình pháön laì tãn thuí tuûc, danh saïch tham säú (nãúu coï) vaì caïc lãûnh näüi dung cuía thuí tuûc. Cuï phaïp âãø khai baïo mäüt thuí tuûc nhæ sau:
proc tãn_tt {tham säú} {lãûnh thaình pháön}
Säú læåüng tham säú cuía mäüt thuí tuûc laì khäng bàõt buäüc, mäüt thuí tuûc coï thãø khäng coï mäüt tham säú naìo. Khi naìy pháön khai baïo tham säú seî laì {}. Vê duû sau laì mäüt khai baïo thuí tuûc âån giaín våïi tãn thuí tuûc, khäng coï tham säú vaì thaình pháön chè laì mäüt lãûnh âån kiãøm tra xem thuí tuûc coï hoaût âäüng täút hay khäng. Tuy nhiãn nãúu chè nhæ váûy thç thuí tuûc trãn chè måïi âæåüc khai baïo vaì caïc lãûnh thaình pháön thuí tuûc chæa âæåüc thæûc hiãûn cho âãún khi thuí tuûc âæåüc goüi âãún trong chæång trçnh.
proc test_proc {} { puts "procedure test"; }
Âãø goüi thæûc hiãûn thuí tuûc trãn ta goüi âãún tãn thuí tuûc âoï vaì truyãön thám säú cho thuí tuûc nãúu coï. Trong vê duû naìy laì mäüt thuí tuûc khäng coï tham säú.
test_proc;
Mäüt chæång trçnh âån giaín bàòng tcl/tk
Cáúu truïc chæång trçnh
tcl laì ngän ngæî thäng dëch nãn caïc lãûnh cuía mäüt chæång trçnh âæåüc thæûc hiãûn tuáön tæû. Caïc lãûnh tring chæång trçnh âæåüc phán têch vaì kãút xuáút theo thæï tæû tæì âáöu âãún cuäúi. Khäng nhæ mäüt chæång trçnh C, chæång trçnh tcl khäng coï cáúu truïc roî neït, caí chæång trçnh laì táûp håüp cuía nhæîng lãûnh âån, caïc cáúu truïc làûp, caïc khai baïo thuí tuûc vaì lãûnh goüi thæûc thi caïc thuí tuûc âaî khai baïo. Tuy nhiãn doìng âáöu tiãn cuía mäüt táûp tin chæïa chæång trçnh tcl âæåüc bàõt âáöu nhæ sau:
#!usr/bin/wish
hoàûc :
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
Do sh thæåìng âæåüc âàût åí nhæîng vë trê khaïc nhau âäúi våïi tæìng phiãn baín khaïc nhau, do âoï khi sæí duûng theo daûng thæï hai ngæåìi sæí duûng chè cáön coï wish trong âæåìng dáùn chè ra cuía hoü laì âuí âãø dëch caïc chæång trçnh tcl/tk trãn hãû thäúng.
Thæûc hiãûn chæång trçnh
Thæûc hiãûn mäüt chæång trçnh tcl/tk ta coï thãø duìng mäüt trong hai daûng sau:
$ tclsh myprog.tcl
$ wish myprog.tcl
Taûi sao laûi coï hai daûng khaïc nhau âãø thæûc hiãûn mäüt chæång trçnh tcl/tk, chuïng coï gç khaïc nhau? Âàûc âiãøm khaïc nhau chênh chuïng ta âaî âæåüc biãút khi tçm hiãøu vãö tclsh vaì wish, tuy nhiãn váùn coï mäüt säú âiãøm khaïc biãût khi thæûc hiãûn mäüt chæång trçnh. wish màûc duì coï thãø hiãøu âæåüc caïc lãûnh cuía tcl vaì caí caïc lãûnh cuía tk nhæng wish chè âæåüc thæûc hiãûn trong mäi træåìng X window.
Sæí duûng socket trong tcl/tk
Lãûnh thiãút láûp mäüt socket kãút näúi âãún server coï cuï phaïp nhæ sau:
socket ?options? host port
Lãûnh naìy thæûc hiãûn kãút näúi âãún server vaì traí vãö säú hiãûu cuía socket nãúu thaình cäng. Sau khi kãút näúi, chuïng ta coï thãø âoüc vaì ghi trãn socket bàòng caïc lãûnh read, puts vaì flush. Lãûnh naìy chè häù tråü båíi giao thæïc TCP, nhæîng phiãn baín sau cuía Linux coï thãø seí häù tråü thãm caïc giao thæïc khaïc.
Mäüt âiãöu chàõc chàõn ràòng, træåïc khi lãûnh naìy âæåüc thæûc hiãûn server phaíi âaî sàôn saìng chåì kãút näúi âãún. Vê duû kãút näúi âãún server coï âëa chè laì 192. 0. 1. 2 vaì cäøng laì 9015:
socket 192. 0. 1. 2 9015;
CHÆÅNG III
XÁY DÆÛNG MÄ HÇNH CLIENT/SERVER
Xáy dæûng chæång trçnh sever
Nguyãn tàõc hoaût âäüng
Chæång trçnh server âæåüc xáy dæûng bàòng ngän ngæî C, æïng duûng láûp trçnh âa tiãön trçnh trãn Linux âãø taûo ra caïc thaình pháön chênh cho mäüt chæång trçnh server. Muûc âêc chçnh cuía chæång trçnh server laì taûo ra caïc socket vaì chåì âåüi caïc chæång trçnh client tæì caïc maïy traûm khaïc kãút näúi vaìo. Sau khi coï mäüt client (chæång trçnh client) kãút näúi âãún, chæång trçnh server phaíi taûo ra mäüt cäøng måïi cho client âoï âäöng thåìi khåíi taûo bäü pháûn træûc tiãúp giao tiãúp våïi chênh client âoï. Tiãúp âãún chæång trçnh server tråí laûi traûng thaïi chåì âåüi mäüt kãút näúi tæì mäüt client khaïc.
Nhæ váûy cáúu truïc cuía mäüt chæång trçnh server seî coï hai thaình pháön chênh. Mäüt thaình pháön luän chåì âåüi caïc kãút näúi, trao âäøi mäüt säú thäng tin cáön thiãút vaì kêch hoaût thaình pháön giao tiãúp træûc tiãúp âãún client. Mäüt thaình pháön khaïc chè âæåüc kêch hoaût khi coï mäüt client kãút näúi âãún, thaình pháön naìy chëu traïch nhiãûm kãút näúi våïi client, nháûn caïc thäng tin tæì client âãø gåíi âãún caïc client khaïc nãúu coï âäöng thåìi nháûn thäng tin tæì caïc client khaïc âãún räöi truyãön cho client maì noï quaín lyï.
TT_ÂÅÜI
TT_XLYÏ
TT_XLYÏ
..........
Client 1
Client 2
SERVER
Så âäö hoaût âäüng hãû client/server
Khi coï n client kãút näúi âãún server, chæång trçnh server seî täön taûi n+1 thaình pháön, trong âoï coï n thaình pháön træûc tiãúp truyãön thäng våïi caïc client vaì mäüt thaình pháön chåì âåüi caïc kãút näúi måïi.
Så âäö thuáût toaïn thaình pháönchåì âåüi kãút näúi
Coï
Khåíi taûo socket
Khåíi taûo daîy thäng baïo
Âåüi mäüt kãút näúi tæì client
BÀÕT ÂÁÖU
Coï kãút näúi
Nháûn thäng tin tæì client
Goüi chæång trçnh quaín lyï client
Khäng
Khåíi taûo socket
Chæång trçnh goüi haìm mk_connect() âãø taûo mäüt socket thäúng nháút cho táút caí caïc client kãút näúi âãún server láön âáöu tiãn. Mäüt client muäún kãút näúi våïi thaình pháön naìy phaíi sæí duûng socket coï âëa chuí IP cuía maïy chuí vaì säú hiãûu cäøng laì 9013. Âoaûn chæång trçnh khåíi taûo socket cuía hai thaình pháön taûo nãn server hoaìn toaìn giäúng nhau træì säú hiãûu cäøng kãút näúi. Sau âáy laì âoaûn chæång trçnh minh hoüa khåíi taûo socket:
int mk_connect(int port)
{
int sd1;
if (port>0) /*Kiãøm tra säú hiãûu cäøng laì mäüt säú dæång*/
sad.sin_port=htons((u_short)port);
else{
fprintf(stderr,"Bad port number %s \n",port);
exit(1);
}
if (((int)(ptrp=getprotobyname("tcp")))==0)
{
fprintf(stderr,"Cannot map \"tcp\" to protocol number");
exit(1);
}
/*Creat a socket*/
sd1=socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd1<0){
fprintf(stderr,"Socket creation failed\n");
exit(1);
}
/* Bind a local address to the socket*/
if(bind(sd1,(struct sockaddr*)&sad,sizeof(sad))<0){
fprintf(stderr,"tn bind failed\n");
exit(1);
}
/*Specify size of request queue*/
if (listen(sd1,QLEN)<0){
fprintf(stderr,"tn listen failed\n");
exit(1);
}
fprintf(stderr,"Server wait for a connect..");
return sd1;
}
Âoaûn chæång trçnh trãn láön læåüt goüi caïc haìm socket(), bind() vaì cuäúi cuìng laì listen() âãø chuáùn bë sàôn saìng chåì âåüi mäüt yãu cáöu kãút näúi tæì client.
Khåíi taûo daîy thäng baïo
Pháön âáöu cuía server chè coï traïch nhiãûm taûo ra daîy thäng baïo vaì baío âaím hoaût âäüng täút træåïc khi cho caïc client kãút näúi. Træåïc tiãn phaíi taûo ra mäüt khoïa cuía daîy thäng baïo tæì táûp tin "msg" vaì mäüt tham säú kyï tæû 'a' âãø khoïa naìy laì duy nháút. Sau âáy laì thuí tuûc taûo ra mäüt daîy thäng baïo måïi:
void crtmsg()
{
filekey=ftok("./msg",'\a');
if (filekey!=0){
msgid=msgget(filekey,IPC_CREAT); /* Taûo daîy thäng baïo måïi*/
}
else exit(1);
printf("Day t/b da duoc tao!\n");
}
Âåüi mäüt kãút näúi tæì client
Âãø server coï thãø cháúp nháûn âäöng thåìi nhiãöu kãút näúi tæì nhiãöu client, viãûc âåüi mäüt kãút näúi laì mäüt voìng làûp vä haûn. Server liãn tuûc âåüi kãút näúi, goüi pháön xæí lyï vaì laûi âåüi kãút näúi khaïc.
while(1) {
wait_connect(sd);
fprintf(stderr,"Tn wait for a connect..");
}
Khi coï mäüt kãút näúi, lãûnh accept() trong haìm wait_connect() seî nháûn láúy caïc thäng tin vãö maïy traûm âang sæí duûng chæång trçnh client coï kãút näúi âãún.
if ((sda[visits].sdi=accept (sd, (struct sockaddr *)&cad, &alen))<0)
{
fprintf(stderr,"accept failed\n");
exit(1);
}
sda laì mäüt maíng cáúu truïc, caïc thaình pháön cuía cáúu truïc naìy seî âæåüc nãu roî trong pháön cáúu truïc dæî liãûu.
Nãúu accept() thaình cäng (kãút näúi thaình cäng), server nháûn láúy thäng tin vãö bê danh cuía ngæåìi sæí duûng. Thãm vaìo maíng sad mäüt pháön tæí. Sau âoï truyãön cho client säú hiãûu cäøng måïi laì PROTOPORT cäüng våïi säú thæï tæû maì client truy cáûp âãún server.
sda[visits]. port = visits + PROTOPORT;
PROTOPORT coï giaï trë laì 9015 âæåüc quy âënh træåïc âãø dãø daìng tênh säú hiãûu cäøng cuía mäøi client.
Tiãúp theo goüi chæång trçnh sv1. Âáy laì mäüt chæång trçnh âæåüc goüi thæûc thi bàòng lãûnh:
if ((fork()) ==0) { execl ("./sv1","sv1","192.0.1.3",buf,sda,"&",NULL);}
Khäng phaíi ngáùu nhiãn lãûnh execl âæåüc goüi keìm trong fork(). Caïc tham säú truyãön cho sv1 laì âëa chè server vaì säú hiãûu cäøng tæång æïng maì client seî duìng âãøn kãút näúi âãún láön hai. sv1 seî træûc tiãúp trao âäøi thäng tin våïi client qua socket naìy. Sau lãûnh naìy haìm wait_connect kãút thuïc vaì tråí laûi voìng làûp chåí kãút näúi.
Så âäö thuáût toaïn thaình pháön xæí lyï thäng tin trao âäøi
Khäng
Phántêch tham säú âáöu vaìo
Khåíi taûo socket
Khåíi taûo daîy thäng baïo
Âåüi kãút näúi tæì client
BÀÕT ÂÁÖU
Coï kãút näúi
Trao âäøi thäng tin giæîa client vaì daîy thäng baïo
Coìn kãút näúi
KÃÚT THUÏC
Coìn
Phán têch tham säú âáöu vaìo
Chæång trçnh nháûn hai tham säú laì âëa chè IP cuía maïy chuí vaì säú hiãûu cäøng daình cho client maì chæång trçnh seî taûo socket vaì sàôn saìng cho kãút näúi tæì client.
Khåíi taûo socket vaì tçm kiãúm daîy thäng baïo
Viãûc khåíi taûo socket åí âáy hoaìn toaìn giäúng våïi pháön trãn træì säú hiãûu cäøng. Mäùi láùn chæång trçnh naìy taûo ra mäüt baín sao hoaût âäüng seî coï mäüt säú hiãûu cäøng khaïc tæång æïng. Do âoï âãø khåíi taûo socket chuïng ta váùn duìng haìm mk_connect() nhæng våïi tham säú port thay âäøi tuìy theo client.
Taûi âáy daîy thäng baïo âaî âæåüc taûo ra tæì træåïc, chuïng ta chè cáön taûo ra khoïa vaì tçm kiãúm daîy laì coï thãø sæí duûng âæåüc. Tuy nhiãn taûo láûp vaì tçm daîy thäng baïo cuìng duìng chung mäüt lãûnh :
msgid=msgget(filekey,IPC_EXCL);
Âåüi mäüt kãút näúi tæì client
Tæång tæû nhæ trãn, chuïng ta sæí duûng haìm wait_connect() âãø chåì client keït näúi âãún træåïc khi thæûc hiãûn trao âäøi thäng tin.
Thæûc hiãûn trao âäøi thäng tin
Âáy laì nhiãûm vuû chênh cuía sv1, chæång trçnh naìy seî phaíi nháûn táút caí caïc thäng baïo cuía client gåíi âãún räöi sau âoï gåíi lãn daîy thäng baïo cho táút caí caïc sv1 cuía caïc client khaïc. Ngoaìi ra chæång trçnh naìy coìn phaíi nháûn caïc thäng baïo trãn daîy coï kiãøu truìng våïi säú hiãûu cäøng cuía mçnh âãø chuyãøn (truyãön qua socket) âãún client. Pháön client seî nháûn caïc thäng baïo tæì socket, phán têch räöi hiãùn thë chuïng.
Cáúu truïc dæî liãûu
Chæång trçnh server âæåüc thæûc hiãûn theo mä hçnh server âäüng nãn trong mäüt thåìi âiãøm hoaût âäüng báút kyì seî coï n + 1 thaình pháön (tiãún trçnh) cuìng thæûc thi. Trong âoï coï n tiãún trçnh thæûc hiãûn viãûc trao âäøi thäng tin træûc tiãúp våïi n client kãút näúi âãún. Nhæ váûy chæång trçnh server phaíi coï mäüt maíng dæî liãûu maì caïc pháön tæí laì mäüt biãún cáúu truïc duìng âãø læu træî âáöy âuí caïc thäng tin vãö n client kãút näúi âãún nhæ âëa chè IP, caïc cäøng, ... Cáúu truïc âoï âæåüc hiãûn thæûc nhæ sau:
struct data{
long type;
int sdi,sdy;
int port;
char nickname[1000];
};
Ngoaìi viãûc quaín lyï caïc thäng tin vãö client, maíng dæî liãûu naìy coìn coï mäüt nhiãûm vuû quan troüng laì khi mäüt coï mäüt client måïi kãút näúi âãún, server seî phaíi láúy caïc thäng tin cuía client måïi thãm vaìo danh saïch vaì thäng baïo cho client naìy biãút ràòng hiãûn âang coï bao nhiãu client âang coï kãút näúi âãún server. ÅÍ âáy chuïng ta âang xáy dæûng mäüt hãû thäúng troì chuyãûn trãn maûng nãn mäùi client âãöu phaíi biãút hiãûn taûi coï bao nhiãu client âang täön taûi.
Caïc tiãún trçnh giao tiãúp træûc tiãúp våïi caïc client seî âæåüc trao âäøi thäng tin giæîa chuïng thäng qua hãû thäúng IPC âæåüc khåíi taûo khi chæång trçnh server âæåüc bàõt âáöu hoaût âäüng. Âoï laì mäüt daîy caïc thäng baïo maì mäùi tiãún trçnh khi nháûn thäng tin tæì client cuía noï seî phaíi gåíi chuïng lãn daîy thäng baïo âãún caïc tiãún trçnh khaïc. Cuîng tæì daîy thäng baïo trãn, mäùi tiãún trçnh seî nháûn láúy caïc thäng baïo âæåüc phán loaûi daình riãng cho noï vaì truyãön qua socket âãún chæång trçnh client åí maïy traûm. Nhæ váûy cáön coï mäüt baíng phán loaûi caïc thäng baïo trãn daîy thäng baïo.
struct messagetype{
long type;
char mess[1000];
}
Caïc cáúu truïc dæî liãûu coï liãn quan âãún daîy thäng baïo âaî âæåüc trçnh baìy åí pháön truyãön thäng bàòng IPC.
Cäøng giao tiãúp våïi caïc client:
Theo nguyãn tàõc hoaût âäüng cuía server thç mäùi client tæì luïc bàõt âáöu cho âãún khi kãút thuïc viãûc kãút näúi, chuyãøn sang chãú âäü trao âäøi thäng tin qua socket, phaíi thæûc hiãûn kãút näúi âãún server hai láön. Láön âáöu tiãn kãút näúi âãún bàòng socket coï cäøng cäú âënh chi táút caí caïc client chênh laì kãút näúi âãún tháönh pháön chåì âåüi kãút näúi cuía server. Nãúu kãút näúi thaình cäng, client seî truyãön âãún server bê danh ngæåìi sæí duûng (nickname) vaì nháûn tæì server säú hiãûu cäøng daình riãng cho client âãø chuáùn bë thæûc hiãûn viãûc kãút näúi âãún server láön thæï hai. Láön hai seî kãút näúi âãún thaình pháön måïi âæåüc taûo ra âãø trao âäøi thäng tin træûc tiãúp våïi client naìy.
Nhæ váûy, khi coï mäüt client kãút näúi âãún, thaình pháön chåì âåüi cuía server seî thæûc hiãûn caïc bæåïc sau:
Nháûn láúy bê danh (nickname) tæì client.
Thãm mäüt pháön tæí måïi trong danh saïch client.
Âæa ra mäüt cäøng måïi cho client naìy vaì truyãön cho client.
Âoïng socket hiãûn taûi.
Taûo thãm mäüt thaình pháön xæí lyï vaì truyãön cho thaình pháön naìy säú hiãûu cäøng âaî gaïn cho client bàòng tham säú.
Taûo tråí laûi socket chuáùn vaì chåì mäüt kãút näúi måïi.
Trãn âáy laì näüi dung caïc bæåïc thæûc hiãûn cuía thaình pháön chåì âåüi cuía server. Riãng thaình pháön xæí lyï seî laìm nhæ thãú naìo âãø truyãön thäng tin âãún client âäöng thåìi trao âäøi thäng tin qua daîy thäng baïo. Pháön xæí lyï seî thæûc hiãûn mäüt säú cäng viãûc nhæ sau:
Taûo socket måïi phuì håüp tham säú âæåüc pháön træåïc truyãön âãún.
Thiãút láûp chãú âäü chåì kãút näúi láön hai tæì client.
Kãút näúi thaình cäng thç sang caïc bæåïc tiãúp theo, nãúu khäng thç kãút thuïc tiãún trçnh.
Nháûn thäng tin tæì client vaì gåíi lãn daîy thäng baïo coï táút caí caïc kiãøu tæång æïng våïi säú læåüng client coï trãn hãû thäúng.
Tçm kiãúm thäng tin trãn daîy thäng baïo, nãúu coï kiãøu tæång æïng våïi säú hiãûu cäøng cho client thç nháûn láúy vaì truyãön cho client qua socket.
Thæûc hiãûn hai bæåïc kãø trãn cho âãún khi client âoïng kãút näúi, kãút thuïc laìm viãûc.
Qua caïc bæåïc trãn, chuïng ta coï thãø cho ràòng læåüng thäng baïo trãn daîy thäng baïo coï thãø phaït sinh ráút nhiãöu khi coï mäüt thäng baïo tæì client naìy gåíi âãún client khaïc. Thæûc ra thao taïc nháûn thäng baïo trãn daîy thäng baïo âæåüc thæûc hiãûn liãn tuûc, báút kyì luïc naìo coï thäúng baïo coï kiãøu tæång æïng xuáút hiãûn seî âæåüc nháûn láúy vaì truyãön cho client. Do âoï ráút khoï xaíy ra træåìng håüp tháút laûc hay tàõc ngheîn thäng tin.
Quaín lyï trao âäøi thäng tin
Âãø quaín lyï täút viãûc trao âäøi thäng tin, træåïc hãút chuïng ta xem xeït hãû thäúng chatting (client/server) coï táút caí bao nhiãu loaûi thäng tin âæåüc trao âäøi giæîa client, server vaì daîy thäng baïo. Coï ba loaûi thäng tin chênh nhæ sau:
Mäüt client måïi âæåüc kãút näúi âãún: Nhiãûm vuû cuía server luïc naìy laì phaíi taûo ra mäüt thaình pháön xæí lyï cho client naìy, âæa client vaìo danh saïch vaì gåíi thäng baïo cho caïc client âaî täön taûi biãút coï moüt client måïi xuáút hiãûn.
Mäüt client kãút thuïc kãút näúi: server seî phaíi thæûc hiãûn gáön nhæ træåìng håüp trãn. Thäng baïo âãún caïc client vãö sæû ra âi cuía mäüt client vaì loaûi boí client ra khoíi danh saïch.
Thäng baïo bçnh thæåìng: server vaì client khäng xæí lyï âàûc biãût khi gàûp loaûi thäng baïo naìy.
Chæång trçnh client
Nguyãn tàõc hoaût âäüng
Chæång trçnh client, sau khi xáy dæûng giao diãûn trãn X, hiãùn thë häüp thåüi yãu cáöu ngæåìi sæí duûng nháûn bê danh cuía mçnh vaì âëa chè maïy chuí cáön kãút näúi âãún. Nãúu thäng tin vãö maïy chuí sai hoàûc khäng kãút näúi âæåüc, chæång trçnh seî baïo läùi vaì yãu cáöu nháûp laûi. Ngæåìi sæí duûng coï thãø boí qua bæåïc naìy nhæîng seî khäng kãút näúi âæåüc âãún server.
Thæûc hiãûn kãút näúi âãún server. Quaï trçnh kãút näúi seî âæåüc trçnh baìy trong pháön sau. Ngæåìi sæí duûng coï thãø bàõt âáöu trao âäøi thäng tin ngay sau khi kãút näúi thaình cäng.
Ngæåìi sæí duûng coï thãø âoïng kãút näúi hoàûc thoaït khoíi chæång trçnh qua caïc trçnh âån trãn thanh thæûc âån.
Så âäö thuáût toaïn
Xáy dæûng giao diãûn
Yãu cáöu nháûp thäng tin
Thæûc hiãûn kãút näúi
BÀÕT ÂÁÖU
Kãút näúi âæåüc
Sæí duûng chæång trçnh "chatting"
Thäng baïo läùi
BÀÕT ÂÁÖU
Âæåüc
Khäng
Thiãút láûp kãút näúi âãún chæång trçnh server
Âãø thiãút láûp âæåüc kãút näúi, ngæåìi sæí duûng phaíi nháûp âuïng âëa chè IP maïy coï caìi âàût chæång trçnh server. Chæång trçnh client seî thæûc hiãûn hai láön kãút näúi âãún maïy chuí, láön âáöu tiãn seî kãút näúi âãún pháön âåüi kãút näúi cuía server, láön thæï hai seî kãút näúi âãún chæång trçnh træûc tiãúp giao tiãúp våïi client. Caïc thäng baïo client nháûn hay gæíi âi âãöu thäng qua socket cuía chæång trçnh naìy.
Chæång trçnh client chè biãút âãún mäüt chæång trçnh âang kãút näúi træûc tiãúp. Tæì client khäng thãø xaïc âënh âæåüc caïc thäng tin âæåüc xæí lyï vaì di chuyãøn nhæ thãú naìo. Client chè viãûc nháûn thäng baïo tæì socket, phán loaûi thäng baïo räöi hiãùn thë ra maìn hçnh. Khäng thãø gåíi mäüt cáúu truïc chæa qua maî hoïa (thä) cho client.
Phán loaûi thäng tin nháûn âæåüc tæì maïy chuí
Caïc client nháûn âæåüc tæì socket ba loaûi thäng baïo. Nãúu chæång trçnh phaït triãøn thaình caïc phoìng riãng (chatroom), kãút håüp ftp, mail, .. seî coï thãø coï nhiãöu loaûi thäng baïo hån.
Caïc thäng baïo bçnh thæåìng cuía caïc client âang täön taûi gæíi âãún. Chè hiãøn thë, khäng xæí lyï thãm.
Thäng baïo thãm client tæì server: Hiãøn thë thäng baïo, thãm mäüt client vaìo khung häüi thoaûi daình riãng cho bê danh ngæåìi duìng.
Thäng baïo mäüt client ngæìng: Hiãøn thë thäng baïo, loaûi boí client trong danh saïch vaì trong khung bê danh.
CHÆÅNG IV
THÆÍ NGHIÃÛM CHÆÅNG TRÇNH
Trçnh tæû sæí duûng chæång trçnh
Chæång trçnh server phaíi âæåüc khåíi âäüng træåïc åí chãú âäü nãön (chæång trçnh server khäng coï giao diãûn). Chæång trçnh server seî tæû taû ra socket vaì chåì âåüi caïc client kãút näúi âãún.
Chæång trçnh client phaíi âæåüc thæûc hiãûn trãn X Window do thiãút láûp giao diãûn bàòng caïc cäng cuû cuía tk (toolkit). Ngæåìi sæí duûng âæåüc yãu cáöu nháûp bê danh vaì âëa chè maïy chuí. chæång trçnh seî thæûc hiãûn kãút näúi vaì coï kãút quaí tråí laûi.
Kãút quaí
CHÆÅNG V
KÃÚT LUÁÛN
Kãút quaí âaût âæåüc
Chæång trçnh server
Xáy dæûng âæåüc chæång trçnh server theo mä hçnh server âäüng. Coï nghéa laì khäng coï træåìng håüp mäüt client báút kyì phaíi chåì âåüi server âaïp æïng cho client khaïc kãút thuïc måïi âãún læåüt mçnh. Noïi caïch khaïc laì server coï thãø âaïp æïng âäöng thåìi cho nhiãöu client kãút näúi âãún.
ÆÏng duûng khaí nàng láûp trçnh âa tiãúp trçnh trãn hãû âiãöu haình Linux.
Thiãút láûp âæåüc mäúi liãn laûc giæîa caïc tiãún trçnh bàòng hãû thäúng IPC (Inter Process Comunication), sæí duûng daîy thäng baïo laìm phæång tiãûn truyãön thäng.
ÆÏng duûng giao tiãúp maûng giæîa caïc maïy sæí duûng Linux.
Chæång trçnh client
Láûp trçnh bàòng ngän ngæî tcl/tk.
Xáy dæûng âæåüc giao diãûn âäö hoüa trãn X Window.
Giao tiãúp âæåüc våïi chæång trçnh server viãút bàòng ngän ngæî C.
Tênh khaí thi
Chæång trçnh coï thãø âæåüc æïng duûng trong phoìng thæûc haình coï duìng hãû âiãöu haình Linux.
Maî nguäön cuía âäö aïn seî cäng khai taûi phoìng thæûc haình xem nhæ mäüt vê duû âãø sinh viãn khoïa sau tiãúp tuûc nghiãn cæïu láûp trçnh trãn X Window vaì trãn maûng Linux
Haûn chãú
Chæång trçnh chæa sæí duûng âæåüc tiãúng Viãût trong giao diãûn vaì trong caïc thäng baïo truyãön qua maûng.
Chæa xáy dæûng mäüt chæång trçnh client trãn MS Window âãø chæïng minh sæû khäng phuû thuäüc hãû âiãöu haình, ngän ngæî láûp trçnh khi sæ duûng chuáùn giao tiãúp qua maûng.
Hæåïng phaït triãøn âãö taìi
Sæí duûng tiãúng Viãût trong giao diãûn vaì caí thäng tin truyãön dáùn.
Xáy dæûng thaình caïc phoìng riãng cho caïc client.
Kãút håüp caïc æïng duûng maûng khaïc nhæ mail, ftp, ...
TAÌI LIÃÛU THAM KHAÍO
Douglas E.Comer. Internetworking with TCP/IP. Simon & Schuster Company. Volume 1. US 1995, 613t.
Douglas E.Comer. Computer Network And Internet. Simon & Schuster /A Viacom Company. US 1997,506t.
David Pitts, et al. Red Hat Linux Unleashed. Sams Publishing 1998. Second Edition, 710t.
Jack Tackett Jr, Steve Burnett. Special Edition Using Linux. Que Corporation 1999. Fourth Edition, 894t.
Bill Ball, Stephen Saioogen. Teach Yourself Linux in 24 Hours. Sams Publishing 1998.
Tim Paker. Teach Yourself TCP/IP in 14 Days. Sams publishing. Second edition 1996.
Các file đính kèm theo tài liệu này:
- LYTHUYET.DOC
- CHUONGTRINH.rar