Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
CH
NG 1
Tổng quan về lập trình truyền thông
Mục đích
Ch ng này nhằm cung cấp cho các bạn một cái nhìn tổng quan về các vấn đề có
liên quan trong lập trình truyền thông
Yêu cầu
Sau khi hoàn tất ch
ng này, bạn có thể:
Giải thích đ ợc C chế giao tiếp liên quá trình (Inter-Process
Communication ) là gì.
Mô tả ch c năng, nhiệm vụ c a các tầng trong mô hình OSI.
Định nghĩa về giao th c và biện luận đ ợc sự cần thiết c a giao th c trong
truyền thông .
Mô tả về bộ giao th c TCP/IP.
Định nghĩa mô hình Client – Server.
Phân biệt đ ợc 2 chế độ giao tiếp: Nghẽn và Không nghẽn.
Phân biệt đ ợc các kiểu kiến trúc ch
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
ng trình.
1
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.1. C chế giao tiếp liên quá trình là gì ?
Truyền thông là một khái niệm dùng để chỉ sự giao tiếp, trao đổi thông tin giữa hai
hay nhiều thực thể trong một hệ th ng nào đó. Nếu hệ th ng mà chúng ta xem xét là xã hội
loài ng i, thì truyền thông có thể là quá trình trao đổi thông tin giữa ng i với ng i
trong cuộc s ng thông qua các ph ng tiện truyền tải thông tin khác nhau nh không khí
(trong trò chuyện trực tiếp), hệ th ng điện thoại, sách, báo, các ph ng tiện nghe nhìn,
mạng máy tính...
Nếu hệ th ng mà chúng ta xem xét là một hệ th ng máy tính hay một hệ th ng
mạng thì truyền thông có thể đ ợc phân thành hai m c:
M c phần c ng: là sự giao tiếp, trao đổi thông tin giữa các bộ phận vật lý
cấu thành nên hệ th ng máy tính nh CPU, bộ nhớ, thiết bị vào ra, card giao
tiếp mạng, nh vào các ph ng tiện truyền thông nh hệ th ng BUS nội, hệ
th ng BUS vào ra hay các dây cáp mạng . . .
M c phần mềm: là sự giao tiếp, trao đổi thông tin giữa các thành phần bên
trong c a một ch ng trình hay giữa các ch ng trình với nhau thông qua
các c chế truyền thông đ ợc hỗ trợ b i các hệ điều hành, hệ điều hành
mạng.
Trong các hệ th ng máy tính đ n nhiệm (monotasking) cổ điển, ví dụ MS-DOS, tại
một th i điểm chỉ cho phép tồn tại một quá trình. Việc giao tiếp, trao đổi thông tin chỉ diễn
ra trong phạm vi c a một ch ng trình. Đó là sự giao tiếp giữa các th tục d ới hình th c
chia sẻ các biến toàn cục, hay bằng cách truyền các tham s khi gọi hàm, th tục hay bằng
giá trị trả về c a một hàm . . . Ng ợc lại, trong các hệ th ng đa nhiệm (multitasking) có
nhiều quá trình tồn tại song song nhau, mỗi quá trình đ ợc thực hiện trong một không gian
địa chỉ (Address space) riêng biệt. Việc giao tiếp giữa các quá trình mu n thực hiện đ ợc
đòi h i phải có những tiện ích hỗ trợ b i hệ điều hành, hệ điều hành mạng. Các tiện ích
này th ng đ ợc gọi với cái tên là C chế giao tiếp liên quá trình (IPC - Inter-Process
Communication).
1.2. Phân loại c chế giao tiếp liên quá trình
Các c chế giao tiếp liên quá trình đ ợc hỗ trợ b i các hệ điều hành đa nhiệm, hệ
điều hành mạng đ ợc chia ra làm hai loại:
Loại 1: C chế giao tiếp liên quá trình hỗ trợ giao tiếp giữa các quá trình trên
cùng một máy tính. (Hình H1.1)
Hình 1.1 - C chế giao tiếp liên quá trình loại 1
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
2
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
- Giáo Trình Lập Trình Truyền Thông
Loại 2: C chế giao tiếp liên quá trình hỗ trợ giao tiếp giữa các quá trình nằm
trên các máy tính khác nhau (Hình H1.2).
Hình 1.2 - C chế giao tiếp liên quá trình loại 2
Trong c chế giao tiếp liên quá trình trên cùng một máy, dữ liệu trao đổi qua lại
giữa các quá trình phải đi xuyên qua hạt nhân (kernel) c a hệ điều hành. Đó có thể là một
vùng nhớ dùng chung cho các quá trình đã đ ợc qui định tr ớc b i hệ điều hành, hay một
tập tin trên đĩa đ ợc quản lý b i hệ điều hành trong đó một quá trình sẽ ghi dữ liệu vào,
quá trình khác đọc dữ liệu ra, . . .
Trong c chế giao tiếp liên quá trình trên các máy tính khác nhau, dữ liệu trao đổi
giữa các quá trình không những phải đi qua hạt nhân nh c chế giao tiếp liên quá trình
trên một máy tính mà h n thế các hạt nhân c a các máy có liên quan phải hiểu nhau. Nói
cách khác các hạt nhân phải thoả thuận tr ớc với nhau về các qui tắc trao đổi thông tin
giữa chúng. Thông th ng ta gọi các qui tắc này là các giao th c (Protocol).
1.3. Mô hình tham khảo OSI
Để dễ dàng cho việc n i kết và trao đổi thông tin giữa các máy tính với nhau, vào
năm 1983, Tổ ch c tiêu chuẩn thế giới ISO đã phát triển một mô hình cho phép hai máy
tính có thể g i và nhận dữ liệu cho nhau. Mô hình này dựa trên tiếp cận phân tầng (lớp),
với mỗi tầng đảm nhiệm một s các ch c năng c bản nào đó và đ ợc gọi là mô hình OSI.
Để hai máy tính có thể trao đổi thông tin đ ợc với nhau cần có rất nhiều vấn đề liên
quan. Ví dụ nh cần có Card mạng, dây cáp mạng, điện thế tín hiệu trên cáp mạng, cách
th c đóng gói dữ liệu, điều khiển lỗi đ ng truyền ... Bằng cách phân chia các ch c năng
này vào những tầng riêng biệt nhau, việc viết các phần mềm để thực hiện chúng tr nên dễ
dàng h n. Mô hình OSI giúp đồng nhất các hệ th ng máy tính khác biệt nhau khi chúng
trao đổi thông tin. Mô hình này gồm có 7 tầng:
7. Tầng ng dụng (Application Layer)
Đây là tầng trên cùng, cung cấp các ng dụng truy xuất đến các dịch vụ mạng.
Nó bao gồm các ng dụng c a ng i dùng, ví dụ nh các Web Browser
(Netscape Navigator, Internet Explorer ), các Mail User Agent (Outlook
Express, Netscape Messenger, ...) hay các ch ng trình làm server cung cấp
các dịch vụ mạng nh các Web Server (Netscape Enterprise, Internet
Information Service, Apache, ...), Các FTP Server, các Mail server (Send
mail, MDeamon). Ng i dùng mạng giao tiếp trực tiếp với tầng này.
6. Tầng trình bày (Presentation Layer)
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
3
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Tầng này đảm bảo các máy tính có kiểu định dạng dữ liệu khác nhau vẫn có
thể trao đổi thông tin cho nhau. Thông th ng các máy tính sẽ th ng nhất với
nhau về một kiểu định dạng dữ liệu trung gian để trao đổi thông tin giữa các
máy tính. Một dữ liệu cần g i đi sẽ đ ợc tầng trình bày chuyển sang định
dạng trung gian tr ớc khi nó đ ợc truyền lên mạng. Ng ợc lại, khi nhận dữ
liệu từ mạng, tầng trình bày sẽ chuyển dữ liệu sang định dạng riêng c a nó.
5. Tầng giao dịch (Session Layer)
Tầng này cho phép các ng dụng thiết lập, sử dụng và xóa các kênh giao tiếp
giữa chúng (đ ợc gọi là giao dịch). Nó cung cấp c chế cho việc nhận biết tên
và các ch c năng về bảo mật thông tin khi truyền qua mạng.
4. Tầng vận chuyển (Transport Layer)
Tầng này đảm bảo truyền tải dữ liệu giữa các quá trình. Dữ liệu g i đi đ ợc
đảm bảo không có lỗi, theo đúng trình tự, không bị mất mát, trùng lắp. Đ i
với các gói tin có kích th ớc lớn, tầng này sẽ phân chia chúng thành các phần
nh tr ớc khi g i đi, cũng nh tập hợp lại chúng khi nhận đ ợc.
3. Tầng mạng (Network Layer)
Tầng này đảm bảo các gói dữ liệu (Packet) có thể truyền từ máy tính này đến
máy tính kia cho dù không có đ ng truyền vật lý trực tiếp giữa chúng. Nó
nhận nhiệm vụ tìm đ ng đi cho dữ liệu đến các đích khác nhau trong hệ
th ng mạng.
2. Tầng liên kết dữ liệu (Data-Link Layer)
Tầng này đảm bảo truyền tải các khung dữ liệu (Frame) giữa hai máy tính có
đ ng truyền vật lý n i trực tiếp với nhau. Nó cài đặt c chế phát hiện và xử
lý lỗi dữ liệu nhận.
1. Tầng vật ký (Physical Layer)
Điều khiển việc truyền tải thật sự các bit trên đ ng truyền vật lý. Nó định
nghĩa các tín hiệu điện, trạng thái đ ng truyền, ph ng pháp mã hóa dữ liệu,
các loại đầu n i đ ợc sử dụng.
Về nguyên tắc, tầng n c a một hệ th ng chỉ giao tiếp, trao đổi thông tin với tầng n
c a hệ th ng khác. Mỗi tầng sẽ có các đ n vị truyền dữ liệu riêng:
•
•
•
•
Tầng vật lý: bit
Tầng liên kết dữ liệu: Frame
Tầng mạng: Packet
Tầng vận chuyển: Segment
Trong thực tế, dữ liệu đ ợc g i đi từ tầng trên xu ng tầng d ới cho đến tầng thấp
nhất c a máy tính g i.
đó, dữ liệu sẽ đ ợc truyền đi trên đ ng truyền vật lý. Mỗi khi
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
4
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
dữ liệu đ ợc truyền xu ng tầng phía d ới thì nó bị "gói" lại trong đ n vị dữ liệu c a tầng
d ới. Tại bên nhận, dữ liệu sẽ đ ợc truyền ng ợc lên các tầng cao dần. Mỗi lần qua một
tầng, đ n vị dữ liệu t ng ng sẽ đ ợc “tháo” ra.
Đ n vị dữ liệu c a mỗi tầng sẽ có một tiêu đề (header) riêng, đ ợc mô tả trong
hình 1.3.
OSI chỉ là mô hình tham khảo, mỗi
nhà sản xuất khi phát minh ra hệ th ng
mạng c a mình sẽ thực hiện các ch c năng
từng tầng theo những cách th c riêng.
Các cách th c này th ng đ ợc mô tả d ới
dạng các chuẩn mạng hay các giao th c
mạng. Nh vậy dẫn đến tr ng hợp cùng
một ch c năng nh ng hai hệ th ng mạng
khác nhau sẽ không t ng tác đ ợc với
nhau. Hình 1.4 sẽ so sánh kiến trúc c a các
hệ điều hành mạng thông dụng với mô
hình OSI.
Hình 1.3 - Xử lý dữ liệu qua các tầng
Hình 1.4 - Kiến trúc c a một s hệ điều hành mạng thông dụng
Để thực hiện các ch c năng
mạng sẽ có các protocol riêng:
tầng 3 và tầng 4 trong mô hình OSI, mỗi hệ th ng
UNIX: Tầng 3 dùng giao th c IP, tầng 4 giao th c TCP/UDP
Netware: Tầng 3 dùng giao th c IPX, tầng 4 giao th c SPX
Windows NT: chỉ dùng 1 giao th c NETBEUI
Nếu chỉ dừng lại đây thì các máy tính UNIX, Netware, NT sẽ không trao đổi
thông tin đ ợc với nhau. Với sự lớn mạnh c a mạng Internet, các máy tính cài đặt các hệ
điều hành khác nhau đòi h i phải giao tiếp đ ợc với nhau, t c phải sử dụng chung một
giao th c. Đó chính là bộ giao th c TCP/IP, giao th c c a mạng Internet.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
5
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.4. Mạng TCP/IP
Đây là kiến trúc c a mạng Internet, chỉ gồm 5 tầng nh hình vẽ d ới đây:
Hình 1.5 - Kiến trúc mạng TCP/IP
Ng i ta còn gọi mô hình này là mô hình OSI đ n giản. Các giao th c đ ợc sử
dụng trên mỗi tầng đ ợc qui định nh sau:
Hình 1.6 – Bộ giao th c TCP/IP
Tầng 3 sử dụng giao th c IP, tầng 4 có thể sử dụng giao th c TCP
kết hoặc UPD chế độ không n i kết.
chế độ có n i
Tầng 5 là tầng c a các ng dụng. Mỗi loại ng dụng phải định nghĩa một giao th c
riêng để các thành phần trong ng dụng trao đổi thông tin qua lại với nhau. Một s ng
dụng phổ biến đã tr thành chuẩn c a mạng Internet nh :
•
•
•
•
ng dụng Web: Sử dụng giao th c HTTP để tải các trang web từ Web Server
về Web Browser.
ng dụng th điện tử: Sử dụng giao th c SMTP để chuyển tiếp mail g i đi
đến Mail Server c a ng i nhận và dùng giao th c POP3 hoặc IMAP để nhận
mail về cho ng i đọc.
ng dụng truyền tải tập tin: Sử dụng giao th c FTP để tải (download) các tập
tin từ các FTP Server xa về máy ng i dùng hay ng ợc lại.
.....
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
6
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Thông th ng các tầng 1,2,3 và 4 đ ợc phát triển b i các nhà sản xuất hệ điều
hành, nhà sản xuất các thiết bị phần c ng mạng. Chúng đảm nhận nhiệm vụ truyền tải
thông tin cho các quá trình trên tầng ng dụng. Chúng cài đặt các c chế giao tiếp liên quá
trình để các quá trình trên tầng ng dụng có thể truy xuất đến dịch vụ truyền tải thông tin
do chúng cung cấp. Trong khi đó, tầng 5 là n i các nhà sản xuất phần mềm khai thác để
tạo ra các ng dụng giải quyết các vấn đề khác nhau c a cuộc s ng. Nó đ ợc xem nh là
tầng xử lý thông tin.
1.5. Dịch vụ mạng
Dịch vụ mạng (Net service) là một ch
đó trên hệ th ng mạng.
ng trình ng dụng thực hiện một tác vụ nào
Ví dụ:
•
•
•
Dịch vụ in trên mạng cho phép nhiều máy tính cùng sử dụng một máy in.
Dịch vụ tập tin trên mạng cho phép chia sẻ ch
tính.
ng trình, dữ liệu giữa các máy
Dịch vụ web cung cấp các trang web cho các máy tính khác nhau
Có nhiều mô hình khác nhau để xây dựng các dịch vụ mạng. Một trong những mô
hình đ ợc sử dụng khá phổ biến là mô hình Client-Server. Đây là một mô hình c bản để
xây dựng các dịch vụ mạng.
1.6. Mô hình Client – Server
1.6.1. Giới thiệu
Trong mô hình này, ch
•
•
ng trình ng dụng đ ợc chia thành 2 thành phần:
Quá trình chuyên cung cấp một s phục vụ nào đó, chẳng hạn: phục vụ tập
tin, phục vụ máy in, phục vụ th điện tử, phục vụ Web... Các quá trình này
đ ợc gọi là các trình phục vụ hay Server.
Một s quá trình khác có yêu cầu sử dụng các dịch vụ do các server cung cấp
đ ợc gọi là các quá trình khách hàng hay Client.
Việc giao tiếp giữa client và server đ ợc
thực hiện d ới hình th c trao đổi các thông
điệp (Message). Để đ ợc phục vụ, client sẽ g i
một thông điệp yêu cầu (Request Message) mô
tả về công việc mu n server thực hiện. Khi
nhận đ ợc thông điệp yêu cầu, server tiến hành
phân tích để xác định công việc cần phải thực
thi. Nếu việc thực hiện yêu cầu này có sinh ra
kết quả trả về, server sẽ g i nó cho client trong
một thông điệp trả l i (Reply Message). Dạng
th c (format) và ý nghĩa c a các thông điệp
Hình 1.7 – Mô hình Client-Server
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
7
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
trao đổi giữa client và server đ ợc qui định rõ b i giao th c (protocol) c a ng dụng.
1.6.2. Ví dụ về dịch vụ Web.
Dịch vụ web đ ợc tổ ch c theo mô hình Client -Server, trong đó:
•
•
•
•
Web server sẵn sàng cung cấp các trang web đang đ ợc l u trữ trên đĩa c ng
cục bộ c a mình.
Web Client, còn gọi là các Browser, có nhu cầu nhận các trang web từ các
Web Server
HTTP là giao th c trao đổi thông tin qua lại giữa Web client và Web Server.
Thông điệp yêu cầu là một chuỗi có dạng sau:
Command URL
•
HTTP/Ver \n\n
Thông điệp trả l i có dạng sau:
<HEADER>\n\n
<CONTENT>
•
Giả sử Client cần nhận trang Web địa chỉ http://www.cit.ctu.edu.vn/, nó sẽ
g i đến Web Server có tên www.cit.ctu.edu.vn thông điệp yêu cầu sau:
GET www.cit.ctu.edu.vn HTTP/1.1\n\n
•
Server sẽ g i về nội dung sau:
HTTP/1.0 200 OK
Date: Mon, 24 Nov 2003 02:43:46 GMT
Server: Apache/1.3.23 (Unix) (Red-Hat/Linux) mod_ssl/2.8.7
OpenSSL/0.9.6b DAV/1
.0.3 PHP/4.1.2 mod_perl/1.26
Last-Modified: Tue, 01 Jul 2003 08:08:52 GMT
ETag: "17f5d-2abb-3f014194"
Accept-Ranges: bytes
Content-Length: 10939
Content-Type: text/html
X-Cache: HIT from proxy.cit.ctu.edu.vn
Proxy-Connection: close
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0
Transitional//EN">
<HTML>
<HEAD>
<LINK href="favicon.ico" rel="SHORTCUT ICON">
...............................
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
8
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.6.3. Các chế độ giao tiếp
Quá trình giao tiếp giữa client và server có thể diễn ra theo hai chế độ là nghẽn
(blocked) hay không nghẽn (Non blocked).
1.6.3.1. Chế độ nghẽn :
Trong chế độ này, khi quá trình
client hay server phát ra lệnh g i dữ liệu,
(thông th ng bằng lệnh send) , sự thực
thi c a nó sẽ bị tạm dừng cho đến khi
quá trình nhận phát ra lệnh nhận s dữ
liệu đó (th ng là lệnh receive).
T ng tự cho tr ng hợp nhận dữ
liệu, nếu quá trình nào đó, client hay
server, phát ra lệnh nhận dữ liệu, mà
th i điểm đó ch a có dữ liệu g i đến, sự
thực thi c a nó cũng tạm dừng cho đến
khi có dữ liệu g i đến.
1.6.3.2. Chế độ không nghẽn:
Hình 1.8 - Chế độ giao tiếp nghẽn
Trong chế độ này, khi quá trình client hay server phát ra lệnh g i dữ liệu, sự thực
thi c a nó vẫn đ ợc tiếp tục mà không
quan tâm đến việc có quá trình nào phát ra
lệnh nhận s dữ liệu đó hay không.
T ợng tự cho tr ng hợp nhận dữ
liệu, khi quá trình phát ra lệnh nhận dữ
liệu, nó sẽ nhận đ ợc s l ợng dữ liệu
hiện có (bằng 0 nếu ch a có quá trình nào
g i dữ liệu đến). Sự thực thi c a quá trình
vẫn đ ợc tiếp tục.
Trong thực tế cần chú ý đến chế độ
giao tiếp nghẽn khi lập trình, vì nó có thể
dẫn đến tr ng hợp ch ng trình bị "treo"
do s lần g i và nhận giữ liệu không bằng
nhau giữa hai bên giao tiếp.
1.7. Các kiểu kiến trúc ch
Hình 1.9 - Chế độ giao tiếp không nghẽn
ng trình
m c luận lý, các ch c năng mà một ch
thành một trong 3 loại sau:
ng trình ng dụng thực hiện có thể xếp
1. Các ch c năng thực hiện việc t ng tác với ng i dùng nh tạo các giao diện
nhập liệu hay in các báo biểu, thông báo ra màn hình. Các ch c năng này
đ ợc gọi chung là Dịch vụ giao diện ng ời dùng (User Interface Service).
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
9
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
2. Các ch c năng tính toán các dữ liệu, xử lý thông tin theo những qui luật
(rule), giải thuật đ ợc qui định b i vấn đề mà ng dụng giải quyết. Các ch c
năng này đ ợc gọi chung là Dịch vụ nghiệp vụ (Business Rule Service).
3. Trong quá trình tính toán, ch ng trình ng dụng cần truy vấn đến các thông
tin đã có đ ợc l u trên đĩa c ng hay trong các c sỡ dữ liệu. Cũng nh cần
thiết phải l u lại các kết quả tính toán đ ợc để sử dụng về sau. Các ch c
năng này đ ợc gọi chung là Dịch vụ l u trữ (Data Storage Service).
m c vật lý, các ch c năng này có thể đ ợc cài đặt vào một hay nhiều tập tin thực
thi hình thành các kiểu kiến trúc ch ng trình khác nhau. Cho đến th i điểm hiện nay,
ng i ta chia kiến trúc c a ch ng trình thành 3 loại đ ợc trình bày tiếp theo sau.
1.7.1. Kiến trúc đ n tầng (Single-tier Architecture)
Trong kiểu kiến trúc này, cả 3 thành phần c a ch ng trình ng dụng (User
Interface, Business Rule, Data Storage) đều đ ợc tích hợp vào một tập tin thực thi.
Ví dụ: BKAV, D2, Winword, . . .
Các ng dụng kiểu này chỉ đ ợc thực thi trên một máy tính.
User Interface
Business Rule
Data Storage
•
•
Hình 1.10 - Kiến trúc ch
ng trình đ n tầng
u điểm:
•
Dễ dàng trong thiết kế cài đặt ng dụng kiểu này.
Nh ợc điểm:
•
•
•
•
B i vì cả 3 thành phần đ ợc cài vào một tập tin thực thi, nên việc sửa lỗi hay
nâng cấp ch ng trình thì rất khó khăn. Toàn bộ ch ng trình phải biên dịch
lại cho dù chỉ sửa đổi một lỗi rất nh trong một thành phần nào đó ( User
Interface chẳng hạn).
Việc bảo trì, nâng cấp ấn bản mới là một công việc cực kỳ nặng nề vì ta phải
thực hiện việc cài đặt trên tất cả các máy tính.
Trong kiểu này, mỗi máy tính duy trì một c s dữ liệu riêng cho nên rất khó
trong việc trao đổi, tổng hợp dữ liệu.
Máy tính phải đ mạnh để có thể thực hiện đồng th i cả 3 loại dịch vụ.
1.7.2. Kiến trúc hai tầng (Two - Tier Architecture)
Kiến trúc này còn đ ợc biết đến với tên kiến trúc Client-Server. Kiến trúc này gồm
2 ch ng trình thực thi: ch ng trình Client và ch ng trình Server. Cả hai ch ng trình
có thể đ ợc thực thi trên cùng một máy tính hay trên hai máy tính khác nhau.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
10
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Client và Server trao đổi thông tin với nhau d ới dạng các thông điệp (Message) .
Thông điệp g i từ Client sang Server gọi là các thông điệp yêu cầu (Request Message) mô
tả công việc mà phần Client mu n Server thực hiện.
Hình 1.11 - Kiến trúc ch
ng trình Client-Server
Mỗi khi Server nhận đ ợc một thông điệp yêu cầu, Server sẽ phân tích yêu cầu,
thực thi công việc theo yêu cầu và g i kết quả về client (nếu có) trong một thông điệp trả
l i (Reply Message). Khi vận hành, một máy tính làm Server phục vụ cho nhiều máy tính
Client.
Mỗi một ng dụng Client-Server phải định nghĩa một Giao th c (Protocol) riêng
cho sự trao đổi thông tin, ph i hợp công việc giữa Client và Server. Protocol qui định một
s vấn đề c bản sau:
•
•
•
•
Khuôn dạng loại thông điệp.
S l ợng và ý nghĩa c a từng loại thông điệp.
Cách th c bắt tay, đồng bộ hóa tiến trình truyền nhận giữa Client và Server.
....
Thông th ng phần client đảm nhận các ch c năng về User Interface, nh tạo các
form nhập liệu, các thông báo, các báo biểu giao tiếp với ng i dùng.
Phần Server đảm nhận các ch c năng về Data Storage. Nh đó dễ dàng trong việc
bảo trì, chia sẻ tổng hợp dữ liệu trong toàn bộ công ty hoặc tổ ch c.
Các ch c năng về Business Rule có thể đ ợc cài đặt
server tạo ra hai loại kiến trúc Client - Server là:
o
Fat Client
o
Fat Server.
phần client hoặc
phần
1.7.2.1. Loại Fat Client
Trong loại này Business Rule đ ợc cài đặt bên phía Client. Phần Server ch yếu
thực hiện ch c năng về truy vấn và l u trữ thông tin.
Hình 1.12 - Kiến trúc ch
ng trình Client – Server theo kiểu Fat Client
u điểm
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
11
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
- Giáo Trình Lập Trình Truyền Thông
Tạo ra ít giao thông trên mạng nh dữ liệu tạm th i trong quá trình tính toán
đ ợc l u tại Client.
Nh ợc điểm
•
•
Vì Business Rule đ ợc cài đặt trên phía Client, đòi h i máy tính thực thi phần
Client phải đ mạnh, dẫn đến t n kém trong chi phí đầu t phần c ng cho các
công ty xí nghiệp.
Phải cài lại tất cả các máy tính Client khi nâng cấp ch ng trình.
1.7.2.2. Loại Fat Server
Trong loại này, phần lớn các ch c năng về Business Rule đ ợc đặt phần Server.
Phần Client chỉ thực hiện một s ch c năng nh c a Business Rule về kiểm tra tính hợp lệ
c a dữ liệu nhập b i ng i dùng.
Hình 1.13 - Kiến trúc ch
ng trình Client – Server theo kiểu Fat Server
u điểm
•
•
Vì Business Rule đ ợc đặt phần Server, các máy tính Client không cần phải
có cấu hình mạnh.
Việc nâng cấp ch ng trình khi Business Rule thay đổi tr nên nhẹ nhàng h n
vì chỉ phải cài đặt lại phần Server.
Nh ợc điểm
•
•
Tạo ra nhiều thông điệp trao đổi giữa Client và Server làm tăng giao thông
trên mạng.
Tăng tải trên máy Server vì nó phải đồng th i thực hiện các ch c năng c a
Business Rule và Data Storage làm giảm hiệu năng c a ch ng trình.
1.7.3. Kiến trúc đa tầng (N-Tier Architecture)
Đây là kiến trúc cho các ng dụng phân tán (Distributed Application). Thông
th ng là kiến trúc 3 tầng. Ch ng trình ng dụng đ ợc tách thành 3 phần riêng biệt t ng
ng cho 3 ch c năng User Interface, Business Rule và Data Storage. Vì các ch c năng
thuộc về Business Rule đ ợc tách thành một phần riêng, nó có thể đ ợc thực thi trên một
máy tính Server riêng giải quyết đ ợc hầu hết các nh ợc điểm mắc phải c a kiến trúc đ n
tầng và kiến trúc hai tầng nói trên.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
12
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Hình 1.12 - Kiến trúc ch
ng trình đa tầng
Kiến trúc này đáp ng t t với những thay đổi về qui luật xử lý dữ liệu c a vấn đề
mà ng dụng giải quyết. Việc thay đổi chỉ ảnh h ng trên tầng Business Rule mà không
ảnh h ng đến hai tầng còn lại.
Thông th
ng, ng
i ta gọi tên các thành phần trên là:
Client – Application Server – Database Server
1.8. Bài tập
1.8.1. Bài tập bắt buộc
Bài tập 1.1: Protocol HTTP
Tìm đọc và viết một báo cáo không quá 10 trang về giao th c HTTP.
Bài tập 1.2: Chat Protocol
Tìm hiểu về dịch vụ Chat trên mạng Internet. Viết một bảng báo cáo không qua 10
trang trình bày 2 nội dung sau:
•
•
Một bảng mô tả các ch c năng th ng đ ợc hỗ trợ trong một dịch vụ Chat.
Xây dựng Chat Protocol riêng c a bạn trong đó mô tả:
o Các ch c năng hỗ trợ b i Chat Server.
o Khuôn dạng (Format) và các loại thông điệp (Message) hỗ trợ b i
Protocol.
o S đồ trạng thái hoạt động c a server và client (giải thuật).
o Minh họa các kịch bản khác nhau cho từng ch c năng c a dịch vụ.
1.8.2. Bài tập gợi ý
Bài tập 1.3: POP3 Protocol
Tìm đọc và viết một báo cáo không quá 10 trang về giao th c POP3.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
13
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
CH
NG 2
S l ợc về ngôn ngữ Java
Mục đích
Ch ng này nhằm giới thiệu s l ợc về ngôn ngữ java cho các sinh viên đã có kiến
th c căn bản về Lập trình h ớng đ i t ợng với C++. Ch ng này sẽ không đề cập đến tất
cả các vấn đề có trong Java mà chỉ giới thiệu những vấn đề c bản nhất về ngôn ngữ Java,
đ để các học viên có thể đọc hiểu các ch ng trình minh họa và làm đ ợc các bài tập ng
dung các ch ng sau.
Yêu cầu
Sau khi hoàn tất ch
•
•
•
•
•
•
•
•
•
•
•
•
ng này, bạn có thể:
Trình bày đ ợc những vấn đề tổng quan về ngôn ngữ Java nh :
o Đặc điểm và khả năng c a ngôn ngữ Java.
o Khái niệm máy ảo c a Java (JVM - Java Virtual Machine ).
o Vai trò c a bộ phát triển ng dụng JDK (Java Developpment Kit).
o Phân biệt đ ợc hai kiểu ch ng trình Applet và Application c a Java.
o Các kiểu dữ liệu và các phép toán đ ợc hỗ trợ b i Java.
Biên soạn, biên dịch và thực thi thành công ch ng trình HelloWorld .
Sử dụng thành thạo các cấu trúc điều khiển d ới Java nh : if, switch, while,
do-while, for.
Biết cách nhận đ i s c a ch ng trình Java.
Biết đổi chuỗi thành s trong Java.
Sử dụng đ ợc c chế ngoại lệ c a Java.
Biết định nghĩa lớp mới, sử dụng một lớp đã có c a Java.
Giải thích đ ợc c chế vào ra với Stream trong Java.
Sử dụng thành thạo các ph ng th c c a hai lớp InputStream và
OutputStream.
Có thể nhập / xuất chuỗi trên một InputStream / OutputStream.
Giải thích đ ợc c chế luồng (Thread).
Cài đặt đ ợc các luồng trong Java.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
14
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.1. Giới thiệu về ngôn ngữ Java
1.1.1. Lịch sử phát triển
Năm 1990, Sun MicroSystems thực hiện dự án Green nhằm phát triển phần mềm
trong các thiết bị dân dụng. James Gosling, chuyên gia lập trình đã tạo ra một ngôn ngữ
lập trình mới có tên là Oak. Ngôn ngữ này có cú pháp gần gi ng nh C++ nh ng b qua
các tính năng nguy hiểm c a C++ nh truy cập trực tiếp tài nguyên hệ th ng, con tr , định
nghĩa chồng các tác tử…
Khi ngôn ngữ Oak tr ng thành, WWW cũng đang vào th i kỳ phát triển mạnh mẽ,
Sun cho rằng đây là một ngôn ngữ thích hợp cho Internet. Năm 1995, Oak đổi tên thành
Java và sau đó đến 1996 Java đã đ ợc xem nh một chuẩn công nghiệp cho Internet.
1.1.2. Khả năng c a ngôn ngữ Java
•
•
•
•
•
•
Là một ngôn ngữ bậc cao nh C, C++, Perl, SmallTalk,.. cho nên có thể đ ợc
dùng để tạo ra các ng dụng để giải quyết các vấn đề về s , xử lý văn bản, tạo
ra trò ch i, và nhiều th khác.
Có các môi tr ng lập trình đồ họa nh Visual Java, Symantec Cafe,
Jbuilder, Jcreator, ...
Có khả năng truy cập dữ liệu từ xa thông qua cầu n i JDBC (Java DataBase
Connectivity)
Hỗ trợ các lớp hữu ích, tiện lợi trong lập trình các ng dụng mạng (Socket)
cũng nh truy xuất Web.
Hỗ trợ lập trình phân tán (Remote Method Invocation ) cho phép một ng
dụng có thể đ ợc xử lý phân tán trên các máy tính khác nhau.
Và luôn đ ợc bổ sung các tính năng cao cấp khác trong các phiên bản sau.
1.1.2. Những đặc điểm c a ngôn ngữ Java
•
•
•
•
•
•
•
Ngôn ngữ hoàn toàn h ớng đ i t ợng.
Ngôn ngữ đa nền cho phép một ch ng trình có thể thực thi trên các hệ điều
hành khác nhau (MS Windows, UNIX, Linux) mà không phải biên dịch lại
ch ng trình. Ph ng châm c a java là "Viết một lần , Chạy trên nhiều
nền" (Write Once, Run Anywhere).
Ngôn ngữ đa luồng, cho phép trong một ch ng trình có thể có nhiều luồng
điều khiển đ ợc thực thi song song nhau, rất hữu ích cho các xử lý song song.
Ngôn ngữ phân tán, cho phép các đ i t ợng c a một ng dụng đ ợc phân b
và thực thi trên các máy tính khác nhau.
Ngôn ngữ động, cho phép mã lệnh c a một ch ng trình đ ợc tải từ một máy
tính về máy c a ng i yêu cầu thực thi ch ng trình.
Ngôn ngữ an toàn, tất cả các thao tác truy xuất vào các thiết bị vào ra đều thực
hiện trên máy ảo nh đó hạn chế các thao tác nguy hiểm cho máy tính thật.
Ngôn ngữ đ n giản, dễ học, kiến trúc ch ng trình đ n giản, trong sáng.
1.1.3. Máy ảo Java (JMV - Java Virtual Machine)
Để đảm bảo tính đa nền, Java sử dụng c chế Máy ảo c a Java. ByteCode đó là
ngôn ngữ máy c a Máy ảo Java t ng tự nh các lệnh nhị phân c a các máy tính thực.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
15
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Một ch ng trình sau khi đ ợc viết bằng ngôn ngữ Java (có phần m rộng là .java) phải
đ ợc biên dịch thành tập tin thực thi đ ợc trên máy ảo Java (có phần m rộng là .class).
Tập tin thực thi này ch a các chỉ thị d ới dạng mã Bytecode mà máy ảo Java hiểu đ ợc
phải làm gì.
Khi thực hiện một ch ng trình, máy ảo Java lần l ợt thông dịch các chỉ thị d ới
dạng Bytecode thành các chỉ thị dạng nhị phân c a máy tính thực và thực thi thực sự
chúng trên máy tính thực.
Máy ảo thực tế đó là một ch ng trình thông dịch. Vì thế các hệ điều hành khác
nhau sẽ có các máy ảo khác nhau. Để thực thi một ng dụng c a Java trên một hệ điều
hành cụ thể, cần phải cài đặt máy ảo t ng ng cho hệ điều hành đó.
1.1.4. Hai kiểu ng dụng d ới ngôn ngữ java
Khi bắt đầu thiết kế một ng dụng d ới ngôn ngữ Java, bạn phải chọn kiểu cho nó
là Application hay Applet.
•
Applet: Là một ch ng trình ng dụng đ ợc nhúng vào các trang web. Mã
c a ch ng trình đ ợc tải về máy ng i dùng từ Web server khi ng i dùng
truy xuất đến trang web ch a nó.
Application: Là một ch ng trình ng dụng đ ợc thực thi trực tiếp trên các
máy ảo c a Java.
•
1.1.5. Bộ phát triển ng dụng Java (JDK- Java Development Kit)
JDK là một bộ công cụ cho phép ng i lập trình phát triển và triển khai các ng
dụng bằng ngôn ngữ java đ ợc cung cấp miễn phí b i công ty JavaSoft (hoặc Sun). Có các
bộ Jdk cho các hệ điều hành khác nhau. Các ấn bản c a JDK không ngừng đ ợc phát
hành, các bạn có thể tải về từ địa chỉ http://java.sun.com hoặc http://www.javasoft.com
Bộ công cụ này gồm các ch ng trình thực thi đáng chú ý sau:
• javac: Ch ng trình biên dịch các ch ng trình nguồn viết bằng ngôn ngữ
java ra các tập tin thực thi đ ợc trên máy ảo Java.
• java: Đây là ch ng trình làm máy ảo c a Java, thông dịch mã Bytecode c a
các ch ng trình kiểu application thành mã thực thi c a máy thực.
• appletviewer: Bộ thông dịch, thực thi các ch ng trình kiểu applet.
• javadoc: Tạo tài liệu về chú thích ch ng trình nguồn một cách tự động.
• jdb: Trình g r i.
• rmic: Tạo Stub cho ng dụng kiểu RMI.
• rmiregistry: Phục vụ danh bạ (Name Server) trong hệ th ng RMI
1.1.6. Kiểu dữ liệu c bản d ới Java
•
Kiểu s
Tên kiểu
byte
short
int
long
float
double
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
Kích th ớc
1 byte
2 bytes
4 bytes
8 bytes
4 bytes
8 bytes
16
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
- Giáo Trình Lập Trình Truyền Thông
Kiểu ký tự char
Java dùng 2 bytes cho kiểu ký tự, theo chuẩn mã UNICODE ( 127 ký tự đầu
t ng thích với mã ASCII). Do đó, ta sử dụng t ng tự nh bảng mã ASCII.
•
Kiểu chuỗi ký tự String
Thực chất đây là một lớp nằm trong th viện chuẩn c a Java (Core API),
java.lang.String
•
Kiểu luận lý boolean
Nhận 2 giá trị là : true và false.
•
Kiểu mảng
o
o
o
Khai báo:
int[] a ; float[] yt; String[] names;
hoặc: int a[]; float yt[]; String names[];int maTran[][]; float
bangDiem[][];
Kh i tạo:
a = new int[3]; yt = new float[10]; names = new String[50];
maTran = int[10][10];
Sử dụng mảng:
int i = a[0]; float f = yt[9]; String str = names[20]; int x =
matran [2][5];
1.1.7. Các phép toán c bản
Các phép toán trong Java cũng t
•
•
•
•
•
ng tự nh trong C++.
Phép toán s học: +, - , *, / , % , =,++ , -- , += , - = , *= , /= , %=
Phép toán logic ==, !=, && , ||, ! ,> , < , >= , <=
Phép toán trên bit : & , | , ^ , << , >> , ~
Phép toán điều kiện : ? :
Cách chuyển đổi kiểu: (Kiểu Mới)
1.1.8. Qui cách đặt tên trong Java
Tên hằng, tên biến, tên lớp, tên ph
ng th c , ... đ ợc đặt tên theo qui tắc bắt buộc
sau:
•
•
•
•
Tên phân biệt giữa chữ hoa và chữ th ng.
Dùng các chữ cái, ký tự s , ký tự _ và $.
Không bắt đầu bằng ký tự s .
Không có khoảng trắng trong tên.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
17
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Để ch ng trình nguồn dễ đọc, dễ theo dõi ng
(không bắt buộc):
•
•
•
i ta còn sử dụng quy ớc đặt tên sau
Tên lớp:
o Các ký tự đầu tiên c a một từ đ ợc viết hoa,
o Các ký tự còn lại viết th ng.
o Ví dụ: lớp Nguoi, SinhVien, MonHoc, String, InputStream,
OutputStream. . .
Tên biến, tên hằng, tên ph ng th c:
o Từ đầu tiên viết th ng.
o Ký tự đầu tiên c a từ th
hai tr đi đ ợc viết hoa.
Ví dụ: ten, ngaySinh, diaChi, inTen(), inDiaChi(), getInputStream(), . .
.
Vị trí đặt dấu { và } để bắt đầu và kết thúc các kh i nh sau:
if (condition) {
command1;
command1;
} else {
command3;
command4;
}
1.2. Ch
ng trình ng dụng kiểu Application
Java là một ngôn ngữ thuần đ i t ợng (pure object). Tất cả các thành phần đ ợc
khai báo nh hằng, biến, hàm th tục đều phải nằm trong phạm vi c a một lớp nào đó.
Một ng dụng trong Java là một tập hợp các lớp liên quan nhau, bao gồm các lớp trong th
viện do Java cung cấp và các lớp đ ợc định nghĩa b i ng i lập trình. Trong một ng dụng
chỉ có một Lớp thực thi đ ợc. Đây là lớp đầu tiên đ ợc xem xét đến khi chúng ta thực thi
ng dụng.
Lớp thực thi đ ợc này có các đặc điểm sau:
•
•
•
•
Có tên lớp trùng với tên tập tin ch a nó.
Phải khai báo phạm vi là public
Có ch a ph ng th c:
public static void main (String args[]){
...
}
là ph ng th c đ ợc thực thi đầu tiên.
Nếu nhiều lớp đ ợc định nghĩa trong một tập tin, chỉ có một lớp đ ợc khai
báo public.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
18
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
1.2.1. Ch
- Giáo Trình Lập Trình Truyền Thông
ng trình HelloWorld
Trong ví dụ này, chúng ta viết một ch ng trình ng dụng in ra màn hình dòng chữ
"Hello World !". Đây là ng dụng đ n giản chỉ có một lớp thực thi đ ợc tên là
HelloWorld. Lớp này đ ợc khai báo là public, có ph ng th c main(), ch a trong tập tin
cùng tên là HelloWorld.java (phần m rộng bắt buộc phải là .java).
Ph
ng th c System.out.print() sẽ in tất cả các tham s trong dấu () c a nó ra màn
hình.
Ta có thể dùng bất kỳ ch ng trình soạn thảo văn bản nào để biên soạn ch
trình. Nh ng nhớ phải ghi lại với phần m rộng là .java.
1.2.3. Biên soạn ch
ng
ng trình bằng phần mềm Notepad c a Ms Windows
Notepad là trình soạn thảo đ n giản có sẵn trong MS Windows mà ta có thể dùng
để biên soạn ch ng trình HelloWorld. Hãy thực hiện các b ớc sau:
•
•
Chạy ch ng trình Notepad:
o Chọn menu Start \ Programs \ Accessories \ Notepad
Nhập nội dung sau vào Notepad
public class HelloWorld {
public static void main(String args[]) {
System.out.print("Hello World! \n");
}
}
•
Save tập tin với tên HelloWorld.java
o Chọn menu File \ Save
o Tại cửa sổ Save As hãy nhập vào:
Save in: Th mục n i sẽ l u tập tin
File Name: HelloWorld.java
Save as type: All Files
Nhấp vào nút Save
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
19
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.2.4. Cài đặt bộ phát triển ng dụng JDK
•
•
•
•
Chuẩn bị bộ nguồn cài đặt JDK phù hợp với hệ điều hành sử dụng (Giả sử
Windows 2000)
Chạy tập tin Setup.exe
Chọn n i cài đặt, giả sử D:\jdk1.4
Đặt biến môi tr ng
o PATH = D:\jdk1.4\bin; để có thể thực thi các ch ng trình này từ bất
kỳ th mục hiện hành nào.
o CLASSPATH = D:\jdk1.4\lib;.; chỉ đến các lớp th viện c a Java trong
th mục D:\jdk1.4\lib và các lớp tại th mục hiện hành, thể hiện bằng
dấu chấm( . ).
1.2.5. Biên dịch và thực thi ch
•
•
•
ng trình
M cửa sổ MS-DOS: Chọn menu Start \ Programs \ Accessories \ Command
Prompt.
Chuyển vào th mục ch a tập tin HelloWorld.java
Dùng ch ng trình javac để biên dịch tập tin HelloWorld.java
javac HelloWorld.java
Nếu có lỗi, trên màn hình sẽ xuất hiện thông báo lỗi với dấu ^ chỉ vị trí
lỗi.
o Nếu không có lỗi, tập tin thực thi HelloWorld.class đ ợc tạo ra.
Thực thi ch ng trình HelloWorld.class
o
•
java HelloWorld
Trên màn hình sẽ xuất hiện dòng chữ Hello World!
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
20
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.2.6. Một s ví dụ
1.2.6.1. Hiển thị thông tin ra màn hành
Để in thông tin ra màn hình bạn dùng ph
ng th c
System.out.print(arg1+ arg2+ .. + argn)
Java sẽ tự động định dạng dữ liệu cho các tham s arg1, arg2, ..., argn tùy theo kiểu
c a chúng.
Hãy l u ch
ng trình sau vào tập tin Display.java:
public class Display {
public static void main(String args[]) {
int i = 10;
String str = " nam yeu ";
char ch = 'm';
System.out.print('\n'+ "Bai hat:" + i + str + ch);
}
}
Biên dịch và thực thi ta có kết quả :
Ph ng th c System.out.println(arg1+ arg2+ .. + argn) in các tham s và tự
động xu ng dòng mới.
1.2.6.2. Đọc ký tự từ bàn phím
Ph ng th c int System.int.read() trả một s nguyên là mã ASCII c a ký tự nhập từ
bàn phím.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
21
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
Hãy l u ch
- Giáo Trình Lập Trình Truyền Thông
ng trình sau vào tập tin KeyRead.java
import java.io.*;
public class KeyRead {
public static void main(String args[]) {
try {
int ch = System.in.read();
System.out.print("Ky tu " + (char)ch + " co ma ascii = "+ch);
} catch(IOException ie) {
System.out.print("Error " + ie) ;
}
}
}
Biên dịch và thực thi ta có kết quả :
Trong ví dụ trên l u ý một s điểm sau:
•
•
Dòng đầu tiên import java.io.*; là c chế để khai báo với trình biên
dịch các lớp th viện c a Java mà ch ng trình có sử dụng đến. Trong tr ng
hợp này ch ng trình khai báo sử dụng tất cả các lớp trong gói (package)
java.io. Thực tế ch ng trình trên chỉ sử dụng lớp IOException c a gói
java.io mà thôi, vì thế ta có thể thay thế dòng java.io.*; bằng
java.io.IOException;.
C chế ngoại lệ (Exception) c a java:
try {
....
} catch(IOException ie) {
....
}
sẽ đ ợc giải thích rõ
phần sau.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
22
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3. Các cấu trúc điều khiển trong Java
1.3.1. Lệnh if – else
Cú pháp:
if (Condition) {
// Các lệnh sẽ đ ợc thực hiện nếu giá trị c a Condition là true
}
if (Condition) {
// Các lệnh sẽ đ ợc thực hiện nếu giá trị c a Condition là true
} else {
// Các lệnh sẽ đ ợc thực hiện nếu giá trị c a Condition là false
}
Ví dụ:
L u ch
ng trình sau vào tập tin IfDemo.java :
import java.io.*;
public class IfDemo {
public static void main(String args[]) {
System.out.print("Vui long nhap mot ky tu:");
try {
int ch = System.in.read();
if (ch == 'A') {
System.out.print("Ban rat may man !");
}
else {
System.out.print("Ban khong gap may !");
}
} catch(IOException ie) {
System.out.print("Error:"+ie);
}
}
}
Biên dich và thực thi có kết quả nh sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
23
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3.2. Phép toán ?
Cú pháp:
(condition) ? Operation1 : Operation2;
Nếu điều kiện condition có giá trị là true lệnh sẽ trả về giá trị c a biểu th c
Operation1, ng ợc lại sẽ trả về giá trị c a biểu th c Operation2.
Ví dụ:
L u ch
ng trình sau vào tập tin QuestionOp.java :
import java.io.*;
public class QuestionOp {
public static void main(String args[]) {
System.out.print("Vui long nhap mot ky tu:");
try {
int ch = System.in.read();
int point = (ch == 'A') ? 10:0;
System.out.print("Diem cua ban la:"+point);
} catch(IOException ie) {
System.out.print("Error:"+ ie);
}
}
}
Biên dịch và thực thi đ ợc kết quả nh sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
24
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3.3. Lệnh switch
Cú pháp
switch ( variable ) {
case value1 : {
Task 1;
// Các tác vụ sẽ đ ợc thực thi nếu giá trị c a variable là value1
break;
}
case value2 : {
Task 2;
// Các tác vụ sẽ đ ợc thực thi nếu giá trị c a variable là value2
break;
}
...
default:
Task n;
// Tác vụ sẽ đ ợc thực thi nếu giá trị c a variable không là các giá trị trên
}
Ví dụ
L u ch
ng trình sau vào tập tin CaseOp.java
import java.io.*;
public class CaseOp {
public static void main(String args[]) {
System.out.print("Enter a number character: ");
try {
int ch = System.in.read();
switch(ch) {
case '0': { System.out.print("Zero");break;}
case '1': { System.out.print("One"); break;}
case '2': { System.out.print("Two"); break;}
case '3': { System.out.print("Three");break;}
case '4': { System.out.print("Four"); break;}
case '5': { System.out.print("Five"); break;}
case '6': { System.out.print("Six"); break;}
case '7': { System.out.print("Seven");break;}
case '8': { System.out.print("Eight");break;}
case '9': { System.out.print("Nine"); break;}
default: { System.out.print("I don't know"); break;}
}
} catch(IOException ie) {
System.out.print("Error "+ie);
}
}
}
Biên dịch và thực thi đ ợc kết quả sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
25
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3.4. Lệnh while
Cú pháp
while (condition) {
// nếu condition có giá trị là true, thì các tác vụ
}
đây sẽ đ ợc lặp lại
Ví dụ
L u ch
ng trình sau vào tập tin WhileDemo.java
import java.io.*;
public class WhileDemo {
public static void main(String args[]) {
int num = '9';
while (num > '0') {
System.out.print((char)num +" ");
num--;
}
}
}
Biên dịch và thực thi đ ợc kết quả sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
26
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3.5. Lệnh do - while
Cú pháp
do {
// Lặp lại các tác vụ
} while (condition)
Ví dụ: L u ch
đây cho đến khi điều kiện condition có giá trị là false
ng trình sau vào tập tin DoWhileDemo.java
import java.io.*;
public class DoWhileDemo {
public static void main(String args[]) {
int num = '9';
do {
System.out.print((char)num +" ");
num--;
} while (num > '0');
}
}
Biên dịch và thực thi đ ợc kết quả sau:
1.3.6. Lệnh for
Cú pháp
for (operation1; condition; operation2){
// Các tác vụ đ ợc lặp lại
}
T
ng đ
ng nh cấu trúc sau:
operation1;
while (condition) {
// Các tác vụ đ ợc lặp lại
operation2;
}
Ví dụ
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
27
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
L u ch
- Giáo Trình Lập Trình Truyền Thông
ng trình sau vào tập tin ForDemo.java
import java.io.*;
public class ForDemo {
public static void main(String args[]) {
for(int num = '9'; num>'0'; num --) {
System.out.print((char)num +" ");
}
}
}
Biên dịch và thực thi đ ợc kết quả nh sau:
1.3.7. Lệnh break
Vòng lặp c a các lệnh while, do-while và for sẽ kết thúc khi lệnh break đ ợc thực
hiện.
Ví dụ
L u ch
ng trình sau vào tập tin BreakDemo.java
import java.io.*;
public class BreakDemo {
public static void main(String args[]){
int num =Integer.valueOf(args[0]).intValue();
int i= num / 2;
while(true){
if (num % i ==0) break;
i--;
}
System.out.println("So lon nhat chia het "+num+ " la: "+i);
}
}
Biên dịch và thực thi đ ợc kết quả sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
28
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Ch ng trình trên đổi đ i s th nhất c a nó (l u trong args[0]) thành s ( bằng
lệnh Integer.valueOf(args[0]).inValue() ) và tìm s lớn nhất chia hết s này.
1.3.8. Lệnh continue
Trong một lần lặp nào đó c a các lệnh while, do-while và for, nếu gặp lệnh
continue thì lần lặp sẽ kết thúc (b qua các lệnh phía sau continue) để bắt đầu lần lặp tiếp
theo.
Ví dụ: L u ch
ng trình sau vào tập tin ContinueDemo.java
import java.io.*;
public class ContinueDemo{
public static void main(String args[]){
int num =Integer.valueOf(args[0]).intValue();
System.out.print("The odd numbers: ");
for (int i =0; i< num; i++ ){
if (i % 2 ==0) continue;
System.out.print(i+ " ");
}
}
}
Biên dịch và thực thi đ ợc kết quả sau:
Ch
ng trình này in ra tất cả các s lẻ nh h n s đ a vào từ đ i s .
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
29
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3.9. Một s vấn đề khác
1.3.9.1. Đọc đ i s c a ch
Khi thực thi ch
ng trình
ng trình ta có thể nhập vào các đ i s từ dòng lệnh theo cú pháp
sau:
java ClassName arg1 arg2 arg3 argn
Các đ i s cách nhau khoảng trắng. Để đón nhận các đ i s này, ph
bắt buộc phải khai báo một tham s kiểu mảng các chuỗi
ng th c main
public static void main(String args[ ] ) {
…
}
Các đ i s i s lần l ợt đ ợc đặt vào các phần tử c a mảng này. S l ợng đ i s có
thể xác định đ ợc bằng cách truy xuất thuộc tính args.length c a mảng.
Ví dụ
L u ch
ng trình sau vào tập tin PrintArgs.java
public class PrintArgs {
public static void main (String args[]) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
Biên dịch và thực thi ch
ng trình đ ợc kết quả sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
30
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3.9.2. Đổi chuỗi thành s
L u ch
ng trình sau vào tập tin StringToNumber.java
public class StringToNumber{
public static void main (String args[]) {
int i = Integer.valueOf( args[0]).intValue();
long l = Long.valueOf( args[1]).longValue();
float f = Float.valueOf( args[2]).floatValue();
System.out.println("Integer number = "+i );
System.out.println("Long number = "+l );
System.out.println("Float number = "+f );
}
}
Biên dịch và thực thi ch
ng trình đ ợc kết quả sau:
1.4. Ngoại lệ (EXCEPTION)
Trong ch ng trình, có một s các "thao tác không chắc chắn", ví dụ nh các thao
tác vào/ra: đĩa mềm ch a sẵn sàng, máy in có lỗi, n i kết mạng không thực hiện đ ợc . . .
sẽ dẫn đến lỗi thực thi ch ng trình.
Java hạn chế các lỗi sinh ra từ "thao tác không chắc chắn" bằng c chế Ngoại lệ
(Exception).
Ngoại lệ t c là một sự kiện xảy ra ngoài dự tính c a ch ng trình nếu không xử lý
sẽ làm cho ch ng trình chuyển sang trạng thái không còn kiểm soát đ ợc. Ví dụ điều gì
sẽ xảy ra nếu ch ng trình truy xuất đến phần tử th 11 c a một mảng 10 phần tử ? Một s
ngôn ngữ nh C, C++ sẽ không báo lỗi gì cả, ch ng trình vẫn tiếp tục vận hành nh ng
kết quả thì không thể xác định đ ợc.
Để hạn chế những lỗi nh thế, Java bắt buộc các lệnh có thể dẫn đến các ngoại lệ
phải có các đoạn mã xử lý phòng h khi ngoại lệ xảy ra theo cú pháp sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
31
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
try {
Các thao tác vào ra có thể sinh ra các ngoại lệ.
}
catch (KiểuNgoạiLệ_01 biến) {
ứng xử khi ngoại lệ KiểuNgoaiLệ_01 sinh ra
} catch (KiểuNgoạiLệ_02 biến) {
ứng xử khi ngoại lệ KiểuNgoaiLệ_02 sinh ra
}finally { Công việc luôn luôn được thực hiện }
Trong c chế này, các lệnh có thể tạo ra ngoại lệ sẽ đ ợc đ a vào trong kh i bao
bọc b i từ khóa try {}. Tiếp theo đó là một loạt các kh i catch{}. Một lệnh có thể sinh ra
một hoặc nhiều loại ngoại lệ. ng với một loại ngoại lệ sẽ có một kh i catch{} để xử lý
cho loại ngoại lệ đó. Tham s c a catch chỉ ra loại ngoại lệ mà nó có trách nhiệm xử lý.
Khi thực thi ch ng trình, nếu một lệnh nào đó nằm trong kh i try{} tạo ra ngoại lệ, điều
khiển sẽ đ ợc chuyển sang các lệnh nằm trong các kh i catch{} t ng ng với loại ngoại
lệ đó. Các lệnh phía sau lệnh tạo ra ngoại lệ trong kh i try{} sẽ bị b qua. Các lệnh nằm
trong kh i finally{} thì luôn luôn đ ợc thực hiện cho dù có xảy ra ngoại lệ hay là không.
Kh i lệnh finally{} là tùy chọn có thể không cần.
Ngoại lệ có loại bắt buộc phải xử lý, t c phải có try{}, có catch{} khi sử dụng
lệnh đó. Ví dụ nh lệnh đọc từ bàn phím. Trình biên dịch c a java sẽ báo lỗi nếu chúng ta
không xử lý chúng.
Ng ợc lại, có loại ngoại lệ không bắt buộc phải xử lý, ví dụ nh truy xuất đến phần
tử bên ngoài chỉ s mảng.
ph
Tra c u tài liệu đặc tả các API c a java để biết đ ợc các ngoại lệ tạo ra từ một
ng th c.
Ví dụ:
L u ch
ng trình sau vào tập tin ExceptionDemo.java :
public class ExceptionDemo {
public static void main(String[] args) {
try {
System.out.println("Hello " + args[0]);
}
catch (ArrayIndexOutOfBoundsException e){
System.out.println("Hello Whoever you are.");
}
finally {
System.out.println("How are you?");
}
}
}
Biên dịch và thực thi có kết quả nh sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
32
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Trong ch ng trình trên chúng ta dự định sẽ chào ng i đ ợc đ a vào từ đ i s th
nhất c a ch ng tình (đ ợc ch a trong phần tử args[0]). Tuy nhiên nếu ng i dùng thực
thi ch ng trình quên đ a vào đ i s , t c phần tử args[0] không tồn tại. Ngoại lệ báo hiệu
truy xuất đến phần tử nằm ngoài mảng (ArrayIndexOutOfBoundsException)
đ ợc quẳng ra (throw). Khi đó đoạn mã lệnh trong kh i catch có tham s là loại ngoại lệ
ArrayIndexOutOfBoundsException sẽ đ ọc thực hiện.
1.5. Một s vấn đề liên quan đến lớp trong Java
1.5.1. Định nghĩa lớp mới
Ngoài các lớp đ ợc định nghĩa sẵn trong th viện chuẩn c a java, các lập trình viên
có thể định nghĩa thêm các lớp c a mình theo cú pháp sau:
class ClassName {
// Danh sách các thuộc tính thuộc lớp
DataType01 attribute1, attribute2, . .;
DataType02 attribute3, attribute4, . .;
// Danh sách các ph ng th c thuộc lớp
ClassName([DataType parameter, DataType parameter]) {
// Constructor
...
}
void method01() {
...
}
DataType method02( . . .) {
...
return xx;
}
}
ClassName là tên lớp mới đang đ ợc định nghĩa.
Tạo đ i t ợng tên obj thuộc lớp ClassName.
ClassName obj = new ClassName();
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
33
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Ví dụ: Định nghĩa một lớp có:
•
•
•
•
•
Tên là Person
Hai thuộc tính là name và address
Ph ng th c kh i tạo có hai tham s để gán giá trị kh i động cho hai thuộc
tính.
Ph ng th c void display() cho biết ng i đó tên là gì, địa chỉ đâu.
Ph ng th c main() tạo ra một đ i t ợng tên là tom thuộc lớp Person
L u ch
ng trình sau vào tập tin Person.java
public class Person{
String name;
//Thuộc tính
String address; //Thuộc tính
Person(String n, String address) { // Ph ng th c kh i tạo
name = n;
this.address = address;
}
void display(){
// Hiển thị tên và địa chỉ
System.out.print(name + " is at "+ address);
}
public static void main(String args[]){
Person tom = new Person("Tom","Disney Land"); // Tạo đ i t ợng
tom.display(); // Gọi ph ng th c c a đ i t ợng
}
}
Biên dịch và thực thi ta đ ợc kết quả:
1.5.2. Phạm vi nhìn thấy c a một lớp
Một lớp đ ợc định nghĩa và cài đặt bên trong một tập tin. Một tập tin có thể ch a
một hoặc nhiều lớp. Trong một tập tin, chỉ có một lớp đ ợc khai báo là public (phía tr ớc
từ khóa class), các lớp còn lại phải là private (mặc nhiên). Một lớp đ ợc khai báo là public
sẽ đ ợc nhìn thấy b i các lớp khác cùng tập tin hay khác tập tin với nó. Ng ợc lại các
lớp private chỉ đ ợc nhìn thấy b i các lớp nằm cùng tập tin với nó mà thôi.
Ví dụ: Trong ví dụ này, chúng ta tách ph ng th c main ra kh i lớp Person và đ a
nó vào lớp mới MultiClass. L u hai lớp này vào trong cùng một tập tin tên là
MultiClass.java, với lớp MultiClass đ ợc khai báo là public, lớp Person khai báo private.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
34
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
// Lớp có phạm vi public có thể tham khảo từ bên ngoài tập tin
public class MultiClass {
public static void main(String args[]){
Person tom = new Person("Tom","Disney Land");
tom.display();
}
}
// Lớp có phạm vi private chỉ có thể tham khảo b i các lớp nằm cùng tập tin
class Person{
String name;
String address;
Person(String n, String address) {
name = n;
this.address = address;
}
void display(){
System.out.println(name + " is at "+ address);
}
}
Biên dịch và thực thi ta đ ợc kết quả:
1.5.3. Tính thừa kế
•
•
•
Một lớp chỉ có thể có một lớp cha (thừa kế đ n).
Lớp cha đ ợc tham khảo từ lớp con b i từ khóa super.
Dùng từ khóa extends để khai báo thừa kế.
Cú pháp:
class A extends B { // Khai báo A thừa kế từ B
...
}
Ví dụ: Định nghĩa lớp Client có các đặc điểm sau:
•
•
•
•
Thừa kế từ lớp Person.
Có thêm thuộc tính: telephone và buy (l ợng hàng mua).
Có ph ng th c kh i tạo.
Định nghĩa lại ph ng th c void display() c a lớp cha.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
35
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
L u ch
- Giáo Trình Lập Trình Truyền Thông
ng trình sau vào tập tin Client.java
public class Client extends Person{
int telephone;
long buy;
public Client(String n, String a, int t, long b) {
super(n,a);
telephone=t;
buy=b;
}
public void display() {
super.display();
System.out.println( ", Number of telephone:"+ telephone + ", buy: "+
buy );
}
public static void main(String args[]){
Client tom = new Client("Tom","Disney Land",123456,1000);
tom.display();
}
}
Biên dịch và thực thi ta đ ợc kết quả:
1.6. Vào / Ra với Stream
Stream là một dòng liên tục, có th tự các bytes dữ liệu chảy giữa ch ng trình và
các thiết bị ngoại vi. Nó là khái niệm trừu t ợng giúp giảm bớt các thao tác vào ra ph c
tạp đ i với ng i lập trình. Nó cho phép n i kết nhiều loại thiết bị ngoại vi khác nhau với
ch ng trình.
Nếu dòng dữ liệu trong Stream có h ớng chảy từ thiết bị ngoại vi vào ch ng trình
thì ta nói đây là Stream nhập (Input Stream), ng ợc lại là Stream xuất (Output Stream).
Đ i với Java, các thiết bị chỉ nhập, nh bàn phím, sẽ có các Stream nhập n i với nó,
các thiết bị chỉ xuất, nh màn hình, sẽ có các stream xuất n i với nó , các thiết bị vừa xuất,
vừa nhập, nh đĩa từ, thì có cả stream nhập và xuất n i với nó.
Để giao tiếp với các thiết bị ngoại vi, ch ng trình tr ớc tiên phải lấy đ ợc các
stream nhập / xuất gắn với thiết bị ngoại vi này. Sau đó, ch ng trình có thể g i dữ liệu ra
ngoại vi bằng thao tác ghi vào Stream xuất c a ngoại vi. Ng ợc lại, ch ng trình có thể
nhận dữ liệu từ ngoại vi bằng thao tác đọc stream nhập c a ngoại vi đó.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
36
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Nh vậy, ch ng trình chỉ làm việc trên các stream nhập và stream xuất, mà không
quan tâm đến đặc điểm riêng biệt c a thiết bị ngoại vi n i với Stream. Điều này giúp
ch ng trình giao tiếp với hệ th ng mạng cũng dễ dàng nh giao tiếp với màn hình, bàn
phím hay đĩa từ.
Một điểm khác cần l u ý là stream bao gồm những bytes r i rạc. Những bytes này
mô tả những dạng dữ liệu khác nhau. Ví dụ một s integer khi viết vào stream sẽ chuyển
thành 4 bytes. Vì thế cần phải có các thao tác chuyển đổi dữ liệu nhận và g i giữa ch ng
trình và stream.
Java hỗ trợ hai các lớp stream c bản trong gói java.io là:
•
•
java.io.InputStream: Stream nhập
java.io.OutputStream: Stream xuất
Ngoài ra còn có các lớp Stream thừa kế từ hai lớp trên nhằm mục đích cung cấp các
tiện ích cho các loại thiết bị vào ra chuyên biệt nh : FileInputStream, FileOutputStream,
PipedInputStream, PipedOutputStream, . . .
1.6.1. Lớp java.io.InputStream
Là loại stream cho phép ch
c bản sau:
ng trình nhận dữ liệu từ ngoại vi. Có các ph
ng th c
int read() throws IOException :
Đọc 1 byte từ Stream
•
•
Return 0-255 : Mã ASCII c a byte nhận đ ợc từ ngoại vi
-1 : Stream đã kết thúc, không còn dữ liệu.
Đ i với Java, System.in là một InputStream n i kết với bàn phím đ ợc tạo sẵn b i
hệ th ng. Ch ng trình có thể dùng InputStream này để nhận các ký tự nhập từ bàn
phím.
Ví dụ: Hãy l u ch
ng trình sau vào tập tin InStream1.java
import java.io.*;
public class InStream1 {
public static void main(String args[]) {
InputStream is = System.in; // KeyBoard = System.in
while (true) {
try {
int ch = is.read();
if (ch ==-1 || ch =='q') break;
System.out.print((char)ch);
} catch (IOException ie) {
System.out.print("Error: "+ie);
}
}
}
}
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
37
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Biên dịch và thực thi ta đ ợc kết quả sau:
Ví dụ trên chờ nhận các ký tự đ ợc nhập từ bàn phím.
int read(byte b[]) throws IOException:
Đọc tất cả các byte hiện có trong Stream vào mảng b.
•
•
Return 0-255: S l ợng byte đọc đ ợc.
-1 : Stream đã kết thúc, không còn dữ liệu.
int read(byte b[], int offset, int len)
Đọc len byte từ Stream hiện tại, l u vào trong mảng b bắt đầu từ vị trí offset
•
•
Return: s l ợng byte đọc đ ợc.
-1 : Stream đã kết thúc.
Các ph ng th c trên khi thực thi sẽ bị nghẽn (block) cho đến khi có dữ liệu hoặc
kết trúc Stream hay một ngoại lệ xuất hiện.
int available()
Trả về s l ợng byte hiện có trong Stream mà không làm nghẽn ch
ng trình.
Ví dụ:
L u ch
ng trình sau vào tập tin có tên InStream2.java
import java.io.*;
public class InStream2 {
public static void main(String args[]) {
InputStream is = System.in; // KeyBoard = System.in
while (true) {
try {
int num = is.available();
if (num > 0){
byte[] b = new byte[num];
int result = is.read(b);
if (result == -1) break;
String s = new String(b);
System.out.print(s);
} else {
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
38
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
System.out.print('.');
}
} catch (IOException ie) {
System.out.print("Error: "+ie);
}
}
}
}
Biên dịch và thực thi ta đ ợc kết quả sau:
Điểm khác biệt trong ví dụ này là các ký tự ta nhập từ bàn phím sẽ không hiển thị
t c thì trên màn hình. Chúng chỉ hiển thị sau khi chúng ta nhấn phím Enter.
1.6.2. Lớp java.io.OutputStream
Là loại stream cho phép ch
c bản sau:
ng trình xuất dữ liệu ra ngoại vi. Có các ph
ng th c
void write(int b) throws IOException
•
•
Viết byte b vào Stream hiện tại,
Return : void
void write (byte[] b) throws IOException
•
•
Viết tất cả các phần tử c a mảng b vào Stream hiện tại
Return : void
void write (byte[] b, int offset, int len) throws IOException:
•
•
Viết len phần tử trong mảng b vào Stream hiện tại, bắt đầu từ phần tử có chỉ
s là offset c a mảng.
Return : void
Đ i với Java, System.out là một OutputStream n i kết với màn hình đ ợc tạo sẵn
b i hệ th ng. Ch ng trình có thể dùng OutputStream này để g i các ký tự ra màn hình.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
39
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Ví dụ:
Hãy l u ch
ng trình sau vào tập tin OutStream1.java
import java.io.*;
public class OutStream1 {
public static void main(String args[]) {
OutputStream os = System.out; // Monitor = System.out
try {
String str = "The example of OutputStream";
byte b[] = str.getBytes(); // Đổi chuỗi thành mảng các bytes
os.write(b);
} catch (IOException ie) {
System.out.print("Error: "+ie);
}
}
}
Biên dịch và thực thi ch
ng trình ta đ ợc kết quả sau:
1.6.3. Nhập chuỗi từ một InputStream
InputStream là Stream nhập gồm chuỗi các bytes. Nó chỉ cung cấp các ph ng th c
cho việc đọc byte và mảng các bytes. Để có thể đọc đ ợc chuỗi từ một InputStream ta phải
sử dụng thêm các lớp sau:
•
•
Lớp java.io.InputStreamReader: Là cầu n i để chuyển InputStream dạng
byte sang InputStream dạng các ký tự (Character).
Lớp java.io.BufferedReader: Hỗ trợ việc đọc văn bản từ một InputStream
dạng ký tự.
Ph ng th c String readLine() throws IOException c a BufferedReader cho
phép đọc dòng văn bản kế tiếp trong InputStream. Một dòng kết thúc b i cặp ký tự ‘\r’’\n’
hoặc kết thúc Stream.
Return: Một chuỗi ký tự hoặc null.
Giả sử is là một đ i t ợng thuộc lớp InputStream. Để đọc chuỗi từ is ta thực hiện
các thao tác sau:
1. InputStreamReader isr = new InputStreamReader(is);
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
40
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
2. BufferedReader br = new BufferedReader (isr);
3. String str = br.readLine();
Ví dụ: Đọc chuỗi từ bàn phím
L u ch
ng trình sau vào tập tin ReadLine.java
import java.io.*;
public class ReadLine{
public static void main(String args[]) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
while (true) {
try {
String line = br.readLine();
if (line == null ) break;
System.out.print(line);
} catch (IOException ie) {
System.out.print("Error: "+ie);
}
}
}
}
Biên dịch và thực thi ta có kết quả sau:
1.6.4. Xuất chuỗi ra một OutputStream
OutputStream là Stream xuất gồm chuỗi các bytes. Nó chỉ cung cấp các ph ng
th c cho việc viết byte và mảng các bytes. Để có thể g i đ ợc chuỗi ra một OutputStream
ta phải sử dụng lớp java.io.PrintWriter.
Giả sử: os là một OutputStream, str là chuỗi cần viết vào os.
Ta thực hiện các thao tác sau:
1.
2.
3.
4.
PrintWriter pw = new PrintWriter(os);
pw.wirte(str);
hoặc pw.println(str); // Nếu mu n có ký tự xu ng dòng
flush()
// Đẩy dữ liệu từ buffer ra ngoại vi
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
41
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Ví dụ: Viết chuỗi ra màn hình
L u ch
ng trình sau vào tập tin PrintString.java
import java.io.*;
public class PrintString {
public static void main(String args[]) {
OutputStream os = System.out;
PrintWriter pw = new PrintWriter(os);
pw.write("This is a string \r\n");
pw.println("This is a line");
pw.write("Bye! Bye!");
pw.flush();
}
}
Biên dịch và thực thi ta đ ợc:
1.7. Luồng (Thread)
Luồng là một cách thông dụng để nâng cao năng lực xử lý c a các ng dụng nh
vào c chế song song. Trong một hệ điều hành cổ điển, đ n vị c bản sử dụng CPU là một
quá trình. Mỗi quá trình có một Thanh ghi bộ đếm ch ng trình (PC-Program Counter),
Thanh ghi trạng thái (Status Register), ngăn xếp (Stack) và không gian địa chỉ riêng
(Address Space).
Ng ợc lại, trong một hệ điều hành có hỗ trợ tiện ích luồng, đ n vị c bản sử dụng
CPU là một luồng. Trong những hệ điều hành này, một quá trình bao gồm một không gian
địa chỉ và nhiều luồng điều khiển. Mỗi luồng có bộ đếm ch ng trình, trạng thái thanh ghi
và ngăn xếp riêng. Nh ng tất cả các luồng c a một quá trình cùng chia sẻ nhau một không
gian địa chỉ. Nh đó các luồng có thể sử dụng các biến toàn cục, chia sẻ các tài nguyên
nh tập tin, hiệu báo một cách dễ dàng...
Cách th c các luồng chia sẻ CPU cũng gi ng nh cách th c c a các quá trình. Một
luồng cũng có những trạng thái: đang chạy (running), sẵn sàng (ready), nghẽn (blocked) và
kết thúc (Dead). Một luồng thì đ ợc xem nh là một quá trình nhẹ.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
42
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Hình 2.1 Các trạng thái c a Luồng
Nh vào luồng, ng
đồng th i.
i ta thiết kế các server có thể đáp ng nhiều yêu cầu một cách
Hình 2.2 - Sử dụng luồng cho các server
Trong mô hình này, Server có một Luồng phân phát (Dispatcher thread) và nhiều
Luồng thực hiện (Worker thread). Luồng phân phát tiếp nhận các yêu cầu n i kết từ các
Client, rồi chuyển chúng đến các luồng thực hiện còn rảnh để xử lý. Những luồng thực
hiện hoạt động song song nhau và song song với cả luồng phân phát, nh đó, Server có
thể phục vụ nhiều Client một cách đồng th i.
1.7.1. Các m c cài đặt luồng
Nhìn từ góc độ hệ điều hành , Luồng có thể đ ợc cài đặt
•
•
một trong hai m c:
Trong không gian ng i dùng (user space)
Trong không gian nhân (kernel mode):
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
43
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.7.1.1. Tiếp cận luồng ở m c ng ời dùng:
Hình 2.3 - Kiến trúc luồng cài đặt
m c ng
i dùng
Không gian ng i dùng bao gồm một hệ th ng runtime mà nó tập hợp những th
tục quản lý luồng. Các luồng chạy trong không gian nằm bên trên hệ th ng runtime thì
đ ợc quản lý b i hệ th ng này. Hệ th ng runtime cũng l u giữ một bảng tin trạng thái để
theo dõi trạng thái hiện hành c a mỗi luồng. T ng ng với mỗi luồng sẽ có một mục từ
trong bảng, bao gồm các thông tin về trạng thái, giá trị thanh ghi, độ u tiên và các thông
tin khác về luồng
Tiếp cận này có hai m c định th i biểu (Scheduling): bộ định th i biểu cho các quá
trình nặng và bộ định th i biểu trong hệ th ng runtime. Bộ lập biểu c a hệ th ng runtime
chia th i gian sử dụng CPU đ ợc cấp cho một quá trình thành những khoảng nh h n để
cấp cho các luồng trong quá trình đó. Nh vậy việc kết thúc một luồng thì v ợt ra ngoài
tầm kiểm soát c a kernel hệ th ng.
1.7.1.2. Tiếp cận luồng ở m c hạt nhân hệ điều hành
Hình 2.4 - Kiến trúc luồng cài đặt
m c hệ th ng
Trong tiếp cận này không có hệ th ng runtime và các luồng thì đ ợc quản lý b i
kernel c a hệ điều hành. Vì vậy, bảng thông tin trạng thái c a tất cả các luồng thì đ ợc l u
trữ b i kernel. Tất cả những l i gọi mà nó làm nghẽn luồng sẽ đ ợc bẫy (TRAP) đến
kernel. Khi một luồng bị nghẽn, kernel chọn luồng khác cho thực thi. Luồng đ ợc chọn có
thể cùng một quá trình với luồng bị nghẽn hoặc thuộc một quá trình khác. Vì vậy sự tồn tại
c a một luồng thì đ ợc biết b i kernel và chỉ có một m c lập biểu trong hệ th ng.
1.7.2. Luồng trong java
Trong Java, luồng là 1 đ i t ợng thuộc lớp java.lang.Thread. Một ch ng trình
trong java có thể cài đặt luồng bằng cách tạo ra một lớp con c a lớp java.lang.Thread.
Lớp này có 3 ph
•
•
•
ng th c c bản để điều khiển luồng là:
public native synchronized void start()
public void run()
public final void stop()
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
44
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
Ph
- Giáo Trình Lập Trình Truyền Thông
ng th c start()
Chuẩn bị mọi th để thực hiện luồng.
Ph
ph
ng th c run()
Thực hiện công việc thực sự c a luồng, () sẽ đ ợc kích hoạt một cách tự động b i
ng th c start().
Ph
ng th c stop()
Kết thúc luồng.
Luồng sẽ "chết" khi tất cả các công việc trong ph
hoặc khi ph ng th c stop() đ ợc kích hoạt.
ng th c run() đ ợc thực hiện
Ví dụ
Ví dụ sau định nghĩa lớp MyThread là một Thread có:
•
•
Các thuộc tính
o name: tên c a thread
o n: s lần thread xuất hiện ra màn hình
Các ph ng th c:
o MyThread(String name, int n):
Là ph ng th c kh i tạo, có nhiệm vụ gán giá trị cho 2 thuộc tính và gọi
ph ng th c start() để cho thread hoạt động (start() tự động gọi run())
o
run()
In n lần dòng thông báo ra màn hình rồi kết thúc thread.
o
main()
Tạo ra 4 thread thuộc lớp MyThread lần l ợt có tên là Thread0, Thread1,
Thread2, Thread3. Mỗi thread có 1000 lần xuất hiện ra màn hình.
L u ch
ng trình sau vào tập tin MyThread.java
public class MyThread extends Thread{
String name;
int n;
MyThread(String name, int n){
this.name = name;
this.n = n;
System.out.println("Thread "+name+" has been created ....!");
start();
}
public void run(){
for(int i=0; i< n; i++) {
System.out.println("Hello, I'm "+ name);
System.out.println(" I go to bed now, bye bye ... wow ... ");
}
}
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
45
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
public static void main(String args[]){
int n = 1000;
int nt = 4 ;
for (int i=0; i< nt; i++){
MyThread t = new MyThread("Thread"+i,n);
}
}
}
Biên dịch và thực thi ta có kết quả sau:
Các Thread in ra màn hình theo th tự ta không thể xác định tr ớc đ ợc vì chúng
đ ợc thực thi song song nhau.
Để dừng tạm th i màn hình kết quả khi ch ng trình đang thực thi, ta nhấp chuột
vào cửa s DOS mà ch ng trình đang chạy. Sau đó ta nhấn phín Enter để ch ng trình
tiếp tục.
Ngoài ra, lớp Thread còn có 1 s các ph
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
ng th c khác :
46
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
•
•
•
- Giáo Trình Lập Trình Truyền Thông
public static void sleep(long milliseconds) throws InterruptedException: làm
cho Thread bị nghẽn (Blocked) một khoảng th i gian mili giây xác định.
public final void suspend(): Chuyển Thread từ trạng thái sẳn sàng sang trạng
thái nghẽn.
public final void resume(): Chuyển Thread từ trạng thái nghẽn sang trạng thái
sẵn sàng.
public final void yield() : Chuyển Thread từ trạng thái đang chạy sang trạng
thái sẵn sàng.
1.7.2.1 Độ u tiên c a luồng
Độ u tiên c a các luồng xác định m c độ u tiên trong việc phân ph i CPU giữa
các luồng với nhau. Khi có nhiều luồng đang trạng thái "Ready", luồng có độ u tiên cao
nhất sẽ đ ợc thực thi (chuyển đến trạng thái "running" ).
Độ u tiên trong Java đ ợc định nghĩa bằng các hằng s nguyên theo th tự giảm
dần nh sau:
•
•
•
Thread.MAX_PRIORITY
Thread.NORM_PRIORITY
Thread.MIN_PRIORITY
Hai ph
•
•
ng th c liên quan đến độ u tiên c a luồng là:
setPriority( int x): Đặt độ u tiên c a luồng là x
int getPriority( ): Trả về giá trị u tiên c a luồng
Ví dụ:
Trong ví dụ này chúng ta tạo ra 12 Thread thuộc lớp MyThread. Một mảng 3 phần
tử tên prio ch a 3 độ u tiên từ cao nhất đến thấp nhất. Thread th i sẽ có độ u tiên vị
trí i%3 trong mảng prio. Nh vậy các thread 0,3,6,9 có độ u tiên cao nhất, sau đó đến
Thread 1,4,7,10 và cu i cùng là các thread 2,5,8,11.
L u ch
ng trình sau vào tập tin PriorityThread.java
public class PriorityThread{
public static void main(String args[]){
int n = 1000;
int nt = 12;
int prio[]= { Thread.MAX_PRIORITY,
Thread.NORM_PRIORITY,
Thread.MIN_PRIORITY};
for (int i=0; i< nt; i++){
MyThread t = new MyThread("Thread"+i,n);
t.setPriority(prio[i%3]);
}
}
}
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
47
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Biên dịch và thực thi ta đ ợc kết quả nh sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
48
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Các Thread 0,3,9 có độ u tiên cao h n các Thread khác cho nên chúng đ ợc thực
thi th ng xuyên h n.
Các Thread 2,5,8,11 có độ u tiên thấp nhất nên chúng kết thúc sau cùng.
1.7.3. Đồng bộ hóa giữa các luồng
Tất cả các luồng c a một quá trình thì đ ợc thực thi song song và độc lập nhau
nh ng lại cùng chia sẻ nhau một không gian địa chỉ c a quá trình. Chính vì vậy có thể dẫn
đến khả năng đụng độ trong việc cập nhật các dữ liệu dùng chung c a ch ng trình (biến,
các tập tin đ ợc m ) khi một luồng ghi lên một dữ liệu trong khi một luồng khác đang đọc
dữ liệu này.
Trong tr ng hợp đó, cần phải sử dụng c chế đồng bộ hóa c a Java. Có nhiều m c
đồng bộ hóa nh : trên một biến, trên một câu lệnh, trên một kh i lệnh hay trên một
ph ng th c.
1.8. Bài tập áp dụng
Ch đề 1: C bản về Java
•
•
Mục đích:
o Sinh viên làm quen với ngôn ngữ Java, viết 1 s ch
bằng Java.
o Thực tập cách nhập / xuất thông tin qua Java.
o Thiết kế lớp đ n giản qua Java.
Yêu cầu
ng trình đ n giản
Sinh viên thực hiện các bài tập sau
o
o
o
o
o
o
o
Bài 1 : Khảo sát cây th mục JDK trên hệ th ng máy tính đang thực
tập. Đặt các biến môi tr ng PATH và CLASSPATH đến các vị trí
thích hợp.
Bài 2 : Viết ch ng trình thể hiện ra màn hình câu : " Hello Java"
Bài 3 : Viết ch ng trình nhập vào 1 chuỗi ký tự. Đổi thành chữ Hoa
và in ra màn hình.
Bài 4 : Viết ch ng trình nhập vào 1 s nguyên. Kiểm tra xem s đó
có phải là s nguyên t hay không và thông báo ra màn hình.
Bài 5 : Viết ch ng trình giải ph ng trình bậc 2.
Bài 6 : Viết ch ng trình tính tổng c a dãy s từ 1 đến n (Với n đ ợc
nhập từ bàn phím).
Bài 7 : Nhập vào 1 dãy s thực, tính tổng c a các s d ng trong dãy
đó.
Ch đề 2: Thiết kế lớp trong Java
•
•
Mục đích:
o Thiết kế lớp d ới Java.
Yêu cầu
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
49
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Sinh viên thực hiện các bài tập sau
o
o
Bài 1 : Thiết kế lớp Diem (Điểm trong không gian 2 chiều) gồm :
Thành phần dữ liệu : x,y kiểu int.
Các hàm thành viên gồm : các ph ng th c kh i tạo, ph ng
th c gán tọa độ cho 1 điểm, ph ng th c nhập tọa độ cho 1
điểm, ph ng th c in ra màn hình tọa độ điểm theo dạng (x,y),
ph ng th c tính khoảng cách từ điểm đó đến g c tọa độ.
Viết hàm main() khai thác lớp vừa định nghĩa.
Bài 2 : Thiết kế lớp PhanSo ( Phân s ) có:
2 thuộc tính tử s và mẫu s thuộc kiểu s nguyên
Các ph ng th c: Ph ng th c kh i tạo, ph ng th c in phân
s , ph ng th c nghịch đảo phân s , ph ng th c trả về giá trị
thực c a phân s , hàm cộng, trừ, nhân, chia 2 phân s .
Ph ng th c main() sử dụng lớp PhanSo.
Ch đề 3: Thread
•
•
Mục đích:
o Tìm hiểu về luồng (Thread), cách lập trình luồng, lập trình song song.
Yêu cầu: Sinh viên thực bài tập sau:
o Bài 1 : Viết ch ng trình mô ph ng bài toán "Ng i sản xuất - Ng i
tiêu dùng", trong đó Ng i sản xuất sẽ sản xuất ra một s l ợng ngẫu
nhiên n sản phẩm nào đó rồi yêu cầu nhập kho. Ng i tiêu dùng sẽ yêu
cầu xuất kho một s l ợng ngẫu nhiên m sản phẩm nào đó từ kho. Yêu
cầu nhập kho chỉ đ ợc chấp nhận nếu s l ợng hàng hóa đ a vào
không v ợt quá s c ch a c a kho, nếu không, phải ch cho đến khi có
đ chổ tr ng trong kho. Yêu cầu xuất kho chỉ đ ợc chấp nhận khi còn
đ hàng trong kho nếu không cũng phải ch .
Gợi ý : Thiết kế các lớp sau:
Lớp Kho: Có thuộc tính là s c ch a, ph ng th c kh i tạo gán
giá trị cho s c ch a, các ph ng th c xem s l ợng hàng tồn,
ph ng th c nhập kho, ph ng th c xuất kho. In thông báo mỗi
khi nhập kho hay xuất kho thành công
Lớp Ng i Sản Xuất là một Thread: Có thuộc tính là kho để
nhập hàng. Ph ng th c kh i tạo gán giá trị cho kho nhập hàng.
Ph ng th c sản xuất lặp lại công việc là tạo ra n sản phẩm
ngẫu nhiên và ch để nhập vào kho.
Lớp Ng i Tiêu Dùng là một Thread: Có thuộc tính là kho để
xuất hàng. Ph ng th c kh i tạo gán giá trị cho kho để xuất
hàng. Ph ng th c tiêu dùng lặp lại công việc là ch để yêu cầu
xuất m sản phẩm từ kho.
Lớp Demo tạo ra một kho và 2 ng i sản xuất, 2 ng i tiêu
dùng thực hiện việc nhập xuất trên cùng một kho.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
50
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
CH
NG 3
ng dẫn (Pipe)
Mục đích
Ch ng này nhằm giới thiệu c chế giao tiếp liên quá trình đầu tiên là Pipe và cách
sử dụng nó trong Java để làm ph ng tiện giao tiếp giữa các Thread trong một ch ng
trình.
Yêu cầu
Sau khi hoàn tất ch
•
•
•
•
ng này, bạn có thể:
Trình bày đ ợc các đặc điểm c a Pipe.
Biết cách tạo Pipe và xuất/ nhập dữ liệu trên Pipe trong Java.
Giải thích đ ợc ch c năng c a dịch vụ phản hồi thông tin (Echo Service).
Xây dựng, biên dịch và thực thi thành công ch ng trình PipedEcho.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
51
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.1. Giới thiệu về ng dẫn
Ông dẫn là một tiện ích đ ợc hỗ trợ trong hầu hết các ngôn ngữ lập trình vận hành
trên các hệ th ng đa nhiệm. ng dẫn cho phép hai quá trình nằm trên cùng một máy có thể
trao đổi dữ liệu với nhau.
Dữ liệu đi trên ng dẫn theo một chiều nhất định. Khi sử dụng ng dẫn, ng
dùng một đầu cho việc viết dữ liệu vào và một đầu còn lại cho việc đọc dữ liệu ra.
i ta
Hình 3.1 Mô hình ng dẫn
ng dẫn thích hợp cho tr
vào cho quá trình kia.
ng hợp dữ liệu tạo ra c a quá trình này sẽ là dữ liệu đầu
Tuy nhiên ta cũng có thể sử dụng ng dẫn để xây dựng các ng dụng theo kiến trúc
Client- Server bằng cách sử dụng hai ng dẫn: một ng dẫn để truyền các yêu cầu
(request), một ng dẫn để truyền các trả l i (reply).
Hình 3.2 – Dùng ng dẫn trong ch
ng trình Client -Server
Có hai loại ng dẫn:
•
•
1.2.
ng dẫn bình th ng ( Normal Pipe): Giới hạn trong phạm vi không gian địa
chỉ c a một quá trình mà thôi. Nó chỉ cho phép giao tiếp giữa quá trình cha
với các quá trình con hay giữa các quá trình con c a một quá trình với nhau.
Java hỗ trợ ng dẫn loại này. Trong đó các quá trình con đ ợc thay thế b i
các luồng.
ng dẫn có tên (Named Pipe): Loại này có thể cho phép hai quá trình có
không gian địa chỉ khác nhau (trên cùng một máy) giao tiếp với nhau. Thực
chất nó gi ng nh một tập tin với qui định rằng dữ liệu sẽ đ ợc lấy ra đầu
tập tin và đ ợc thêm vào cu i tập tin.
ng dẫn trong Java
1.2.1. Giới thiệu
Java hỗ trợ tiên ích ng dẫn thông qua hai lớp java.io.PipedInputStream và
java.io.PipedOutputStream. Chúng là hai đầu c a một ng dẫn. Trong đó
PipedInputStream là đầu đọc dữ liệu và PipedOutputStream là đầu ghi dữ liệu c a ng
dẫn.
PipedInputStream là lớp con c a InputStream nên nó có tất cả các thuộc tính c a
InputStream.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
52
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
PipedOutputStream là lớp con c a OutputStream nên nó có tất cả các thuộc tính c a
OutputStream
1.2.2. Các cách tạo ng dẫn
Để tạo một ng dẫn ta chỉ cần tạo ra hai đ i t ợng thuộc lớp PipedInputStream và
PipedOutputStream và n i chúng lại với nhau. Khi đó dữ liệu đ ợc ghi vào
PipedOutputStream sẽ đ ợc đọc ra đầu PipedInputStream:
Hình 3.4 - Tạo ng dẫn trong Java
Cách 1
1. Tạo đầu đọc:
o PipedInputStream readId = new PipedInputStream();
2. Tạo đầu ghi:
o PipedOutputStream writeId = new PipedOutputStream();
3. N i đầu đọc với đầu ghi hay ng ợc lại
o readId.connect(writeId);
o // hoặc writeId.connect(readId);
Cách 2
1. Tạo đầu đọc:
o PipedInputStream readId = new PipedInputStream();
2. Tạo đầu ghi và n i vào đầu đọc đã có:
o PipedOutputStream writeId = new PipedOutputStream(readId);
Hoặc: Ta có thể tạo đầu ghi tr ớc rồi tạo đầu đọc sau.
L u ý: Các ph ng th c kh i tạo c a PipedInputStream và PipedOutputStream sử
dụng trên đòi h i phải "bắt" (catch) IOException do chúng có thể “quẳng” ra (throws)..
1.3. Dịch vụ phản hồi thông tin (Echo Service)
Dịch vụ phản hồi thông tin là một dịch vụ tồn tại trên hệ th ng mạng UNIX. Dịch
vụ này đ ợc xây dựng theo mô hình Client - Server, c chế hoạt động nh sau:
•
•
Phần Server: Ch nhận các byte g i đến từ Client. Với mỗi byte nhận đ ợc,
Server sẽ g i về đúng byte đã nhận tr về Client.
Phần Client: G i các byte sang Server, ch nhận các byte g i về từ Server.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
53
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.4. Giả lập dịch vụ phản hồi thông tin bằng Pipe
Phần kế tiếp ta xây dựng một ng dụng có tên là PipeEcho mô ph ng dịch vụ phản
hồi thông tin để minh họa cách sử dụng Pipe làm ph ng tiện giao tiếp giữa các Thread
trong một ng dụng.
Hình 3.5 – Mô hình ng dụng PipeEcho
Trong ng dụng này Client và Server là hai Thread thuộc lớp PipedEchoClient và
PipedEchoServer. Việc trao đổi thông tin giữa client và server đ ợc thực hiện thông qua 2
Pipe (cwPipe-srPipe) và (swPipe-crPipe).
PipedEchoClient nhận các ký tự từ bàn phím, g i chúng sang PipedEchoServer và
ch nhận các ký tự g i về từ PipedEchoServer để in ra màn hình. PipedEchoServer ch
nhận từng ký tự từ PipedEchoClient, đổi ký tự nhận đ ợc thành ký tự hoa và g i ng ợc về
PipedEchoClient.
1.4.1. Lớp PipedEchoServer
Hãy l u ch
ng trình sau vào tập tin PipedEchoServer.java
import java.io.*;
public class PipedEchoServer extends Thread {
PipedInputStream readPipe;
PipedOutputStream writePipe;
PipedEchoServer(PipedInputStream readPipe, PipedOutputStream writePipe){
this.readPipe = readPipe;
this.writePipe = writePipe;
System.out.println("Server is starting . . .");
start();
}
public void run(){
while(true) {
try{
int ch = readPipe.read();
ch = Character.toUpperCase((char)ch);
writePipe.write(ch);
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
54
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
}
catch (IOException ie) { System.out.println("Echo Server Error: "+ie ); }
}
}
}
1.4.2. Lớp PipedEchoClient
Hãy l u ch
ng trình sau vào tập tin PipedEchoClient.java
import java.io.*;
public class PipedEchoClient extends Thread {
PipedInputStream readPipe;
PipedOutputStream writePipe;
PipedEchoClient(PipedInputStream readPipe, PipedOutputStream writePipe){
this.readPipe = readPipe;
this.writePipe = writePipe;
System.out.println("Client creation");
start();
}
public void run(){
while(true) {
try {
int ch=System.in.read();
writePipe.write(ch);
ch = readPipe.read();
System.out.print((char)ch);
}
catch(IOException ie){
System.out.println("Echo Client Error: "+ie );
}
}
}
}
1.4.3. Lớp PipedEcho
Hãy l u ch
ng trình sau vào tập tin PipedEcho.java
import java.io.*;
public class PipedEcho {
public static void main(String argv[]){
try{
PipedOutputStream cwPipe = new PipedOutputStream();
PipedInputStream crPipe = new PipedInputStream();
PipedOutputStream swPipe = new PipedOutputStream(crPipe);
PipedInputStream srPipe = new PipedInputStream(cwPipe);
PipedEchoServer server = new PipedEchoServer(srPipe,swPipe);
PipedEchoClient client = new PipedEchoClient(crPipe,cwPipe);
} catch(IOException ie) {
System.out.println("Pipe Echo Error:"+ie);
}
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
55
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
}
}
1.4.5. Biên dịch và thực thi ch
Biên dịch và thực thi ch
ng trình
ng trình theo cách sau:
Nhập vào bàn phím chuỗi ký tự mà bạn mu n rồi nhấp phím Enter. Bạn sẽ thấy
chuỗi ký tự in hoa c a chuỗi vừa nhập xuất hiện trên màn hình.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
56
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
CH
NG 4
Socket
Mục đích
Ch ng này nhằm giới thiệu về cách th c xây dựng ng dụng Client-Server trên
mạng TCP/IP theo cả hai chế độ Có n i kết (TCP) và Không n i kết (UDP).
Yêu cầu
Sau khi hoàn tất ch
•
•
•
•
•
•
•
•
ng này, bạn có thể:
Giải thích đ ợc Socket là gì, vai trò c a s hiệu cổng (Port) và địa chỉ IP
trong c chế Socket.
Phân biệt đ ợc sự khác biệt c a hai loại Protocol TCP và UDP.
Trình bày đ ợc các b ớc xây dựng một ch ng trình Client-Server sử dụng
Socket làm ph ng tiện giao tiếp trong cả hai chế độ: Có n i kết và không n i
kết.
Liệt kê các lớp hỗ trợ lập trình Socket c a Java.
Xây dựng đ ợc các ch ng trình Client sử dụng Sokcet chế độ có n i kết
bằng ngôn ngữ Java.
Xây dựng đ ợc các ch ng trình Server sử dụng Sokcet chế độ có n i kết
phục vụ tuần tự và phục vụ song song bằng ngôn ngữ Java.
Xây dựng đ ợc các ch ng trình Client-Server sử dụng Sokcet chế độ
không n i kết bằng ngôn ngữ Java.
Tự xây dựng đ ợc các Protocol mới cho ng dụng c a mình.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
57
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.1. Giới thiệu về socket
1.1.1. Giới thiệu
Socket là một giao diện lập trình ng dụng (API-Application Programming
Interface). Nó đ ợc giới thiệu lần đầu tiên trong ấn bản UNIX - BSD 4.2. d ới dạng các
hàm hệ th ng theo cú pháp ngôn ngữ C (socket(), bind(), connect(), send(), receive(),
read(), write(), close() ,..). Ngày nay, Socket đ ợc hỗ trợ trong hầu hết các hệ điều hành
nh MS Windows, Linux và đ ợc sử dụng trong nhiều ngôn ngữ lập trình khác nhau: nh
C, C++, Java, Visual Basic, Visual C++, . . .
Socket cho phép thiết lập các kênh giao tiếp mà hai đầu kênh đ ợc đánh dấu b i hai
cổng (port). Thông qua các cổng này một quá trình có thể nhận và g i dữ liệu với các quá
trình khác.
Hình 4.1 – Mô hình Socket
Có hai kiểu socket:
1. Socket kiểu AF_UNIX chỉ cho phép giao tiếp giữa các quá trình trong cùng
một máy tính
2. Socket kiểu AF_INET cho phép giao tiếp giữa các quá trình trên những máy
tính khác nhau trên mạng.
1.1.2. S hiệu cổng (Port Number) c a socket
Để có thể thực hiện các cuộc giao tiếp, một trong hai quá trình phải công b s hiệu
cổng c a socket mà mình sử dụng. Mỗi cổng giao tiếp thể hiện một địa chỉ xác định trong
hệ th ng. Khi quá trình đ ợc gán một s hiệu cổng, nó có thể nhận dữ liệu g i đến cổng
này từ các quá trình khác. Quá trình còn lại cũng đ ợc yêu cầu tạo ra một socket.
Ngoài s hiệu cổng, hai bên giao tiếp còn phải biết địa chỉ IP c a nhau. Địa chỉ IP
giúp phân biệt máy tính này với máy tính kia trên mạng TCP/IP. Trong khi s hiệu cổng
dùng để phân biệt các quá trình khác nhau trên cùng một máy tính.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
58
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Hình 4.2 – Cổng trong Socket
Trong hình trên, địa chỉ c a quá trình B1 đ ợc xác định bằng 2 thông tin: (Host B,
Port B1):
Địa chỉ máy tính có thể là địa chỉ IP dạng 203.162.36.149 hay là địa chỉ theo dạng
tên miền nh www.cit.ctu.edu.vn
S hiệu cổng gán cho Socket phải duy nhất trên phạm vi máy tính đó, có giá trị
trong khoảng từ 0 đến 65535 (16 bits). Trong đó, các cổng từ 1 đến 1023 đ ợc gọi là cổng
hệ th ng đ ợc dành riêng cho các quá trình c a hệ th ng.
Các cổng mặc định c a 1 s dịch vụ mạng thông dụng:
S hiệu cổng
Quá trình hệ th ng
7
Dịch vụ Echo
21
Dịch vụ FTP
23
Dịch vụ Telnet
25
Dịch vụ E-mail (SMTP)
80
Dịch vụ Web (HTTP)
110
Dịch vụ E-mail (POP)
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
59
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.1.3. Các chế độ giao tiếp
Xét kiến trúc c a hệ th ng mạng TCP/IP
Hình 4.3 – Bộ giao th c TCP/IP
Tầng vận chuyển giúp chuyển tiếp các thông điệp giữa các ch
với nhau. Nó có thể hoạt động theo hai chế độ:
•
•
ng trình ng dụng
Giao tiếp có n i kết, nếu sử dụng giao th c TCP
Hoặc giao tiếp không n i kết, nếu sử dụng giao th c UDP
Socket là giao diện giữa ch ng trình ng dụng với tầng vận chuyển. Nó cho phép
ta chọn giao th c sử dụng tầng vận chuyển là TCP hay UDP cho ch ng trình ng dụng
c a mình.
Bảng sau so sánh sự khác biệt giữa hai chế độ giao tiếp có n i kết và không n i kết:
Chế độ có n i kết (TCP)
•
•
•
Tồn tại kênh giao tiếp ảo giữa
hai bên giao tiếp
Dữ liệu đ ợc g i đi theo chế độ
bảo đảm: có kiểm tra lỗi. truyền
lại gói tin lỗi hay mất, bảo đảm
th tự đến c a các gói tin . . .
Dữ liệu chính xác, T c độ truyền
chậm.
Chế độ không n i kết (UDP)
•
•
•
•
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
Không tồn tại kênh giao tiếp ảo
giữa hai bên giao tiếp
Dữ liệu đ ợc g i đi theo chế độ
không bảo đảm: Không kiểm tra
lỗi, không phát hiện không
truyền lại gói tin bị lỗi hay mất,
không bảo đảm th tự đến c a
các gói tin . . .
Dữ liệu không chính xác, t c độ
truyền nhanh.
Thích hợp cho các ng dụng cần
t c độ, không cần chính xác cao:
truyền âm thanh, hình ảnh . . .
60
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.2. Xây dựng ng dụng Client-Server với Socket
Socket là ph ng tiện hiệu quả để xây dựng các ng dụng theo kiến trúc ClientServer. Các ng dụng trên mạng Internet nh Web, Email, FTP là các ví dụ điển hình.
Phần này trình bày các b ớc c bản trong việc xây dựng các ng dụng ClientServer sử dụng Socket làm ph ng tiện giao tiếp theo cả hai chế độ: Có n i kết và không
n i kết.
1.2.1. Mô hình Client-Server sử dụng Socket ở chế độ có n i kết (TCP)
Giai đoạn 1: Server tạo Socket, gán s hiệu cổng và lắng nghe yêu cầu n i kết.
•
•
•
socket(): Server yêu cầu tạo một socket để có thể sử dụng các dịch vụ c a
tầng vận chuyển.
bind(): Server yêu cầu gán s hiệu cổng (port) cho socket.
listen(): Server lắng nghe các yêu cầu n i kết từ các client trên cổng đã đ ợc
gán.
Server sẵn sàng phục vụ Client.
Giai đoạn 2: Client tạo Socket, yêu cầu thiết lập một n i kết với Server.
•
•
socket(): Client yêu cầu tạo một socket để có thể sử dụng các dịch vụ c a tầng
vận chuyển, thông th ng hệ th ng tự động gán một s hiệu cổng còn rảnh
cho socket c a Client.
connect(): Client g i yêu cầu n i kết đến server có địa chỉ IP và Port xác định.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
61
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
- Giáo Trình Lập Trình Truyền Thông
accept(): Server chấp nhận n i kết c a client, khi đó một kênh giao tiếp ảo
đ ợc hình thành, Client và server có thể trao đổi thông tin với nhau thông qua
kênh ảo này.
Giai đoạn 3: Trao đổi thông tin giữa Client và Server.
•
•
•
Sau khi chấp nhận yêu cầu n i kết, thông th ng server thực hiện lệnh read()
và nghẽn cho đến khi có thông điệp yêu cầu (Request Message) từ client g i
đến.
Server phân tích và thực thi yêu cầu. Kết quả sẽ đ ợc g i về client bằng lệnh
write().
Sau khi g i yêu cầu bằng lệnh write(), client ch nhận thông điệp kết quả
(ReplyMessage) từ server bằng lệnh read().
Trong giai đoạn này, việc trao đổi thông tin giữa Client và Server phải tuân th giao
th c c a ng dụng (Dạng th c và ý nghĩa c a các thông điệp, qui tắc bắt tay, đồng bộ
hóa,... ). Thông th ng Client sẽ là ng i g i yêu cầu đến Server tr ớc.
Nếu chúng ta phát triển ng dụng theo các Protocol đã định nghĩa sẵn, chúng ta
phải tham khảo và tuân th đúng những qui định c a giao th c. Bạn có thể tìm đọc mô tả
chi tiết c a các Protocol đã đ ợc chuẩn hóa trong các tài liệu RFC (Request For
Comments). Ng ợc lại, nếu chúng ta phát triển một ng dụng Client-Server riêng c a
mình, thì công việc đầu tiên chúng ta phải thực hiện là đi xây dựng Protocol cho ng dụng.
Giai đoạn 4: Kết thúc phiên làm việc.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
62
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
- Giáo Trình Lập Trình Truyền Thông
Các câu lệnh read(), write() có thể đ ợc th c hiện nhiều lần (ký hiệu bằng
hình ellipse).
Kênh ảo sẽ bị xóa khi Server hoặc Client đóng socket bằng lệnh close().
•
Nh vậy toàn bộ tiến trình diễn ra nh sau:
1.2.2. Mô hình Client-Server sử dụng Socket ở chế độ không n i kết
(UDP)
Giai đoạn 1: Server tạo Socket - gán s hiệu cổng.
o
socket(): Server yêu cầu tạo một socket để có thể sử dụng các dịch vụ c a
tầng vận chuyển.
o
bind(): Server yêu cầu gán s hiệu cổng cho socket..
Giai đoạn 2: Client tạo Socket.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
63
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Giai đoạn 3: Trao đổi thông tin giữa Client và Server.
Sau khi tạo Socket xong, Client và Server có thể trao đổi thông tin qua lại với nhau
thông qua hai hàm sendto() và recvfrom(). Đ n vị dữ liệu trao đổi giữa Client và Server là
các Datagram Package (Gói tin th tín). Protocol c a ng dụng phải định nghĩa khuôn
dạng và ý nghĩa c a các Datagram Package. Mỗi Datagram Package có ch a thông tin về
địa chỉ ng i g i và ng i nhận (IP, Port).
1.3. Socket d ới ngôn ngữ Java
Java hỗ trợ lập trình mạng thông qua các lớp trong gói java.net. Một s lớp tiêu
biểu đ ợc dùng cho lập trình Client-Server sử dụng socket làm ph ng tiện giao tiếp nh :
•
•
•
•
•
InetAddress: Lớp này quản lý địa chỉ Internet bao gồm địa chỉ IP và tên máy
tính.
Socket: Hỗ trợ các ph ng th c liên quan đến Socket cho ch ng trình Client
chế độ có n i kết.
ServerSocket: Hỗ trợ các ph ng th c liên quan đến Socket cho ch ng trình
Server chế độ có n i kết.
DatagramSocket: Hỗ trợ các ph ng th c liên quan đến Socket chế độ
không n i kết cho cả Client và Server.
DatagramPacket: Lớp cài đặt gói tin dạng th tín ng i dùng (Datagram
Packet) trong giao tiếp giữa Client và Server chế độ không n i kết.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
64
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
1.3.1. Xây dựng ch
- Giáo Trình Lập Trình Truyền Thông
ng trình Client ở chế độ có n i kết
Các b ớc tổng quát:
1. M một socket n i kết đến server đã biết địa chỉ IP (hay tên miền) và s hiệu
cổng.
2. Lấy InputStream và OutputStream gán với Socket.
3. Tham khảo Protocol c a dịch vụ để định dạng đúng dữ liệu trao đổi với
Server.
4. Trao đổi dữ liệu với Server nh vào các InputStream và OutputStream.
5. Đóng Socket tr ớc khi kết thúc ch ng trình.
1.3.1.1. Lớp java.net.Socket
Lớp Socket hỗ trợ các ph ng th c cần thiết để xây dựng các ch ng trình client sử
dụng socket chế độ có n i kết. D ới đây là một s ph ng th c th ng dùng để xây
dựng Client:
public Socket(String HostName, int PortNumber) throws IOException
Ph ng th c này dùng để n i kết đến một server có tên là HostName, cổng là
PortNumber. Nếu n i kết thành công, một kênh ảo sẽ đ ợc hình thành giữa Client và
Server.
•
•
HostName: Địa chỉ IP hoặc tên logic theo dạng tên miền.
PortNumber: có giả trị từ 0 ..65535
Ví dụ: M socket và n i kết đến Web Server c a khoa Công Nghệ Thông Tin, Đại
Học Cần Th :
Socket s = new Socket(“www.cit.ctu.edu.vn”,80);
Hoặc: Socket s = new Socket(“203.162.36.149”,80);
public InputStream getInputStream()
Ph ng th c này trả về InputStream n i với Socket. Ch
InputStream này để nhận dữ liệu từ Server g i về.
ng trình Client dùng
Ví dụ: Lấy InputStream c a Socket s:
InputStream is = s.getInputStream();
public OutputStream getOutputStream()
Ph ng th c này trả về OutputStream n i với Socket. Ch
OutputStream này để g i dữ liệu cho Server.
ng trình Client dùng
Ví dụ: Lấy OutputStream c a Socket s:
OutputStream os = s.getOutputStream();
public close()
Ph
Server.
ng th c này sẽ đóng Socket lại, giải phóng kênh ảo, xóa n i kết giữa Client và
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
65
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Ví dụ: Đóng Socket s:
s.close();
1.3.1.2. Ch
ng trình TCPEchoClient
Trên hệ th ng UNIX, Dịch vụ Echo đ ợc thiết kế theo kiến trúc Client-Server sử
dụng Socket làm ph ng tiện giao tiếp. Cổng mặc định dành cho Echo Server là 7, bao
gồm cả hai chế độ có n i kết và không n i kết.
Ch ng trình TCPEchoClient sẽ n i kết đến EchoServer chế độ có n i kết, lần
l ợt g i đến Echo Server 10 ký tự từ ‘0’ đến '9', ch nhận kết quả trả về và hiển thị chúng
ra màn hình.
Hãy l u ch
ng trình sau vào tập tin TCPEchoClient.java
import java.io.*;
import java.net.Socket;
public class TCPEchoClient{
public static void main(String args[]){
try {
Socket s = new Socket(args[0],7);
// N i kết đến Server
InputStream is = s.getInputStream();
// Lấy InputStream
OutputStream os = s.getOutputStream(); // Lấy OutputStream
for (int i='0'; i<='9';i++){ // Gui ‘0’ ->’9’ den EchoServer
os.write(i);
// G i 1 ký tự sang Server
int ch = is.read();
// Ch nhận 1 ký tự từ Server
System.out.print((char)ch); // In ký tự nhận đ ợc ra màn hình
}
} //try
catch(IOException ie){
System.out.println("Loi: Khong tao duoc socket");
} //catch
} //main
}
Biên dịch và thực thi ch
ng trình nh sau:
Ch ng trình này nhận một đ i s là địa chỉ IP hay tên miền c a máy tính mà đó
Echo Server đang chạy. Trong hệ th ng mạng TCP/IP mỗi máy tính đ ợc gán một địa chỉ
IP cục bộ là 127.0.0.1 hay có tên là localhost. Trong ví dụ trên, ch ng trình Client n i
kết đến Echo Server trên cùng máy với nó.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
66
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
1.3.2. Xây dựng ch
- Giáo Trình Lập Trình Truyền Thông
ng trình Server ở chế độ có n i kết
1.3.2.1. Lớp java.net.ServerSocket
Lớp ServerSocket hỗ trợ các ph ng th c cần thiết để xây dụng các ch ng trình
Server sử dụng socket chế độ có n i kết. D ới đây là một s ph ng th c th ng dùng
để xây dựng Server:
public ServerSocket(int PortNumber);
Ph ng th c này tạo một Socket với s hiệu cổng là PortNumber mà sau đó Server
sẽ lắng nghe trên cổng này.
Ví dụ: Tạo socket cho Server với s hiệu cổng là 7:
ServerSocket ss = new ServerSocket(7);
public Socket accept()
Ph ng th c này lắng nghe yêu cầu n i kết c a các Client. Đây là một ph ng th c
hoạt động chế độ nghẽn. Nó sẽ bị nghẽn cho đến khi có một yêu cầu n i kết c a client
g i đến.
Khi có yêu cầu n i kết c a Client g i đến, nó sẽ chấp nhận yêu cầu n i kết, trả về
một Socket là một đầu c a kênh giao tiếp ảo giữa Server và Client yêu cầu n i kết.
Ví dụ: Socket ss ch nhận yêu cầu n i kết:
Socket s = ss.accept();
Server sau đó sẽ lấy InputStream và OutputStream c a Socket mới s để giao tiếp
với Client.
1.3.2.2. Xây dựng ch
ng trình Server phục vụ tuần tự
Một Server có thể đ ợc cài đặt để phục vụ các Client theo hai cách: phục vụ tuần tự
hoặc phục vụ song song.
Trong chế độ phục vụ tuần tự, tại một th i điểm Server chỉ chấp nhận một yêu cầu
n i kết. Các yêu cầu n i kết c a các Client khác đều không đ ợc đáp ng (đ a vào hàng
đợi).
Ng ợc lại trong chế độ phục vụ song song, tại một th i điểm Server chấp nhận
nhiều yêu cầu n i kết và phục vụ nhiều Client cùng lúc.
Các b ớc tổng quát c a một Server phục vụ tuần tự
1. Tạo socket và gán s hiệu cổng cho server.
2. Lắng nghe yêu cầu n i kết.
3. Với một yêu cầu n i kết đ ợc chấp nhận thực hiện các b ớc sau:
o Lấy InputStream và OutputStream gắn với Socket c a kênh ảo vừa
đ ợc hình thành.
o Lặp lại công việc sau:
Ch nhận các yêu cầu (công việc).
Phân tích và thực hiện yêu cầu.
Tạo thông điệp trả l i.
G i thông điệp trả l i về Client.
Nếu không còn yêu cầu hoặc Client kết thúc, đóng Socket và
quay lại b ớc 2.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
67
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
1.3.2.3. Ch
- Giáo Trình Lập Trình Truyền Thông
ng trình STCPEchoServer
STCPEchoServer cài đặt một Echo Server phục vụ tuần tự
Server lắng nghe trên cổng mặc định s 7.
Hãy l u ch ng trình sau vào tập tin STCPEchoServer.java
chế độ có n i kết.
import java.net.*;
import java.io.*;
public class STCPEchoServer {
public final static int defaultPort = 7;
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(defaultPort);
while (true) {
try {
Socket s = ss.accept();
OutputStream os = s.getOutputStream();
InputStream is = s.getInputStream();
int ch=0;
while(true) {
ch = is.read();
if(ch == -1) break;
os.write(ch);
}
s.close();
}
catch (IOException e) {
System.err.println(" Connection Error: "+e);
}
}
}
catch (IOException e) {
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
68
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
System.err.println(" Server Creation Error:"+e);
}
}
}
Biên dịch và thực thi ch
ng trình theo cách sau:
M một cửa s DOS khác và thực thi ch
nh sau:
ng trình TCPEchoClient ta có kết quả
Hai ch ng trình này có thể nằm trên hai máy khác nhau. Trong tr ng hợp đó khi
thực hiện ch ng trình TCPEchoClient phải chú ý nhập đúng địa chỉ IP c a máy tính đang
chạy ch ng trình STCPEchoServer.
Xem địa chỉ IP c a một máy tính Windows bằng lệnh ipconfig.
1.3.2.4. Server phục vụ song song
Các b ớc tổng quát c a một Server phục vụ song song
Server phục vụ song song gồm 2 phần thực hiện song song nhau:
•
•
Phần 1: Xử lý các yêu cầu n i kết.
Phần 2: Xử lý các thông điệp yêu cầu
từ khách hàng.
Có cấu trúc nh hình sau, trong đó Phần 1
là (Dispatcher Thread), Phần 2 là các (Worker
Thread)
Phần 1: Lặp lại các công việc sau:
•
Lắng nghe yêu cầu n i kết c a khách
hàng.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
Hình 4.5 Server
chế độ song song
69
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
- Giáo Trình Lập Trình Truyền Thông
Chấp nhận một yêu cầu n i kết.
o Tạo kênh giao tiếp ảo mới với khách hàng.
o Tạo Phần 2 để xử lý các thông điệp yêu cầu c a khách hàng.
Phần 2: Lặp lại các công việc sau:
•
•
•
Ch nhận thông điệp yêu cầu c a khách hàng.
Phân tích và xử lý yêu cầu.
G i thông điệp trả l i cho khách hàng.
Phần 2 sẽ kết thúc khi kênh ảo bị xóa đi.
Với mỗi Client, trên Server sẽ có một Phần 2 để xử lý yêu cầu c a khách hàng.
Nh vậy tại một th i điểm bất kỳ luôn tồn tại 1 Phần 1 và 0 hoặc nhiều Phần 2.
Do Phần 2 thực thi song song với Phần 1 cho nên nó đ ợc thiết kế là một Thread.
1.3.2.5. Ch
ng trình PTCPEchoServer
PTCPEchoServer cài đặt một Echo Server phục vụ song song chế độ có n i kết.
Server lắng nghe trên cổng mặc định là 7. Ch ng trình này gồm 2 lớp:
•
•
Lớp TCPEchoServer, cài đặt các ch c năng c a Phần 1 - xử lý các yêu cầu
n i kết c a TCPEchoClient.
Lớp RequestProcessing, là một Thread cài đặt các ch c năng c a Phần 2 - Xử
lý các thông điệp yêu cầu.
Hãy l u ch
ng trình sau vào tập tin PTCPEchoServer.java
import java.net.*;
import java.io.*;
public class PTCPEchoServer {
public final static int defaultPort = 7; // Cổng mặc định
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(defaultPort); //Tạo socket cho server
while (true) {
try {
Socket s = ss.accept(); // Lắng nghe các yêu cầu n i kết
RequestProcessing rp = new RequestProcessing(s); // Tạo phần xử lý
rp.start(); // Kh i động phần xử lý cho Client hiện tại
}
catch (IOException e) {
System.out.println("Connection Error: "+e);
}
}
}
catch (IOException e) {
System.err.println("Create Socket Error: "+e);
}
}
}
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
70
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
class RequestProcessing extends Thread {
Socket channel; //Socket c a kênh ảo n i với Client hiện tại
public RequestProcessing(Socket s){
channel = s; // Nhận socket c a kênh ảo n i với Client
}
public void run() {
try {
OutputStream os = channel.getOutputStream();
InputStream is = channel.getInputStream();
while (true) {
int n = is.read();
// Nhận ký tự từ Client
if (n == -1) break; // Thoát nếu kênh ảo bị xóa
os.write(n);
// G i ký tự nhận đ ợc về Client
}
}
catch (IOException e) {
System.err.println("Request Processing Error: "+e);
}
}
}
Biên dịch và thực thi ch
ng trình nh sau:
Sau đó m thêm 2 c a sổ DOS khác để thực thi ch ng trình TCPEchoClient n i
kết tới PTCPEchoServer. Ta sẽ nhận thấy rằng PTCPEchoServer có khả năng phục vụ
đồng th i nhiều Client.
1.3.3. Xây dựng ch
ng trình Client - Server ở chế độ không n i kết
Khi sử dụng socket, ta có thể chọn giao th c UDP cho lớp vận chuyển. UDP viết tắt
c a User Datagram Protocol, cung cấp c chế vận chuyển không bảo đảm và không n i
kết trên mạng IP, ng ợc với giao th c vận chuyển tin cậy, có n i kết TCP.
Cả giao th c TCP và UDP đều phân dữ liệu ra thành các gói tin. Tuy nhiên TCP có
thêm vào những tiêu đề (Header) vào trong gói tin để cho phép truyền lại những gói tin
thất lạc và tập hợp các gói tin lại theo th tự đúng đắn. UDP không cung cấp tính năng
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
71
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
này, nếu một gói tin bị thất lạc hoặc bị lỗi, nó sẽ không đ ợc truyền lại, và th tự đến đích
c a các gói tin cũng không gi ng nh th tự lúc nó đ ợc g i đi.
Tuy nhiên, về t c độ, UDP sẽ truyền nhanh gấp 3 lần TCP. Cho nên chúng th ng
đ ợc dùng trong các ng dụng đòi h i th i gian truyền tải ngắn và không cần tính chính
xác cao, ví dụ truyền âm thanh, hình ảnh . . .
Mô hình client - server sử dụng lớp ServerSocket và Socket trên sử dụng giao
th c TCP. Nếu mu n sử dụng mô hình client - server với giao th c UDP, ta sử dụng hai
lớp java.net.DatagramSocket và java.net.DatagramPacket.
DatagramSocket đ ợc sử dụng để truyền và nhận các DatagramPacket. Dữ liệu
đ ợc truyền đi là một mảng những byte, chúng đ ợc gói vào trong lớp DatagramPacket.
Chiều dài c a dữ liệu t i đa có thể đ a vào DatagramPacket là khoảng 60.000 byte (phụ
thuộc vào dạng đ ng truyền). Ngoài ra DatagramPacket còn ch a địa chỉ IP và cổng c a
quá trình g i và nhận dữ liệu.
Cổng trong giao th c TCP và UDP có thể trùng nhau. Trên cùng một máy tính, bạn
có thể gán cổng 20 cho socket dùng giao th c TCP và cổng 20 cho socket sử dụng giao
th c UDP.
1.3.3.1. Lớp DatagramPacket
Lớp này dùng để đóng gói dữ liệu g i đi. D ới đây là các ph
dụng để thao tác trên dữ liệu truyền / nhận qua DatagramSocket.
ng th c th
ng sử
public DatagramPacket(byte[] b, int n)
•
•
Là ph ng th c kh i tạo, cho phép tạo ra một DatagramPacket ch a n bytes
dữ liệu đầu tiên c a mảng b. (n phải nh h n chiều dài c a mảng b)
Ph ng th c trả về một đ i t ợng thuộc lớp DatagramePacket
Ví dụ: Tạo DatagramPacket để nhận dữ liệu:
byte buff[] = new byte[60000];
// N i ch a dữ liệu nhận đ ợc
DatagramPacket inPacket = new Datagrampacket(buff, buff.lenth);
public DatagramPacket(byte[] b, int n, InternetAddress ia, int port)
•
•
Ph ng th c này cho phép tạo một DatagramPacket ch a dữ liệu và cả địa chỉ
c a máy nhận dữ liệu.
Ph ng th c trả về một đ i t ợng thuộc lớp DatagramePacket
Ví dụ: Tạo DatagramPacket ch a chuỗi "My second UDP Packet", với địa chỉ máy
nhận là www.cit.ctu.edu.vn, cổng c a quá trình nhận là 19:
try {//Địa chỉ Internet c a máy nhận
InetAddress ia = InetAddess.getByName("www.cit.ctu.edu.vn");
int port = 19; // Cổng c a socket nhận
String s = "My second UDP Packet"; // Dữ liệu g i đi
byte[] b = s.getBytes(); // Đổi chuỗi thành mảng bytes
// Tạo gói tin g i đi
DatagramPacket outPacket = new DatagramPacket(b, b.length, ia, port);
}
catch (UnknownHostException e) {
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
72
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
System.err.println(e);
}
Các ph
ng th c lấy thông tin trên một DatagramPacket nhận đ ợc
Khi nhận đ ợc một DatagramPacket từ một quá trình khác g i đến, ta có thể lấy
thông tin trên DatagramPacket này bằng các ph ng th c sau:
•
•
•
•
public synchronized() InternetAddress getAddress() : Địa chỉ máy g i
public synchronized() int getPort() : Cổng c a quá trình g i
public synchronized() byte[] getData() : Dữ liệu từ gói tin
public synchronized() int getLength() : Chiều dài c a dữ liệu trong gói tin
Các ph
ng th c đặt thông tin cho gói tin gởi
Tr ớc khi g i một DatagramPacket đi, ta có thể đặt thông tin trên DatagramPacket
này bằng các ph ng th c sau:
•
•
•
•
public synchronized() void setAddress(IntermetAddress dis) : Đặt địa chỉ máy
nhận.
public synchronized() void setPort(int port) : Đặt cổng quá trình nhận
public synchronized() void setData(byte buffer[]) : Đặt dữ liệu g i
public synchronized() void setLength(int len) : Đặt chiều dài dữ liệu g i
1.3.3.2. Lớp DatagramSocket
Lớp này hỗ trợ các ph
ng th c sau để g i / nhận các DatagramPacket
public DatagramSocket() throws SocketException
•
Tạo Socket kiểu không n i kết cho Client. Hệ th ng tự động gán s hiệu cổng
ch a sử dụng cho socket.
Ví dụ: Tạo một socket không n i kết cho Client:
try{
DatagramSocket ds = new DatagramSocket();
} catch(SocketException se) {
System.out.print("Create DatagramSocket Error: "+se);
}
public DatagramSocket(int port) throws SocketException
•
Tạo Socket kiểu không n i kết cho Server với s hiệu cổng đ ợc xác định
trong tham s (port).
Ví dụ: Tạo một socket không n i kết cho Server với s hiệu cổng là 7:
try{
DatagramSocket dp = new DatagramSocket(7);
} catch(SocketException se) {
System.out.print("Create DatagramSocket Error: "+se);
}
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
73
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
public void send(DatagramPacket dp) throws IOException
•
Dùng để g i một DatagramPacket đi.
Ví dụ: G i chuỗi "My second UDP Packet", cho quá trình
www.cit.ctu.edu.vn, cổng nhận là 19:
địa chỉ
try {
DatagramSocket ds = new DatagramSocket(); //Tạo Socket
//Địa chỉ Internet c a máy nhận
InetAddress ia = InetAddess.getByName("www.cit.ctu.edu.vn");
int port = 19; // Cổng c a quá trình nhận
String s = "My second UDP Packet"; // Dữ liệu cần g i
byte[] b = s.getBytes(); // Đổi sang mảng bytes
// Tạo gói tin
DatagramPacket outPacket = new DatagramPacket(b, b.length, ia, port);
ds.send(outPacket); // G i gói tin đi
}
catch (IOException e) {
System.err.println(e);
}
public synchronized
IOException
•
void
receive(Datagrampacket
dp)
throws
Ch nhận một DatagramPacket. Quá trình sẽ bị nghẽn cho đến khi có dữ liệu
đến.
Ví dụ:
try {
DatagramSocket ds = new DatagramSocket(); //Tạo Socket
byte[] b = new byte[60000]; // N i ch a dữ liệu nhận đ ợc
DatagramPacket inPacket = new DatagramPacket(b, b.length); // Tạo gói tin
ds.receive(inPacket); // Ch nhận gói tin
}
catch (IOException e) {
System.err.println(e);
}
1.3.3.3. Ch
ng trình UDPEchoServer
Ch ng trình UDPEchoServer cài đặt Echo Server chế độ không n i kết, cổng
mặc định là 7. Ch ng trình ch nhận từng gói tin, lấy dữ liệu ra kh i gói tin nhận đ ợc và
g i ng ợc dữ liệu đó về Client.
L u ch
ng trình sau vào tập tin UDPEchoServer.java
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
74
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
import java.net.*;
import java.io.*;
public class UDPEchoServer {
public final static int port = 7; // Cổng mặc định c a Server
public static void main(String[] args) {
try {
DatagramSocket ds = new DatagramSocket(port); // Tạo Socket với cổng là 7
byte[] buffer = new byte[6000]; // Vùng đệm ch a dữ liệu cho gói tin nhận
while(true) {
// Tạo gói tin nhận
DatagramPacket incoming = new DatagramPacket(buffer,buffer.length);
ds.receive(incoming); // Ch nhận gói tin g i đến
// Lấy dữ liệu kh i gói tin nhận
String theString = new String(incoming.getData(),0,incoming.getLength());
// Tạo gói tin g i ch a dữ liệu vừa nhận đ ợc
DatagramPacket outsending = new DatagramPacket(theString.getBytes(),
incoming.getLength(),incoming.getAddress(), incoming.getPort());
ds.send(outsending);
}
}
catch (IOException e) {
System.err.println(e);
}
}
}
Biên dịch và thực thi ch
1.3.3.4. Ch
ng trình nh sau
ng trình UDPEchoClient
Ch ng trình này cho phép ng i sử dụng nhận các chuỗi từ bàn phím, g i chuỗi
sang EchoServer chế độ không n i kết cổng s 7, ch nhận và in dữ liệu từ Server g i
về ra màn hình.
L u ch
ng trình sau vào tập tin UDPEchoClient.java
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
75
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
import java.net.*;
import java.io.*;
public class UDPEchoClient extends Object{
public final static int serverPort = 7; // Cổng mặc định c a Echo Server
public static void main(String[] args) {
try {
if (args.length ==0) { // Kiểm tra tham s , là địa chỉ c a Server
System.out.print("Syntax: java UDPClient HostName");
return;
}
DatagramSocket ds = new DatagramSocket(); // Tạo DatagramSocket
InetAddress server = InetAddress.getByName(args[0]); // Địa chỉ Server
while(true) {
InputStreamReader isr = new InputStreamReader(System.in); // Nhập
BufferedReader br = new BufferedReader(isr);
// một chuỗi
String theString = br.readLine();
// từ bàn phím
byte[] data = theString.getBytes(); // Đổi chuỗi ra mảng bytes
// Tạo gói tin g i
DatagramPacket dp = new DatagramPacket(data,data.length,server, serverPort);
ds.send(dp); // Send gói tin sang Echo Server
byte[] buffer = new byte[6000]; // Vùng đệm cho dữ liệu nhận
// Gói tin nhận
DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
ds.receive(incoming); // Ch nhận dữ liệu từ EchoServer g i về
// Đổi dữ liệu nhận đ ợc dạng mảng bytes ra chuỗi và in ra màn hình
System.out.println(new String(incoming.getData(), 0, incoming.getLength()));
}
}
catch (IOException e) {
System.err.println(e);
}
}
}
Biên dịch và thực thi ch
ng trình nh sau:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
76
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Chú ý, khi thực hiện ch ng trình UDPEchoClient phải đ a vào đ i s là địa chỉ
c a máy tính đang thực thi ch ng trình UDPEchoServer. Trong ví dụ trên, Server và
Client cùng chạy trên một máy nên địa chỉ c a UDPEchoServer là localhost (hay
127.0.0.1). Nếu UDPEchoServer chạy trên máy tính khác thì khi thực thi, ta phải biết đ ợc
địa chỉ IP c a máy tính đó và cung cấp vào đ i s c a ch ng trình. Chẳng hạn, khi
UDPEchoServer đang phục vụ trên máy tính địa chỉ 172.18.250.211, ta sẽ thực thi
UDPEchoClient theo cú pháp sau:
java UDPEchoClient 172.18.250.211
1.4. Bài tập áp dụng
Ch đề 1: Client ở chế độ có n i kết
•
Mục đích:
Viết các ch
•
ng trình Client n i kết đến các server theo các Protocol chuẩn.
Yêu cầu
Sinh viên thực hiện các bài tập sau
o
Bài 1 : Viết ch ng trình nhận đ i s là một URL. N i kết đến Web
Server trong URL nhận đ ợc, lấy trang web về và in ra màn hình theo
dạng textfile (html).
Ch đề 2: Client - Server chế độ có n i kết
•
•
Mục đích:
o Viết các ch
Yêu cầu
ng trình Client -Server theo chế độ có n i kết.
Sinh viên thực hiện các bài tập sau, với mỗi bài tập hãy thiêt kế một Server
phục vụ chế độ tuần tự và một Server phục vụ chế độ song song.
o
Bài 1: Viết ch ng trình theo mô hình Client-Server sử dụng dụng
Socket chế độ có n i kết. Trong đó :
+ Server làm nhiệm vụ đọc một ký tự s từ '0' đến '9'.
( Ví dụ : nhận s 0 : trả về "khong" , 1 : trả về "một" ; ... ... 9 : trả về
"chín", nếu nhận ký tự khác s thì trả về "Không phải s nguyên" ).
+ Client sẽ nhập vào 1 ký tự, gửi qua Server, nhận kết quả trả về từ
Server và thể hiện lên màn hình
o
Bài 2: Viết ch ng trình theo mô hình Client-Server sử dụng Socket
chế độ có n i kết. Trong đó :
+ Server sẽ nhận các yêu cầu là một chuỗi có khuôn dạng nh sau:
"OP Operant1 Operant2\n"
Trong đó:
- OP là một ký tự chỉ phép toán mu n thực hiện: '+','-', '*', '/'.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
77
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
- Operant1, Operant2 là đ i s c a phép toán.
- Các thành phần trên cách nhau b i 1 ký tự trắng ' '.
- Kết thúc yêu cầu bằng ký tự xu ng dòng '\n'.
Mỗi khi server nhận đ ợc một thông điệp nó sẽ thực hiện phép toán:
Operant1 OP Operant2 để cho ra kết quả, sau đó đổi kết quá thành
chuỗi và g i về Client.
+ Client cho phép ng i dùng nhập các phép toán mu n tính theo cách
th c thông th ng. Ví dụ: 100+200. Client tạo ra thông điệp yêu cầu
theo đúng dạng do Server qui định, mô tả về phép toán mu n Server
thực thi, rồi g i sang Server, ch nhận kết quả trả về và in ra màn hình.
Ch đề 3: Client-Server ở chế độ không n i kết
•
•
Mục đích:
o Viết các ch ng trình Client -Server theo chế độ không n i kết.
Yêu cầu
o Bài 1 : Viết ch ng trình Talk theo chế độ không n i kết. Cho phép hai
ng i ngồi trên hai máy tính có thể tán gẫu (chat) với nhau.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
78
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
CH
NG 5
RPC và RMI
Mục đích
Ch ng này nhằm giới thiệu cách th c xây dựng các ng dụng phân tán bằng các
c chế gọi th tục từ xa (RPC - Remote Procedure Call và RMI - Remote Method
Invocation)
Yêu cầu
Sau khi hoàn tất ch
•
•
•
•
•
•
•
•
•
•
ng này, bạn có thể:
Định nghĩa đ ợc ng dụng phân tán là gì.
Trình bày đ ợc kiến trúc c a một ng dụng phân tán xây dựng theo c chế
gọi th tục từ xa (RPC).
Trình bày đ ợc kiến trúc c a một ng dụng phân tán (hay còn gọi ng dụng
đ i t ợng phân tán ) xây dựng theo c chế RMI c a Java.
Trình bày đ ợc các c chế liên quan khi xây dựng một ng dụng theo kiểu
RMI.
Trình bày đ ợc c chế vận hành c a một ng dụng theo kiểu RMI.
Giải thích đ ợc vai trò rmiregistry server.
Liệt kê đ ợc các lớp c a java hỗ trợ xây dựng các ng dụng kiểu RMI.
Trình bày chi tiết các b ớc phải qua khi xây dựng một ng dụng theo kiểu
RMI.
Biên soạn, biên dịch và thực thi thành công ch ng trình minh họa Hello.
Phân tích, thiết kế và cài đặt đ ợc các ch ng trình theo c chế RMI để giải
quyết các vấn đề cụ thể.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
79
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.1. Lời gọi th tục xa (RPC- Remote Procedure Call)
1.1.1. Giới thiệu
L i gọi th tục xa là một c chế cho phép một ch ng trình có thể gọi thực thi một
th tục (hay hàm) trên một máy tính khác. Trong ch ng trình lúc này, tồn tại hai loại th
tục: th tục cục bộ và th tục xa.
•
•
Th tục cục bộ là th tục đ ợc định nghĩa, cài đặt và thực thi tại máy c a
ch ng trình.
Th tục xa là th tục đ ợc định nghĩa, cài đặt và thực thi trên một máy tính
khác.
Cú pháp giữa l i gọi th tục cục bộ và xa thì gi ng nhau. Tuy nhiên, khi một th
tục xa đ ợc gọi đến, một thành phần c a ch ng trình gọi là Stub sẽ chuyển h ớng để
kích hoạt một th tục t ng ng nằm trên một máy tính khác với máy c a ch ng trình
gọi. Đ i với ng i lập trình, việc gọi th tục xa và th tục cục bộ thì gi ng nhau về mặt cú
pháp. Đây chính là c chế cho phép đ n giản hóa việc xây dựng các ng dụng ClientServer. Trong hệ th ng RPC, Server chính là máy tính cung cấp các th tục xa cho phép
các ch ng trình trên các máy tính khác gọi thực hiện. Client chính là các ch ng trình có
thể gọi các th tục xa trong quá trình tính toán c a mình.
Một Client có thể gọi th tục xa c a nhiều h n một máy tính. Nh vậy sự thực thi
c a ch ng trình Client lúc này không còn gói gọn trên một máy tính c a Client mà nó trải
rộng trên nhiều máy tính khác nhau. Đây chính là mô hình c a ng dụng phân tán
(Distributed Application).
1.1.2. Kiến trúc c a ch
th tục xa
ng trình Client-Server cài đặt theo c chế lời gọi
Một ng dụng Client-Server theo c chế RPC đ ợc xây dựng gồm có sáu phần nh
s đồ d ới đây:
Hình 5.1 Kiến trúc ch
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
ng trình kiểu RPC
80
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Phần Client là một quá trình ng i dùng, n i kh i tạo một l i gọi th tục từ xa. Mỗi
l i gọi th tục xa trên phần Client sẽ kích hoạt một th tục cục bộ t ng ng nằm trong
phần Stub c a Client.
Phần ClientStub cung cấp một bộ các hàm cục bộ mà phần Client có thể gọi. Mỗi
một hàm c a ClientStub đại diện cho một hàm xa đ ợc cài đặt và thực thi trên Server.
Mỗi khi một hàm nào đó c a ClientStub đ ợc gọi b i Client, ClientStub sẽ đóng
gói một thông điệp để mô tả về th tục xa t ng ng mà Client mu n thực thi cùng với
các tham s nếu có. Sau đó nó sẽ nh hệ th ng RPCRuntime cục bộ g i thông điệp này
đến phần Server Stub c a Server.
Phần RPCRuntime quản lý việc truyền thông điệp thông qua mạng giữa máy Client
và máy Server. Nó đảm nhận việc truyền lại, báo nhận, chọn đ ng gói tin và mã hóa
thông tin.
RPCRuntime trên máy Client nhận thông điệp yêu cầu từ ClientStub, g i nó cho
RPCRuntime trên máy Server bằng lệnh send(). Sau đó gọi lệnh wait() để ch kết quả trả
về từ Server.
Khi nhận đ ợc thông tiệp từ RPCRuntime c a Client g i sang, RPCRuntime bên
phía server chuyển thông điệp lên phần ServerStub.
ServerStub m thông điệp ra xem, xác định hàm
cùng với các tham s c a nó. ServerStub gọi một th tục t
xa mà Client mu n thực hiện
ng ng nằm trên phần Server.
Khi nhận đ ợc yêu cầu c a ServerStub, Server cho thực thi th tục đ ợc yêu cầu và
g i kết quả thực thi đ ợc cho ServerStub.
ServerStub đóng gói kết quả thực trong một gói tin trả l i, chuyển cho phần
RPCRuntime cục bộ để nó g i sang RPCRuntime c a Client .
RPCRuntime bên phía Client chuyển gói tin trả l i nhận đ ợc cho phần ClientStub.
ClientStub m thông điệp ch a kết quả thực thi về cho Client tại vị trí phát ra l i gọi th
tục xa.
Trong các thành phần trên, RPCRuntime đ ợc cung cấp b i hệ th ng. ClientStub và
ServerStub có thể tạo ra th công (phải lập trình) hay có thể tạo ra bằng các công cụ cung
cấp b i hệ th ng.
C chế RPC đ ợc hỗ trợ b i hầu hết các hệ điều hành mạng cũng nh các ngôn ngữ
lập trình.
1.2. Kích hoạt ph
ng th c xa (RMI- Remote Method Invocation )
1.2.1. Giới thiệu
RMI là một sự cài đặt c chế RPC trong ngôn ngữ lập trình h ớng đ i t ợng Java.
Hệ th ng RMI cho phép một đ i t ợng chạy trên một máy ảo Java này có thể kích hoạt
một ph ng th c c a một đ i t ợng đang chạy trên một máy ảo Java khác. Đ i t ợng có
ph ng th c đ ợc gọi từ xa gọi là các đ i t ợng xa (Remote Object).
Một ng dụng RMI th
một ch ng trình Client.
ng bao gồm 2 phần phân biệt: Môt ch
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
ng trình Server và
81
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
•
- Giáo Trình Lập Trình Truyền Thông
Ch ng trình Server tạo một s các Remote Object, tạo các tham chiếu
(reference) đến chúng và ch những ch ng trình Client kích hoạt các
ph ng th c c a các Remote Object này.
Ch ng trình Client lấy một tham chiếu đến một hoặc nhiều Remote Object
trên Server và kích hoạt các ph ng th c từ xa thông qua các tham chiếu.
Một ch ng trình Client có thể kích hoạt các ph ng th c xa trên một hay nhiều
Server. T c là sự thực thi c a ch ng trình đ ợc trải rộng trên nhiều máy tính. Đây chính
là đặc điểm c a các ng dụng phân tán. Nói cách khác, RMI là c chế để xây dựng các
ng dụng phân tán d ới ngôn ngữ Java.
1.2.2. Kiến trúc c a ch
Kiến trúc một ch
d ới đây:
ng trình Client-Server theo c chế RMI
ng trình Client-Server theo c chế RMI đ ợc mô tả nh hình
Hình 5.2 - Kiến trúc ch
ng trình kiểu RMI
Trong đó:
•
•
•
•
•
Server là ch ng trình cung cấp các đ 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.
Con đ
ng kích hoạt một ph
ng th c
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
xa đ ợc mô tả nh hình d ới đây:
82
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
Hình 5.3 C chế hoạt động c a RMI
1.2.3. Các c chế liên quan trong một ng dụng đ i t ợng phân tán
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 (Locate remote objects): C chế này xác định
cách th c mà ch ng trình Client có thể lấy đ ợc tham chiếu (Stub) đến các
đ i t ợng
xa. Thông th ng ng i ta sử dụng một Dịch vụ danh bạ
(Naming Service) l u giữ các tham khảo đến các đ i t ợng cho phép gọi từ xa
mà Client sau đó có thể tìm kiếm.
Cơ chế giao tiếp với các đối tượng ở xa (Communicate with remote objects):
Chi tiết c a c chế giao tiếp với các đ i t ợng xa đ ợc cài đặt b i hệ th ng
RMI.
Tải các lớp dạng bytecodes cho các lớp mà nó được chuyển tải qua lại giữa
Máy ảo (Load class bytecodes for objects that are passed around): Vì RMI
cho phép các ch ng trình gọi ph ng th c từ xa trao đổi các đ i t ợng với
các ph ng th c xa d ới dạng các tham s hay giá trị trả về c a ph ng
th c, nên RMI cần có c chế cần thiết để tải mã Bytecodes c a các đ i t ợng
từ máy ảo này sang máy ảo khác.
Hình d ới đây mô tả một ng dụng phân tán d ới RMI sử dụng dịch vụ danh bạ để
lấy các tham khảo c a các đ i t ợng xa. Trong đó:
•
•
Server đăng ký tên cho
đ i t ợng có thể đ ợc
gọi từ xa c a mình với
Dịch vụ danh bạ
(Registry Server).
Client tìm đ i t ợng
xa thông qua tên đã
đ ợc đăng ký trên
Registry Server (looks
up) và tiếp đó gọi các
ph ng th c xa.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
Hình 5.4 Vai trò c a dịch vụ tên
83
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
•
- Giáo Trình Lập Trình Truyền Thông
Hình minh họa cũng cho thấy cách th c mà hệ th ng RMI sử dụng một
WebServer sẵn có để truyền tải mã bytecodes c a các lớp qua lại giữa Client
và Server.
1.2.4. C chế vận hành c a c a một
RMI
ng dụng Client-Server theo kiểu
Tiến trình vận hành c a một ng dụng Client-Server theo kiểu RMI diễn ra nh sau:
B ớc 1: Server tạo ra các đ i
t ợng cho phép gọi từ xa cùng với
các Stub và Skeleton c a chúng.
B ớc 2: Server sử dụng lớp
Naming để đăng ký tên cho một
đ i t ợng từ xa (1).
B ớc 3: Naming đăng ký Stub
c a đ i t ợng từ xa với Registry
Server (2).
B ớc 4: Registry Server sẵn sàng
cung cấp tham thảo đến đ i t ợng
từ xa khi có yêu cầu (3).
Client yêu cầu Naming định vị đ i
t ợng xa qua tên đã đ ợc đăng ký
(ph ng th c lookup) với dịch vụ
tên (4).
Naming tải Stub c a đ i t ợng xa từ dịch vụ tên mà đ i t ợng xa đã đăng ký
về Client (5).
Cài đặt đ i t ợng Stub và trả về tham khảo đ i t ợng xa cho Client (6).
Client thực thi một l i gọi ph
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
ng th c xa thông qua đ i t ợng Stub (7).
84
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
1.2.5. Các lớp hỗ trợ ch
- Giáo Trình Lập Trình Truyền Thông
ng trình theo kiểu Client-Server trong Java
Java hỗ trợ các lớp cần thiết để cài đặt các ng dụng Client-Server theo kiểu RMI
trong các gói: java.rmi. Trong s đó các lớp th ng đ ợc dùng là:
•
•
•
•
•
•
java.rmi.Naming
java.rmi.RMISecurityManager
java.rmi.RemoteException;
java.rmi.server.RemoteObject
java.rmi.server.RemoteServer
java.rmi. server.UnicastRemoteObject
1.3. Xây dựng một ng dụng phân tán với RMI
Xây dụng một ng dụng phân tán bằng c chế RMI gồm các b ớc sau:
1.
2.
3.
4.
Thiết kế và cài đặt các thành phần c a ng dụng.
Biên dịch các ch ng trình nguồn và tạo ra Stub và Skeleton.
Tạo các lớp có thể truy xuất từ mạng cần thiết.
Kh i tạo ng dụng
1.3.1. Thiết kế và cài đặt các thành phần c a ng dụng.
Đầu tiên bạn phải xác định lớp nào là lớp cục bộ, lớp nào là lớp đ ợc gọi từ
xa. Nó bao gồm các b ớc sau:
•
•
•
Định nghĩa các giao diện cho các phương thức ở xa (remote interfaces): Một
remote interface mô tả các ph ng th c mà nó có thể đ ợc kích hoạt từ xa b i
các Client. Đi cùng với việc định nghĩa Remote Interface là việc xác định các
lớp cục bộ làm tham s hay giá trị trả về c a các ph ng th c đ ợc gọi từ xa.
Cài đặt các đối tượng từ xa (remote objects): Các Remote Object phải cài đặt
cho một hoặc nhiều Remote Interfaces đã đ ợc định nghĩa. Các lớp c a
Remote Object class cài đặt cho các ph ng th c đ ợc gọi từ xa đã đ ợc khai
báo trong Remote Interface và có thể định nghĩa và cài đặt cho cả các ph ng
th c đ ợc sử dụng cục bộ. Nếu có các lớp làm đ i s hay giá trị trả về cho các
ph ng th c đ ợc gọi từ xa thì ta cũng định nghĩa và cài đặt chúng.
Cài đặt các chương trình Client: Các ch ng trình Client có sử dụng các
Remote Object có thể đ ợc cài đặt bất kỳ th i điểm nào sau khi các Remote
Interface đã đ ợc định nghĩa.
1.3.2. Biên dịch các tập tin nguồn và tạo Stubs và Skeleton
Giai đoạn này gồm 2 b ớc: B ớc th nhất là dùng ch ng trình biên dịch javac để
biên dịch các tập tin nguồn nh các remote interface, các lớp cài đặt cho các
remote interface, lớp server, lớp client và các lớp liên quan khác. Kế tiếp ta dùng
trình biện dịch rmic để tạo ra stub và skeleton cho các đ i t ợng từ xa từ các lớp
cài đặt cho các remote interface.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
85
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3.3. Tạo các lớp có thể truy xuất từ mạng
Tạo một tập tin ch a tất cả các file có liên quan nh các remote interface stub,
các lớp hỗ trợ mà chúng cần thiết phải tải về Client và làm cho tập tin này có thể
truy cập đến thông qua một Web server.
1.3.4. Thực thi ng dụng
Thực thi ng dụng bao gồm việc thực thi rmiregistry server, thực thi server, và
thực thi client.
Tóm lại các công việc phải làm là:
•
•
•
•
•
•
•
•
Tạo giao diện (interface) khai báo các ph ng th c đ ợc gọi từ xa c a đ i
t ợng.
Tạo lớp cài đặt (implement) cho giao diện đã đ ợc khai báo.
Viết ch ng trình Server.
Viết ch ng trình Client.
Dịch các tập tin nguồn theo dạng RMI để tạo ra các lớp t ng ng và stub cho
client, skeleton cho server.
Kh i động dịch vụ registry.
Thực hiện ch ng trình Server.
Thực thi ch ng trình Client.
1.3.4. Ví dụ minh họa
Trong ví dụ này chúng ta định nghĩa một ph ng th c String sayHello() đ ợc gọi
từ xa. Mỗi khi ph ng th c này đ ợc kích hoạt nó sẽ trả về chuỗi "Hello World" cho
Client gọi nó.
D ới đây là các b ớc để xây dựng ng dụng:
B ớc 01: Tạo giao diện (interface) khai báo các ph
xa c a đ i t ợng.
o
ng th c đ ợc gọi từ
Cú pháp tổng quát:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface InterfaceName extends Remote {
ReturnType remoteMethodOne() throws RemoteException;
ReturnType remoteMethodTwo() throws RemoteException;
...
}
o
Định nghĩa remote interface có tên là HelloItf, có ph
gọi từ xa là String sayHello() nh sau:
ng th c đ ợc
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloItf extends Remote {
String sayHello() throws RemoteException;
}
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
86
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
L u ch
- Giáo Trình Lập Trình Truyền Thông
ng trình này vào tập tin HelloItf.java
B ớc 02: Tạo lớp cài đặt (implement) cho giao diện đã đ ợc khai báo:
o
Cú pháp tổng quát:
import java.rmi. server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class RemoteClass extends UnicastRemoteObject implements
InterfaceName {
public RemoteClass() throws RemoteException {
super();
....... // Implement of Method
}
public ReturnType remoteMethodOne() throws RemoteException {
....... // Implement of Method
}
public ReturnType remoteMethodTwo() throws RemoteException {
....... // Definition of Method
}
}
o
Định nghĩa lớp cài đặt có tên là Hello cài đặt cho remote interface
HelloItf
import java.rmi. server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class Hello extends UnicastRemoteObject implements HelloItf {
public Hello() throws RemoteException {
super();
}
public String sayHello() {
return "Hello World !";
}
}
L u ch
ng trình này vào tập tin Hello.java
B ớc 03: Viết ch
o
ng trình Server:
Cú pháp tổng quát:
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
public class ServerName {
public static void main(String args[]) {
if (System.getSecurityManager() == null) { // Cài đặt c chế bảo mật
System.setSecurityManager(new RMISecurityManager());
}
try {
// Tạo các đ i t ợng từ xa
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
87
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
RemoteClass remoteObject = new RemoteClass();
// Đăng ký tên cho các đ i t ợng từ xa
Naming.rebind(“RegistryName", remoteObject);
...
}
catch (Exception e) {
System.out.println(”Error: . . .” + e);
}
}
}
o
Tạo server có tên HelloServer ch a một đ i t ợng từ xa obj thuộc lớp
cài đặt Hello. Đăng ký tên cho đ i t ợng obj là HelloObject
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
public class HelloServer {
public static void main(String args[]) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
Hello obj = new Hello();
Naming.rebind("HelloObject", obj);
System.out.println("HelloObject is registried");
}
catch (Exception e) {
System.out.println("Error: " + e);
}
}
}
L u ch
ng trình này vào tập tin HelloServer.java
B ớc 04: Viết ch
o
ng trình Client:
Cú pháp tổng quát:
import java.rmi.Naming;
import java.rmi.RemoteException;
public class Client {
public static void main(String args[]) {
String remoteObjectURL = "rmi://NameServer/RegistryName”;
Interfacename object = null;
try {
object = (InterfaceName)Naming.lookup(remoteObjectURL);
object.remoteMethodOne();
...
}
catch (Exception e) {
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
88
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
System.out.println(" Error: ”+ e);
}
}
}
o
Tạo client có tên là HelloClient, tìm đ i t ợng HelloObject trên
rmiregistry chẳng hạn tại địa chỉ 172.18.211.160. Gọi ph ng th c
sayHello() và in kết quả trả về ra màn hình.
import java.rmi.Naming;
import java.rmi.RemoteException;
public class HelloClient {
public static void main(String args[]) {
String helloURL = "rmi://172.18.211.160/HelloObject";
HelloItf object = null;
try {
object = (HelloItf)Naming.lookup( helloURL);
String message = object.sayHello();
System.out.println(message);
}
catch (Exception e) {
System.out.println("Client Error :" + e);
}
}
}
L u ch
ng trình vào tập tin HelloClient.java
B ớc 05: Dịch các tập tin nguồn theo dạng RMI để tạo ra các lớp t
ng và stub cho client, skeleton cho server:
o
ng
Cú pháp tổng quát:
javac InterfaceName.java RemoteClass.java Server.java Client.java
( Tạo ra các lớp InterfaceName.class RemoteClass.class Server.class
Client.class)
rmic RemoteClass
( Tạo ra các lớp cho Skeleton và Stub: RemoteClass_Skel.class
RemoteClass_Stub.class)
o
Biên dịch các lớp trong Hello:
javac Hello.java HelloItf.java HelloServer.java HelloClient.java
rmic Hello.class
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
89
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
B ớc 06: Khởi động dịch vụ rmiregistry
o
Cú pháp tổng quát:
start rmiregistry [port]
Cổng mặc định là 1099.
o
Khới động dịch vụ rmiregistry trên cổng mặc định nh sau:
Khi đó rmiregistry server sẽ chạy trên một cửa sổ mới, giữ nguyên cửa sổ này,
không đóng nó lại.
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
90
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
B ớc 07: Thực hiện ch
o
- Giáo Trình Lập Trình Truyền Thông
ng trình Server
Cú pháp tổng quát:
java -Djava.security.policy =UrlOfPolicyFile ServerName
Trong đó UrlOfPolicyFile là địa chỉ theo dạng URL c a tập tin mô tả chính
sách về bảo mật mã nguồn c a Server (policy file). Nó qui định "ai" (ch ng
trình, máy tính, quá trình trên) sẽ có quyền download các tập tin c a nó trong
đó có stub. Để đ n giản trong phần này ta cho phép tất cả mọi ng i đều có
quyền download các tập tin c a Server. Khi triển khai các ng dụng thật sự
ta phải có các chính sách bảo mật nghiêm ngặt h n (Tham khảo tài liệu về
Security c a Java). File policy có dạng nh sau:
grant {
// Allow everything for now
permission java.security.AllPermission;
};
L u nội dung trên vào tập tin có tên policy.java
o
Thực thi HelloServer với địa tập tin plolicy nằm
D:\progs\policy.java
B ớc 08: Thực thi ch
th
mục
ng trình Client:
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
91
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
o
- Giáo Trình Lập Trình Truyền Thông
Cú pháp tổng quát
java ClientName
o
Thực thi HelloClient với địa chỉ c a rmiregistry đ a vào trong tham s
Để thực thi đ ợc ch ng trình HelloClient cần có hai class nằm cùng th mục với
nó là HelloItf.class và Hello_Stub.class.
1.4. Bài tập áp dụng
•
Mục đích:
Xây dựng ng dụng phân tán theo c chế RMI.
•
Yêu cầu
Sinh viên thực hiện các bài tập sau:
o
Bài 1 : Xây dựng một ng dụng phục vụ việc bán vé máy bay cho các
đại lý phân tán các tỉnh thành khác nhau. ng dụng này có các lớp
sau:
Lớp chuyến bay: Đại diện cho một chuyến bay
Có các thuộc tính: S hiệu chuyến bay, Ngày gi bay,
N i đi, N i đến, Th i gian bay, Tổng s ghế, S l ợng
ghế đã bán, S l ợng ghế còn tr ng.
Các ph ng th c trên một chuyến bay: ph ng th c xem
thông tin về chuyến bay, ph ng th c mua vé, ph ng
th c trả vé. Để phục vụ cho nhiều đại lý các ph ng th c
trên thuộc loại đuợc gọi từ xa.
Lớp Server, tạo ra nhiều chuyến bay và duy trì nó để cho phép
các đại lý thực hiện các giao dịch trên chuyến bay cụ thể.
Client là ch ng trình cho phép mỗi đại lý đ ợc quyền xem
thông tin về chuyến bay, mua vé, trả vé theo yêu cầu.
Mục lục
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
92
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
CH
- Giáo Trình Lập Trình Truyền Thông
NG 1..........................................................................................................................1
Tổng quan về lập trình truyền thông ....................................................................................1
1.1. C chế giao tiếp liên quá trình là gì ?.....................................................................2
1.2. Phân loại c chế giao tiếp liên quá trình ................................................................2
1.3. Mô hình tham khảo OSI .........................................................................................3
1.4. Mạng TCP/IP..........................................................................................................6
1.5. Dịch vụ mạng .........................................................................................................7
1.6. Mô hình Client – Server .........................................................................................7
1.6.1. Giới thiệu.........................................................................................................7
1.6.2. Ví dụ về dịch vụ Web......................................................................................8
1.6.3. Các chế độ giao tiếp ........................................................................................9
1.6.3.1. Chế độ nghẽn :..........................................................................................9
1.6.3.2. Chế độ không nghẽn:................................................................................9
1.7. Các kiểu kiến trúc ch
ng trình .............................................................................9
1.7.1. Kiến trúc đ n tầng (Single-tier Architecture) ...............................................10
1.7.2. Kiến trúc hai tầng (Two - Tier Architecture) ................................................10
1.7.2.1. Loại Fat Client........................................................................................11
1.7.2.2. Loại Fat Server .......................................................................................12
1.7.3. Kiến trúc đa tầng (N-Tier Architecture)........................................................12
1.8. Bài tập...................................................................................................................13
1.8.1. Bài tập bắt buộc.............................................................................................13
1.8.2. Bài tập gợi ý ..................................................................................................13
Tìm đọc và viết một báo cáo không quá 10 trang về giao th c POP3...............................13
CH
NG 2........................................................................................................................14
S l ợc về ngôn ngữ Java ..................................................................................................14
1.1. Giới thiệu về ngôn ngữ Java.................................................................................15
1.1.1. Lịch sử phát triển...........................................................................................15
1.1.2. Khả năng c a ngôn ngữ Java.........................................................................15
1.1.2. Những đặc điểm c a ngôn ngữ Java .............................................................15
1.1.3. Máy ảo Java (JMV - Java Virtual Machine) .................................................15
1.1.4. Hai kiểu ng dụng d ới ngôn ngữ java.........................................................16
1.1.5. Bộ phát triển ng dụng Java (JDK- Java Development Kit) ........................16
1.1.6. Kiểu dữ liệu c bản d ới Java.......................................................................16
1.1.7. Các phép toán c bản ....................................................................................17
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
93
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.1.8. Qui cách đặt tên trong Java ...........................................................................17
1.2. Ch
ng trình ng dụng kiểu Application ............................................................18
1.2.1. Ch
ng trình HelloWorld .............................................................................19
1.2.3. Biên soạn ch
ng trình bằng phần mềm Notepad c a Ms Windows ...........19
1.2.4. Cài đặt bộ phát triển ng dụng JDK..............................................................20
1.2.5. Biên dịch và thực thi ch
ng trình................................................................20
1.2.6. Một s ví dụ...................................................................................................21
1.2.6.1. Hiển thị thông tin ra màn hành...............................................................21
1.2.6.2. Đọc ký tự từ bàn phím............................................................................21
1.3. Các cấu trúc điều khiển trong Java.......................................................................23
1.3.1. Lệnh if – else .................................................................................................23
1.3.2. Phép toán ? ....................................................................................................24
1.3.3. Lệnh switch ...................................................................................................25
1.3.4. Lệnh while.....................................................................................................26
1.3.5. Lệnh do - while..............................................................................................27
1.3.6. Lệnh for .........................................................................................................27
1.3.7. Lệnh break.....................................................................................................28
1.3.8. Lệnh continue ................................................................................................29
1.3.9. Một s vấn đề khác........................................................................................30
1.3.9.1. Đọc đ i s c a ch
ng trình ..................................................................30
1.3.9.2. Đổi chuỗi thành s ..................................................................................31
1.4. Ngoại lệ (EXCEPTION) ......................................................................................31
1.5. Một s vấn đề liên quan đến lớp trong Java.........................................................33
1.5.1. Định nghĩa lớp mới........................................................................................33
1.5.2. Phạm vi nhìn thấy c a một lớp......................................................................34
1.5.3. Tính thừa kế...................................................................................................35
1.6. Vào / Ra với Stream ............................................................................................36
1.6.1. Lớp java.io.InputStream................................................................................37
1.6.2. Lớp java.io.OutputStream .............................................................................39
1.6.3. Nhập chuỗi từ một InputStream ....................................................................40
1.6.4. Xuất chuỗi ra một OutputStream ..................................................................41
1.7. Luồng (Thread).....................................................................................................42
1.7.1. Các m c cài đặt luồng ...................................................................................43
1.7.1.1. Tiếp cận luồng
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
m c ng
i dùng: ........................................................44
94
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
1.7.1.2. Tiếp cận luồng
- Giáo Trình Lập Trình Truyền Thông
m c hạt nhân hệ điều hành.........................................44
1.7.2. Luồng trong java ...........................................................................................44
1.7.2.1 Độ u tiên c a luồng ...............................................................................47
1.7.3. Đồng bộ hóa giữa các luồng..........................................................................49
1.8. Bài tập áp dụng.....................................................................................................49
Ch đề 1: C bản về Java ........................................................................................49
Ch đề 2: Thiết kế lớp trong Java ...........................................................................49
Ch đề 3: Thread .....................................................................................................50
CH
NG 3........................................................................................................................51
ng dẫn (Pipe) ...................................................................................................................51
1.1. Giới thiệu về ng dẫn ...........................................................................................52
1.2. ng dẫn trong Java...............................................................................................52
1.2.1. Giới thiệu.......................................................................................................52
1.2.2. Các cách tạo ng dẫn.....................................................................................53
1.3. Dịch vụ phản hồi thông tin (Echo Service) ..........................................................53
1.4. Giả lập dịch vụ phản hồi thông tin bằng Pipe ......................................................54
1.4.1. Lớp PipedEchoServer....................................................................................54
1.4.2. Lớp PipedEchoClient ....................................................................................55
1.4.3. Lớp PipedEcho ..............................................................................................55
1.4.5. Biên dịch và thực thi ch
CH
ng trình................................................................56
NG 4........................................................................................................................57
Socket .................................................................................................................................57
1.1. Giới thiệu về socket..............................................................................................58
1.1.1. Giới thiệu.......................................................................................................58
1.1.2. S hiệu cổng (Port Number) c a socket........................................................58
1.1.3. Các chế độ giao tiếp ......................................................................................60
1.2. Xây dựng ng dụng Client-Server với Socket .....................................................61
1.2.1. Mô hình Client-Server sử dụng Socket
chế độ có n i kết (TCP) ..............61
1.2.2. Mô hình Client-Server sử dụng Socket
chế độ không n i kết (UDP)........63
1.3. Socket d ới ngôn ngữ Java ..................................................................................64
1.3.1. Xây dựng ch
ng trình Client
chế độ có n i kết .......................................65
1.3.1.1. Lớp java.net.Socket................................................................................65
1.3.1.2. Ch
ng trình TCPEchoClient ................................................................66
1.3.2. Xây dựng ch
ng trình Server
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
chế độ có n i kết ......................................67
95
Khoa Công Nghệ Thông Tin - Đại Học Cần Th
- Giáo Trình Lập Trình Truyền Thông
1.3.2.1. Lớp java.net.ServerSocket .....................................................................67
1.3.2.2. Xây dựng ch
1.3.2.3. Ch
ng trình Server phục vụ tuần tự .....................................67
ng trình STCPEchoServer .............................................................68
1.3.2.4. Server phục vụ song song.......................................................................69
1.3.2.5. Ch
ng trình PTCPEchoServer .............................................................70
1.3.3. Xây dựng ch
ng trình Client - Server
chế độ không n i kết ...................71
1.3.3.1. Lớp DatagramPacket ..............................................................................72
1.3.3.2. Lớp DatagramSocket..............................................................................73
1.3.3.3. Ch
ng trình UDPEchoServer...............................................................74
1.3.3.4. Ch
ng trình UDPEchoClient ...............................................................75
1.4. Bài tập áp dụng.....................................................................................................77
CH
NG 5........................................................................................................................79
RPC và RMI .......................................................................................................................79
1.1. L i gọi th tục xa (RPC- Remote Procedure Call) ..............................................80
1.1.1. Giới thiệu.......................................................................................................80
1.1.2. Kiến trúc c a ch
tục xa
80
ng trình Client-Server cài đặt theo c chế l i gọi th
Hình 5.1 Kiến trúc ch
ng trình kiểu RPC........................................................................80
1.2. Kích hoạt ph
ng th c xa (RMI- Remote Method Invocation ) .........................81
1.2.1. Giới thiệu.......................................................................................................81
1.2.2. Kiến trúc c a ch
ng trình Client-Server theo c chế RMI .........................82
1.2.3. Các c chế liên quan trong một ng dụng đ i t ợng phân tán .....................83
1.2.4. C chế vận hành c a c a một ng dụng Client-Server theo kiểu RMI ........84
1.2.5. Các lớp hỗ trợ ch
ng trình theo kiểu Client-Server trong Java ..................85
1.3. Xây dựng một ng dụng phân tán với RMI .........................................................85
1.3.1. Thiết kế và cài đặt các thành phần c a ng dụng..........................................85
1.3.2. Biên dịch các tập tin nguồn và tạo Stubs và Skeleton...................................85
1.3.3. Tạo các lớp có thể truy xuất từ mạng ............................................................86
1.3.4. Thực thi ng dụng .........................................................................................86
1.3.4. Ví dụ minh họa ..............................................................................................86
1.4. Bài tập áp dụng.....................................................................................................92
Mục lục...............................................................................................................................92
Biên Soạn: Ngô Bá Hùng - Nguyễn Công Huy
96