View
154
Download
0
Category
Preview:
Citation preview
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Đại Học Quốc Gia Tp.HCM
Trường Khoa Học Tự Nhiên Tp. HCM
Khoa Điện Tử Viễn Thông
Đề tài: Multicast Hình Ảnh
Nhóm:
Ngô Đức Phú 0720143
Nguyễn Vũ Linh 0720137
Hoàng Anh Khoa 0720113
Lâm Thị Bé Vàng 0720138
Giáo Viên hướng dẫn:
Ths. Lê Đức Trị
1
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
MỤC LỤC
1. GIỚI THIỆU...........................................................................................................21.1 Giới thiệu.........................................................................................................21.2 Multicast là gì?.................................................................................................21.3 Multicast Scoping............................................................................................31.4 Multicast Group Management.........................................................................51.5 Multicast Distribution Trees............................................................................71.6 Các vấn đề với Unicast....................................................................................81.7 Địa chỉ multicast..............................................................................................9
1.8 Hình ảnh ……………………………………………………………………102. MỤC TIÊU...........................................................................................................103. ĐÁNH GIÁ...........................................................................................................113.1 Cơ chế hoạt động:..............................................................................................11
3.2 Phần Server....................................................................................................153.2.1 Các chức năng:.......................................................................................153.2.2 Phân tích chức năng:...............................................................................163.2.3 Sơ đồ hoạt động :....................................................................................16
3.3 Phần Client.....................................................................................................173.3.1 Các chức năng:.......................................................................................183.3.2 Phân tích chức năng:...............................................................................183.3.3 Sơ đồ hoạt động:.....................................................................................19
4. CHƯƠNG TRÌNH................................................................................................204.1 Phần Server TCP............................................................................................21
4.1.1 Đợi client kết nối vào.............................................................................214.1.2 Gửi lệnh tạo file và nghe client trả lời....................................................214.1.3 Gửi dữ liệu..............................................................................................224.1.4 Gửi lệnh thông báo đã gửi xong và nghe client trả lời...........................224.1.5 Gửi lại những gói dữ liệu đã mất............................................................22
4.2 Phần Client TCP............................................................................................234.2.1 Kết nối server và gửi thông tin lên server...............................................234.2.2 Nhận lệnh tạo file và trả lời server.........................................................234.2.3 Nhận dữ liệu phân tích và ghi vào file....................................................234.2.4 Nhận thông báo từ server và trả lời server..............................................244.2.5 Nhận dữ liệu mất....................................................................................24
4.3 Phần kết nối UDP...........................................................................................255.KẾT QUẢ
5.1 Kết quả................................................................................................................315.2 Hướng phát triển............................................................................................32
6. TÀI LIỆU THAM KHẢO....................................................................................337. GIAO DIỆN VÀ HƯỚNG DẪN SỬ DỤNG CHƯƠNG TRÌNH:......................33
7.1 Server.............................................................................................................347.2 Client..............................................................................................................367.3 Server............................................................................................................36 7.4 Client..............................................................................................................36
2
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
1. GIỚI THIỆU
1.1 Giới thiệu
Ngày nay mạng máy tính đã phát triển với tốc độ rất nhanh chóng và
việc trao đổi thông tin trên mạng là điều tất yếu. Cùng với tốc độ phát triển
là sự ra đời của nhiều công nghệ mạng, các công nghệ này sử dụng các giao
thức kết nối khác nhau (TCP, UDP: tuỳ vào mục đích sử dụng), làm cho
việc trao đổi dữ liệu trên mạng được nhanh chóng, chính xác và hiệu quả.
Multicast ra đời cũng nhằm phục vụ cho một trong những mục đích trên.
Để trao đổi dữ liệu Multicast sử dụng giao thức UDP. Điểm mạnh của
multicast là có thể truyền tải dữ liệu với tốc độ cao và dữ liệu chỉ gửi đi một
lần.
Có 2 loại ứng dụng multicast chính:
- Ứng dụng không cần khôi phục dữ liệu mất: Ví dụ như những ứng
dụng truyền tải hình ảnh và âm thanh, có thể méo dạng ở mức cho
phép.
- Ứng dụng cần khôi phục dữ liệu mất: Ví dụ như ứng dụng Ghost của
Synmantec hoặc Multicast truyền nhận của chúng ta. Trong những
ứng dụng này cần đảm bảo tính toàn vẹn của dữ liệu, nếu chỉ cần mất
một bit thì dữ liệu của chúng ta sẽ bị hỏng nên cần có cơ chế khôi
phục dữ liệu. Do UDP thì không có cơ chế tự khôi phục dữ liệu nên
phần mềm phải đảm nhiệm vai trò này.
1.2 Multicast là gì?
Multicast là công nghệ dùng để truyền tải dữ liệu từ một nguồn đến
một nhóm máy tính muốn nhận dữ liệu đó (một tiến trình gửi và nhiều tiến
trình nhận). Để nhận dữ liệu thì các máy thành viên của nhóm cần kết nối
đến một địa chỉ Multicast và dữ liệu nguồn sẽ gửi dữ liệu lên đó.
3
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Từ một khía cạnh nào đó thì multicast giống như hệ thống radio hay
TV. Nếu kênh được phát đi chúng ta có thể đồng thời nghe hoặc xem cùng
một kênh giống như những người khác.
Ví dụ mô hình multicast:
Ví dụ multicast và unicast:
4
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Ba kỹ thuật trong việc quản lí sự phân phát multicast trên mạng là:
scoping, group management, và distribution trees.
1.3 Multicast Scoping
IP Multicast sử dụng một tham số Time To Live (TTL) trong header
từng gói dữ liệu của các ứng dụng IP Multicast. Các router căn cứ vào giá
trị TTL của gói dữ liệu này để quyết định xem gói dữ liệu này có được
phép đi qua hay không. Khi chúng ta đặt giá trị TTL trong một ứng dụng IP
Multicast là n thì những gói dữ liệu này không thể đi quá n router. Ví dụ,
nếu chúng ta đặt Site Server's Active Channel Multicaster có giá trị TTL
tới 16, để đảm bảo rằng Site Server's Active Channel Multicaster không
vượt qua quá 16 router. Đúng như trong unicast, mỗi thời gian một
multicast router chuyển một gói multicast, router giảm bớt giá trị TTL của
gói dữ liệu đi một đơn vị. Nếu giá trị TTL =0 thì router sẽ huỷ gói dữ liệu
này. Trên mỗi interface (cổng giao tiếp mạng) của router chúng ta có thể
quy định giá trị TTL mặc định. Ví dụ, nếu chúng ta đặt ngưỡng TTL là 10
5
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
trên một interface thì chỉ những gói dữ liệu với giá trị TTL lớn hơn 10 mới
có thể đi qua được interface đó.
Cơ bản multicast scoping có hai khuyết điểm:
- Việc xác định một giá trị TTL thích hợp cho một ứng dụng
multicast là khó khăn
- Nếu người nào đó đặt ngưỡng TTL theo thói quen trên các
interface của router thì phạm vi hoạt đông của những ứng dụng
multicast có thể không đoán trước được.
Để khắc phục được những giới hạn này, the Internet Engineering
Task Force (IETF) đưa ra Administratively Scoped IP Multicast như là một
chuẩn Internet RFC 2365 in July 1998. IETF có những địa chỉ IP multicast
được chỉ định trong khoảng 239.0.0.0 và 239.255.255.255 như là những địa
chỉ administratively scoped cho việc sử dụng mạng cục bộ. Chúng ta có thể
cấu hình các router hỗ trợ các địa chỉ administratively scoped trên các
đường bên trong mạng của chúng ta để hạn chế vùng multicast riêng của
chúng ta. Chúng ta cũng có thể định nghĩa nhiều vùng multicast được cô
lập trong mạng của chúng ta như thế dữ liệu multicast sẽ chỉ di chuyển
trong vùng được chỉ định.
1.4 Multicast Group Management
6
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Một multicast network chỉ chuyển dữ liệu multicast cho các mạng
con có các máy nhận nằm trong một nhóm multicast tương ứng trong một
vùng multicast. Sự chuyển dữ liệu có chọn lọc này là sự khác biệt lớn nhất
giữa multicast và broadcast (broadcast gửi dữ liệu tới tất các mạng con).
Để chuyển dữ liệu multicast tới các máy nhận trong một vùng
multicast, router cần thông tin về sự tham gia của các thành viên trên các
mạng con cục bộ của chúng. Một router trên mỗi mạng con sẽ gửi định kỳ
các thông điệp (message) tới tất cả các máy tính trên mạng con cục bộ. Các
máy tính trên mạng con cục bộ trả lời các messages này của router. Bằng
cách này router sẽ xây dựng cho mình một bảng thông kê các thành viên
của nhóm mà chúng có liên quan. Khi các thành viên của nhóm khác nhận
một thông báo máy tính thành viên thì các thành viên của nhóm hoãn các
báo cáo tham gia của chúng và đợi một biến chu kỳ thời gian. Thời gian đợi
này làm giảm lưu thông báo cáo tham gia và thời gian xử lí của router.
Miễn là một router biết rằng một nhóm các thành viên trên mạng con cục
bộ, router chuyển dữ liệu multicast tới mạng con đó và các thành viên của
nhóm khác sẽ nhận dữ liệu multicast. Khi một thành viên mới muốn join
một nhóm, thành viên không cần đợi câu hỏi tiếp theo từ router. Thay vào
đó, thành viên mới ngay lập tức gửi một báo cáo tham gia như là sự trả lời
tới câu hỏi tham gia. Khi router nhận báo cáo này, ngay lập tức nó chuyển
dữ liệu multicast tới mạng con mà trên đó thành viên mới hiện diện nếu
thành viên mới là thành viên đầu tiên của nhóm mạng con multicast đó.
(Hình bên)
7
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
IETF đang làm việc trên IGMPv3 để cải tiến IGMPv2. IGMPv3 sẽ
bao gồm các đặt tính mới. Một trong các đặc tính mới là xác nhận được
máy tính nào trong nhóm sẽ nhận dữ liệu từ nguồn.
1.5 Multicast Distribution Trees
Sử dụng thông tin thành viên IGMP của router, một multicast
routing protocol xây dựng một distribution tree để chuyển dữ liệu multicast
từ một nguồn đến nhóm multicast. Có hai loại distribution tree: source-
based và shared.
Khi router kết nối đến nguồn để nhận gói dữ liệu multicast đầu tiên,
router sẽ chuyển gói dữ liệu đến các đỉnh của mạng để tìm máy nhận. Sau
khi kiểm tra IGMP nếu một router trên mạng không tìm thấy máy nhận nào,
router đó sẽ gửi một thông điệp prune (prune message) đến router cha gần
nó nhất trên đường đến nguồn. Prune message sẽ loại router đó. Một
distribution tree chỉ chứa những router có máy nhận trên nhánh. Giao thức
này sẽ gửi tiến trình broadcast and prune một cách định kỳ trong lúc
multicast cập nhật distribution tree và phản hồi đến các thành viên.
Một multicast routing protocol sử dụng tiến trình broadcast-and-
prune để thiết lập một source-based tree là một giao thức broadcast-and-
prune. Bởi vì giao thức broadcast-and-prune làm cho broadcast tuần hoàn,
những giao thức này chỉ thích hợp cho việc sử dụng trong những môi
trường LAN có nhiều băng thông và nhiều máy nhận. Sự bất lợi khác của
việc sử dụng giao thức broadcast-and-prune là nếu hai nguồn khác nhau gửi
dữ liệu cho cùng một nhóm multicast thì giao thức đó phải tạo ra một
source-based distribution tree cho mỗi nguồn
8
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Trái ngược với source-based tree, shared-tree có thể hỗ trợ nhiều
nguồn dữ liệu multicast tới cùng một nhóm multicast sử dụng cùng
distribution tree. Shared tree thích hợp cho môi trường có máy nhận phân
tán rải rát trên một băng thông nhỏ trong môi trường WAN. Một giao thức
shared-tree hoặc tự động chọn hoặc để cho người quản trị mạng định nghĩa
gốc của một shared tree trong một mạng. Gốc là một router, được biết như
là một điểm trung tâm (core) hoặc điểm gặp nhau (rendezvous point). Các
gốc thường là trung tâm của các nhóm multicast. Khi một router của nguồn
nhận dữ liệu multicast thì router sẽ chuyển dữ liệu tới điểm trung tâm của
nhóm multicast. Điểm trung tâm sẽ chuyển dữ liệu tới tất cả các máy nhận
trong nhóm. Shared tree không thiết lập việc sử dụng broadcast-and-prune
để tìm nhóm thành viên nhưng phụ thuộc vào tất cả các thành viên kết nối
vào cây. Khi một router tìm thấy một nhóm thành viên thông qua viêc kiểm
tra IGMP, router sẽ gửi yêu cầu kết nối đến điểm trung tâm. Điểm trung
tâm hoặc router trung gian sẽ trả lời yêu cầu với một kết nối ack và gửi ack
đến router yêu cầu.
1.6 Các vấn đề với Unicast
9
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Unicast không giống như Multicast. Khi ta gửi một gói dữ liệu
(packet) nếu chỉ có một tiến trình gửi và một tiến trình nhận thì đây chính là
unicast. Có hai giao thức truyền dữ liệu chính trên mạng là: TCP và UDP.
TCP chính là unicast. UDP có thể là unicast trong trường hợp chúng ta gửi
những packet UDP và chỉ có một tiến trình nhận duy nhất. Trường hợp
ngược lại nó có thể là broadcast hoặc multicast.
Unicast thống lĩnh trên mạng internet trong nhiều năm cho đến năm
1993 khi mà Multicast ra đời nó đã làm thay đổi vai trò truyền dữ liệu trên
mạng internet bởi những lợi ích mà nó đem lại. Những trang web mạnh ra
đời, mọi người có thể nghe và nhìn thấy nhau.
Với các công nghệ mạng ngày nay thì chúng ta có đủ khả năng tài
chính để chi trả cho những kết nối unicast đến tất cả những ai muốn truy
cập vào trang web của chúng ta. Tuy nhiên, nếu các ứng dụng web của
chúng ta tương trợ các dịch vụ âm thanh và hình ảnh thì chúng ta cần một
băng thông khổng lồ cho các ứng dụng này. Trước khi multicast ra đời thì
có 2 giải pháp: thiết lập một kết nối unicast riêng biệt đối với mỗi người
nhận hoặc sử dụng broadcast.
Giải pháp đầu tiên không thuận lợi vì mỗi kết nối đơn gửi dữ liệu âm
thanh/hình ảnh đều cần một băng thông lớn mà chúng ta có thể có hàng
trăm hoặc thậm chí hàng ngàn kết nối như vậy thì cả hệ thống mạng của
chúng ta có thể bị sụp đổ. Ví dụ Unicast video/audio transmission:
Broadcast dường như là một giải pháp nhưng nó chưa là giải pháp
tốt. Nếu chúng ta muốn tất cả các máy tính trong một mạng LAN nhận dữ
liệu đồng thời từ một máy gửi thì chúng ta có thể sử dụng broadcast. Những
10
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
dữ liệu sẽ được gửi đồng thời một lần đến tất cả các máy tính nhận theo địa
chỉ broadcast của mạng tương ứng. Vấn đề khó khăn chỉ xảy ra khi máy
tính gửi và máy tính nhận ở hai mạng LAN khác nhau, bởi vì các trang thiết
bị mạng lớp thứ 3 (router) không cho phép các gói dữ liệu có địa chỉ máy
đích là broadcast đi qua.
Giải pháp duy nhất còn lại là multicast. Thông qua multicast chúng
ta gửi dữ liệu đến một địa chỉ đặc biệt (giống như tần số của radio/video).
Tất cả các máy tính muốn nhận dữ liệu này đều phải kết nối đến địa chỉ đặc
biệt trên. Từ một khía cạnh nào đó thì multicast giống như broadcast. Điều
khác biệt cơ bản giữa chúng là dữ liệu multicast truyền được trên hệ thống
mạng còn broadcast chỉ hoạt động trong môi trường một mạng LAN duy
nhất. Ví dụ Multicast video/audio transmission :
1.7 Địa chỉ multicast
Địa chỉ Multicast là địa chỉ thuộc lớp D với các giá trị nằm trong
khoảng từ 224.0.0.0 239.255.255.255
11
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Mỗi IP datagram có địa chỉ đích bắt đầu bằng 4 bits “1110” là một
IP Multicast datagram. 28 bits còn lại dùng để xác định nhóm (group) mà
datagram được gửi tới. Tương tự như việc chúng ta điều chỉnh tần số để
nghe một chương trình nào đó được phát ra trên tần số đó, chúng ta có thể
điều chỉnh để nhận được những packet gửi lên một nhóm multicast đã xác
định. Điều đó có ý nghĩa là các máy tính đã được kết nối với nhau vào một
nhóm trên interface đã được xác định.
1.8 Hình ảnh là gì?
Hình ảnh là tập hợp của vô số điểm ảnh nhỏ tạo thành hình ảnh. Độ sắc
nét của hình ành p thuộc số ượng điểm ảnh mà mắt ta (thiết bị) phân
giải cho pixel.
Do vậy, việc truyền hình ảnh có thể cho phép méo dạng cho phép, các
điểm ảnh có thể mất đi nhưng nhờ các thuật toán sửa lỗi sẽ phục hồi lại
điểm anh 2 lân cạnh mà không mất tính khác biệt với ảnh gốc. Giao thức
UDP sẽ là giao thức lượt chọn hàng đầu trong truyền dẫn hình ảnh.
Trong một số truyền đặc biệt thì người ta dùng TCP truyền hình ảnh.
2. MỤC ĐÍCH
Áp dụng các tính năng của công nghệ Multicast để xây dựng chương
trình Multicast hình ảnh dùng để truyền dữ liệu từ một máy tính (server) đến
đồng thời nhiều máy tính khác (client) trên một mạng LAN.
3. PHÂN TÍCH
3.1 Cơ chế:
12
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Chương trình hoạt động theo mô hình client/server: Server chịu trách
nhiệm đọc và gửi dữ liệu, Client chịu trách nhiệm nhận và ghi dữ liệu.
Việc trao đổi dữ liệu trên mạng cần tạo ra các kết nối. Có hai giao thức
tạo kết nối trên mạng: TCP và UDP
- TCP là kết nối tin cậy, dữ liệu được gửi đến máy đích một cách
tuần tự và trên một mạch ảo duy nhất. TCP có cơ chế tự kiểm tra
lỗi và khôi phục dữ liệu trong trường hợp dữ liệu bị mất hoặc lỗi.
- UDP là kết nối không tin cậy, dữ liệu đi từ nguồn đến đích theo
nhiều đường khác nhau và không theo thứ tự. Khi dữ liệu được gửi
đi máy tính nguồn sẽ không quan tâm và không biết được dữ liệu
có đến đích nguyên vẹn và theo đúng thứ tự hay không. UDP
không có cơ chế tự kiểm tra lỗi và khôi phục dữ liệu. Đây là trở
ngại lớn nhất cho những ứng dụng được xây dựng trên nền tảng
kết nối UDP, bởi vì sự mất mát và lỗi của dữ liệu trong quá trình
truyền tải là không tránh khỏi. Để giải quyết vấn đề này chúng ta
cần phải tự xây dựng cho mình một cơ chế kiểm tra lỗi và khôi
phục dữ liệu.
Trong ứng dụng Muticast hình ảnh, chúng ta sử dụng cả 1 loại kết nối
UDP, trong một trường hợp nâng cao hiệu quả và tính toàn vẹn của dữ liệu
TCP là sự lưạ trong quá trình gửi và nhận
TCP được sử dụng trong những kết nối đòi hỏi sự chính xác, như việc
trao đổi thông tin giữa client và server hoặc việc kết nối từ client đến server.
Dung lượng thông tin trao đổi trong những kết nối TCP này rất nhỏ nên không
làm ảnh hưởng nhiều đến tốc độ của chương trình mà còn làm tăng hiệu quả
của nó. Điều đó có nghĩa là kết nối TCP được sử dụng để gửi các thông báo
giữa client và server.
UDP được sử dụng để gửi dữ liệu từ server đến client. Quá trình này
chiếm nhiều thời gian và băng thông nhất, đồng thời sự mất mát và lỗi của dữ
liệu xảy ra chủ yếu trong giai đoạn này.
Dữ liệu UDP gửi từ nguồn đến đích đi theo nhiều đường khác nhau.Vấn
đề đặt ra là làm sao máy đích biết được gói dữ liệu nào là trước dữ liệu nào là
13
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
sau mà sắp xếp cho đúng thứ tự và làm sao biết được gói dữ liệu đó có đầy đủ
hay không.
Như chúng ta đã biết độ lớn tối đa của một gói dữ liệu trao đổi trên
mạng hiện nay là 64KB, nhưng file mà ta cần truyền có độ lớn gấp nhiều lần so
với một gói dữ liệu. Như vậy thì chúng ta cần chia file này ra thành nhiều phần
có độ lớn thích hợp để gửi qua mạng. Đồng thời để cho máy đích kiểm tra được
sự mất mát và lỗi mà sắp xếp dữ liệu theo đúng thứ tự, chúng ta cần định nghĩa
ra một cấu trúc dữ liệu mới như sau:
Packet gồm 3 phần:
- Phần header gồm có: COMMAND, INDEX và LENGTH
- Phần nội dung: DATA
- Phần kiểm tra lỗi: CRC
Trong đó:
COMMAND có độ lớn 1byte: là thông số của packet. Nếu COMMAND
= 1 thì packet này thông báo cho client biết đây là gói dữ liệu cuối cùng. Nếu
COMMAND = 2 thì DATA là dữ liệu của file copy.
INDEX có độ lớn 4bytes (int): là chỉ số của packet. Mỗi packet có một
chỉ số riêng. Số này cũng chính là số thứ tự của gói dữ liệu khi gửi. Các máy
đích sẽ sử dụng chỉ số này để sắp xếp các gói dữ liệu vào vị trí tương ứng trong
file.
LENGTH có độ lớn 4bytes (int): là chiều dài của toàn packet.
DATA là dữ liệu được lấy từ file (mảng byte).
CRC có độ lớn 8 bytes: là dữ liệu dùng để client kiểm tra tính toàn vẹn
của gói dữ liệu. Nghĩa là client sẽ so sánh số CRC của packet mà server gửi với
CRC mà client tính được dựa trên các giá trị trong gói dữ liệu mà nó nhận
được. Nếu hai số này bằng nhau thì packet này toàn vẹn, ngược lại gói dữ liệu
COMMAND INDEX LENGTH
DATA
CRC
14
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
lỗi. Để tính số CRC ta dùng đối tượng CRC32 trong Java. Đối tượng này sẽ
update lần lươt các giá trị COMMAND, INDEX, LENGTH, DATA vào đối
tượng CRC32 và nó sẽ lấy ra một số có chiều dài 8bytes (long) số này chính là
CRC. Số này sẽ được đóng gói vào phần cuối của packet. Client sẽ dựa vào số
CRC này để kiểm tra packet có đầy đủ không.
Ví dụ:
CRC32 crc = new CRC32();
crc.update(COMMAND);
crc.update(INDEX);
crc.update(LENGTH);
crc.update(DATA);
long CRC = crc.getValue(); // Số CRC
Để kiểm tra thứ tự của gói dữ liệu client sẽ dựa vào số INDEX. Nếu
INDEX nhỏ thì packet này là trước (INDEX là vị trí của DATA trong file).
Dùng đối tượng RandomAccessFile của Java để lấy dữ liệu (DATA) từ
file và ghi vào file. Vì đối tượng này cho phép ta lấy từng mảng byte từ một vị
trí bất kỳ nào đó của file và cho phép ghi vào một vị trí xác định nào đó trong
file. Khi lấy một DATA nào trong file thì ta đặt cho DATA đó một số INDEX.
Cách lấy dữ liệu từ file:
// tạo ra đối tượng RandomAccessFile và truyền vào file cần lấy hay
ghi //dữ liệu
RandomAccessFile raFile = new RandomAccessFile(file, “r”);
while(byteRead>0){
raFile.seek(INDEX); // hàm seek dùng để di chuyển con trỏ
đến //một vị trí INDEX trong file. Vị trí này chính là số INDEX của
DATA
INDEX++; // tăng INDEX lên một đơn vị
byteRead = raFile.read(buffer, 0, byteRead); // dùng để lấy
DATA từ file.
}
15
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Cách ghi dữ liệu vào file:
this.raFile.seek(INDEX); // trước khi ghi dữ liệu raFile sẽ di chuyển
con trỏ đến INDEX. INDEX lấy từ packet vừa nhận
this.raFile.write(data, 0, length);// hàm này dùng để ghi dữ liệu vừa
nhận được vào file tại vị trí INDEX.
Chúng ta đã xây dựng được một cấu trúc dữ liệu. Vậy làm cách nào
để chuyển gói dữ liệu này qua mạng?
Java cung cấp cho chúng ta đối tượng Serializable dùng để truyền
dữ liệu trên mạng. Muốn truyền đối tượng nào qua mạng chỉ cần đối tượng
đó hiện thực (implements) đối tượng Serializable là nó có khả năng trao đổi
trên mạng. Nhưng sau khi kiểm tra chúng tôi thấy rằng nếu dùng đối tượng
Serializable thì độ lớn của đối tượng hiện thực nó tăng lên khá nhiều so với
dữ liệu thực tế cần gửi. Điều này làm giảm tốc độ của chương trình vì nó
mất nhiều thời gian gửi hơn. Do đó dùng đối tượng Serializable không hiệu
quả.
Cách giải quyết tốt nhất là làm thế nào để cho độ lớn của gói dữ liệu
khi gửi bằng độ lớn thực tế của nó và việc thao tác trên các trường của gói
dữ liệu này được dễ dàng.
Để đóng gói và lấy các thành phần của packet ta xây dựng đối tượng
ByteStream. Đối tượng này cung cấp các phương thức reader và writer để
ghi các thành phần vào packet và đọc các thành phần này ra.
Các phương thức reader:
public byte readByte() // đọc 1 byte
public short readShort() // đọc 2 bytes
public int readInt() // đọc 4 bytes
public long readLong()// đọc 8 bytes
public byte[] readArray(int len) // đọc một mảng bytes
public long readCRC() // đọc số CRC 8 bytes.
Các phương thức writer:
16
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
public void writeByte(byte b) // ghi 1 byte
public void writeShort(short s) // ghi 2 bytes
public void writeInt(int i) // ghi 4 bytes
public void writeLong(long l) // ghi 8 bytes
public void writeArray(byte[] array) // ghi mang bytes array
Như đã giới thiệu điểm mạnh của multicast là dùng kết nối UDP để gửi
dữ liệu một lần lên địa chỉ multicast những client nào muốn nhận dữ liệu thì chỉ
kết nối vào địa chỉ multicast này và nhận dữ liệu. Địa chỉ multicast này là một
địa chỉ thuộc lớp D. Nếu dùng kết nối TCP thì mỗi client muốn nhận dữ liệu
phải tạo và duy trì một kết TCP giữa client và server. Nếu có hàng trăm hoặc
hàng ngàn kết nối được duy trì như vậy phải cần một băng thông rất lớn làm
như vậy thì hệ thống mạng của chúng ta có thể sụp đổ.
Quá trình gửi và nhận dữ liệu của file sử dụng kết nối UDP(multicast)
để thực hiện việc kết nối vào địa chỉ multicast, gửi và nhận dữ liệu lên địa chỉ
đó. Để thực hiện kết nối và gửi dữ liệu multicast Java cung cấp hai lớp
MulticastSocket và DatagramPacket để sử dụng dễ dàng.
Ví dụ:
Gửi dữ liệu:
MulticastSocket ms = new MulticastSocket();
// data là phần dữ liệu cần gửi đi.
DatagramPacket dp = new DatagramPacket(data, data.length, ia,
port);
//Kết nối vào nhóm multicast với địa chỉ ia thuộc lớp D.
ms.joinGroup(ia);
// gửi dữ liệu dp
ms.send(dp);
Nhận dữ liệu:
MulticastSocket ms = new MulticastSocket( port );
// tạo một đối tượng DatagramPacket
17
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
DatagramPacket dp = new DatagramPacket(data, length);
//Kết nối vào nhóm multicast với địa chỉ ia trùng với địa chỉ của máy
//gửi
ms.joinGroup(ia);
// Nhận dữ liệu
ms.receive(dp);
Việc kiểm tra các packet bị mất và yêu cầu server gửi lại có 2 giải pháp:
- Kiểm tra packet mất trong lúc nhận và yêu cầu server gửi lại ngay
packet này.
- Kiểm tra packet mất trong lúc nhận và yêu cầu server gửi lại khi
client đã nhận xong dữ liệu.
Giải pháp thứ nhất không hiệu quả vì nó sẽ làm giảm tốc độ của chương
trình. Nếu làm như vậy thì cứ mỗi client bị mất thì sẽ yêu cầu server gửi lại, có
thể có nhiều client mất những packet giống nhau như vậy server sẽ gửi lại
những packet đó nhiều lần điều này không cần thiết và nó làm giảm hiệu quả
của chương trình.
Giải pháp thứ hai hiệu quả hơn vì khi các client nhận xong dữ liệu một
lần rồi mới yêu cầu server gửi lại những packet đó. Như vậy server sẽ kiểm tra
tất cả các yêu cầu gửi packet mất của từng client rồi mới gửi lại những packet
đó một lần. Do đó làm tăng tính hiệu quả của chương trình.
Phương pháp kiểm tra packet:
Khi nhận được packet, ta dùng đối tượng ByteStream để tách dữ liệu ra
thành nhiều thành phần gồm: COMMAND 1byte, INDEX 4bytes, LENGTH
4bytes, DATA tuỳ thuộc vào server gửi, CRC 8bytes.
Kiểm tra tính chính xác của packet ta dựa vào số CRC nhận được và số
CRC ta sẽ tính khi nhận được packet này. Để tính số CRC ta dùng đối tượng
CRC32 trong Java. Để lấy được giá trị CRC ta cũng lần lượt update các giá trị
COMMAND, INDEX, LENGTH, DATA vừa nhận được vào đối tượng
CRC32 rồi sau đó lấy ra giá trị CRC này và so sánh nó vói số CRC lấy được từ
18
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
packet vừa nhận nếu chúng bằng nhau thì packet này đầy đủ và client sẽ ghi
phần DATA vào vị trí INDEX của file đã tạo. Nếu sai nghĩa là packet này sai
thì client sẽ đưa packet này vào danh sách các packet mất.
3.2 Phần Server
3.2.1 Các chức năng
3.2.2 Phân tích chức năng
- Listen Client Connect:
Khi nhấn nút accept thì usecase này hoạt động để chờ client kết
nối vào. Khi có một client kết nối vào, server sẽ lấy thông tin của
client này bao gồm IP và tên máy. Usecase này kết thúc khi nút
start copy được nhấn hoặc sau thời gian time out.
Sau khi kết thúc thì usecase Send Create File hoạt động.
- Listen Client Response:
Usecase này hoạt động sau khi usecase Send Create File hoặc
usecase Send Close File kết thúc. Usecase này dùng để nhận thông
tin phản hồi từ client và lấy những dữ liệu từ thông tin này.
Usecase kết thúc khi dữ liệu được lấy ra.
- Send Create File:
19
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Khi nhấn nút Start copy thì usecase này hoạt động để gửi lệnh tạo
file đến client (thông tin này bao gồm đường dẫn và tên file).
Usecase kết thúc khi gửi xong.
Khi usecase này kết thúc thì usecase Listen Client Response hoạt
động.
- Send Packet:
Khi usecase Listen Client Response kết thúc thì Send Packet thi
hành. Usecase này dùng để gửi từng packet đến tất cả client mà
server đã ghi nhận. Usecase này kết thúc khi dữ liệu đã gửi xong.
Khi usecase này kết thúc thì usecase Close File hoạt động.
- ReSend Packet:
Khi usecase Send Packet và usecase Listen Client Response kết
thúc. Server sẽ kiểm tra xem có client nào yêu cầu gửi những dữ
liệu đã mất hay không nếu có thì usecase ReSend Packet hoạt
đông để gửi lại tất cả những packet đã bị mất.
Khi usecase này kết thúc thì usecase Close File hoạt động.
- Send Close File:
Hoạt động khi usecase Send Packet hoặc ReSend Packet kết thúc.
Usecase này dùng để thông báo cho client biết sever đã gửi xong
dữ liệu. Khi gửi thông báo xong usecase kết thúc.
Khi usecase này kết thúc thì usecase Listen Client Response hoạt
động.
3.2.3 Sơ đồ hoạt động
20
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
3.3 Phần Client
3.3.1 Các chức năng
3.3.2 Phân tích chức năng:
- Send Client Info:
Sau khi nhập địa chỉ ip server và nhấn nút accept thì usecase hoạt
động. Client sẽ lấy địa chỉ và tên máy của mình và gửi đến server.
Sau khi gửi usecase sẽ kết thúc.
- Response Server:
21
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Usecase bắt đầu khi usecase Receive Create File Command hoặc
usecase Receive Close File kết thúc. Usecase này sẽ phản hồi
thông tin lên server. Thông tin này có thể là báo cho server biết file
có tạo được hay không hoặc báo cho server biết đã nhận được lệnh
close file hay chưa hoặc là gửi lên danh sách các packet đã bị mất
khi nhận. Usecase kết thúc khi thông tin được gửi lên server.
- Receive Create File Command:
Sau khi usecase Send Client Info kết thúc thì usecase Receive
Create File Command thực hiện. Usecase này sẽ nhận lệnh tạo file
và sẽ dựa vào thông tin của server gửi đến và tạo file. Usecase kết
thúc khi đã tạo xong file hoặc không thể tạo file.
- Receive Packet:
Sau khi phản hồi cho server biết đã tạo xong file, usecase Receive
Packet hoạt động. Usecase này sẽ nhận packet từ server, phân tích
những packet này và ghi dữ liệu vào file vừa tạo được. Usecase kết
thúc khi client nhận được lệnh close file từ server.
- Receive Packet Lost:
Sau khi usecase Receive Packet kết thúc client sẽ kiểm tra xem có
packet nào bị mất không, sau đó sẽ gửi thông tin lên server. Nếu có
packet bị mất thì thông tin này chứa nhưng packet đã bị mất Sau
khi gửi thì usecase Receive Packet Lost hoạt động. Usecase này sẽ
nhận những packet mất của mình và ghi những packet này vào file
đã tạo. Usecase này kết thúc khi usecase Receive Close File hoạt
động.
- Receive Close File:
Usecase này hoạt động cùng với sự hoạt động của usecase Receive
Packet hoặc Receive Packet Lost. Usecase này sẽ nhận lệnh close
22
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
file từ server và sẽ kết thúc usecase Receive Packet hoặc Receiver
Packet Lost.
3.3.3 Sơ đồ hoạt động
4. THIẾT KẾ CHƯƠNG TRÌNH
4.1 Phần Server
Quá trình hoạt động của server chia làm 5 giai đoạn sau:
Giai đoạn 1: Đợi client kết nối vào.
Giai đoạn 2: Gửi lệnh tạo file và nghe client trả lời có tạo được file hay
không.
Giai đoạn 3: Gửi dữ liệu
Giai đoạn 4: Gửi lệnh thông báo đã gửi xong và nghe client trả lời
Giai đoạn 5: Gửi lại những gói dữ liệu đã mất mà client yêu cầu. Sau đó
trở về giai đoạn thứ 4. Lặp cho đến khi không còn client
nào yêu cầu gửi dữ liệu.
4.1.1 Đợi client kết nối vào
23
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Mở một cổng TCP để nhận thông tin của các client gửi đến. Kết nối
TCP này đồng thời cũng kiểm tra xem client và server có kết nối được với
nhau hay không.
Server sẽ tạo ra một danh sách để lưu những thông tin của từng
client.
4.1.2 Gửi lệnh tạo file và nghe client trả lời
Khi nhấn nút start copy, server sẽ liệt kê trong danh sách đã lưu
có bao nhiêu client và sẽ gửi lệnh tạo file đến tất cả các client đó. Ứng
với mỗi client server sẽ tạo một kết nối TCP
Sau khi gửi server sẽ nghe client trả lời. Nếu client nào không tạo
được file hoặc quá trình tạo kết nối TCP không thành công thì server sẽ
loại bỏ những thông tin của client này trong danh sách.
Sau khi nghe client trả lời server sẽ bước vào giai đoạn gửi dữ
liệu.
4.1.3 Gửi dữ liệu
Giai đoạn này sử dụng kết nối UDP (multicast) để thực hiện việc
kết nối vào địa chỉ multicast và gửi dữ liệu lên đó. Để thực hiện kết nối
và gửi dữ liệu ta sử dụng hai lớp MulticastSocket và DatagramPacket.
Để kết nối vào nhóm multicast thì ta gọi phương thức
joinGroup() và truyền vào phương thức này một địa chỉ lớp D. Tất cả
các host (cả server và client) tham gia vào quá trình gửi nhận dữ liệu đều
phải kết nối vào cùng địa chỉ này.
Để gửi dữ liệu đi thì cần tạo ra một đối tượng DatagramPakect.
Sau đó dùng phương thức send và truyền đối tượng DatagramPacket vừa
mới tạo ra vào phương thức send của đối tượng MulticastSocket trên để
gửi.
Để gửi dữ liệu server sẽ cắt file cần gửi ra thành nhiều phần
(DATA), những phần này nhiều hay ít dựa vào độ lớn của gói dữ liệu
24
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
(packet) mà server gửi. Ứng với mỗi packet sẽ được đánh một chỉ số
(INDEX).
Để đóng gói các packet ta xây dựng một lớp ByteStream. Lớp
này dùng để ghi các thành phần COMMAND, INDEX, LENGTH,
DATA, CRC vào gói và lấy các thành phần đó ra.
Dữ liệu được cắt từ file sẽ được đánh số (INDEX) tuần tự từ
packet đầu tiên cho đến packet cuối cùng. Và server cũng sẽ gửi tuần tự
các gói này.
Sau khi gửi dữ liệu xong server sẽ bước vào giai đoạn gửi thông
báo và nghe client trả lời.
4.1.4 Gửi lệnh thông báo đã gửi xong và nghe client trả lời
Sử dụng kết nối TCP. Vì dữ liệu trao đổi trong giai đoạn này rất
nhỏ.
Giai đoạn này server gửi thông báo đã gửi xong packet cho tất cả
các client và nghe client trả lời và sẽ tạo ra một danh sách chứa các
packet bị mất của các client. Danh sách này chứa phần index của packet.
4.1.5 Gửi lại những gói dữ liệu đã mất
Server dựa vào danh sách các packet mất và lấy ra đúng những
dữ liệu đó đóng gói và gửi đến client. Quá trình gửi dữ liệu trong giai
đoạn này cũng giống như giai đoạn gửi dữ liệu.
4.2 Phần Client
Quá trình hoạt động của Client chia làm 5 giai đoạn:
Giai đoạn 1: Kết nối với server và gửi thông tin lên server gồm địa chỉ ip
và tên máy.
Giai đoạn 2: Nhận lệnh tạo file và trả lời cho server.
Giai đoạn 3: Nhận dữ liệu phân tích dữ liệu và ghi vào file đã tạo.
Giai đoạn 4: Nhận thông báo từ server và trả lời cho server.
25
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Giai đoạn 5: Nhận dữ liệu bị mất phân tích và ghi vào file. Sau đó trở lại
giai đoạn 4. Lặp cho đến khi hết packet mất.
4.2.1 Kết nối server và gửi thông tin lên server
Tạo một kết nối TCP để gửi thông tin của client đến server. Kết
nối TCP này đồng thời cũng kiểm tra xem client và server có kết nối
được với nhau hay không.
Nếu không kết nối được với server chương trình sẽ thông báo lỗi.
4.2.2 Nhận lệnh tạo file và trả lời server
Sau khi gửi thông tin lên server, client sẽ tạo kết nối TCP để nghe
lệnh tạo file từ server khi nhận được lệnh tạo file client sẽ dựa vào
đường dẫn trong lệnh này mà tạo file.
Khi tạo xong file hoặc không tạo được thì client cũng gửi thông
báo lên server. Nếu file không tạo được hoặc kết nối TCP không thành
công thì client sẽ thông báo lỗi.
4.2.3 Nhận dữ liệu phân tích và ghi vào file
Giai đoạn này sử dụng kết nối UDP (multicast). Client sẽ kết nối
vào một địa chỉ lớp D đã định sẵn để nhận dữ liệu. Địa chỉ này chính là
địa chỉ mà server kết nối vào để gửi dữ liệu lên.
Để kết nối vào nhóm multicast thì ta gọi phương thức joinGroup
của đối tượng MulticastSocket và truyền vào phương thức này một địa
chỉ lớp D trùng với địa chỉ mà server đã gửi lên. Tất cả các host (cả
server và client) tham gia vào quá trình gửi nhận dữ liệu đều phải kết nối
vào cùng địa chỉ này.
Các dữ liệu nhận được là các packet có cấu trúc giống như cấu
trúc packet đã gửi.
Client sẽ lấy từng thành phần của packet này ra: COMMAND,
INDEX, LENGTH, DATA, CRC. Client sẽ tính lại số crc của packet
26
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
nhận được nếu số CRC vừa tính bằng với số CRC mà server gửi qua thì
client sẽ ghi phần DATA và vào vị trí INDEX của file đã tạo.
Trong quá trình nhận packet client sẽ kiểm tra sự mất mát dữ liệu,
nếu có dữ liệu mất thì client sẽ tạo ra một danh sách chứa các packet mất
này. Và sẽ yêu cầu server gửi lại những packet mất này.
4.2.4 Nhận thông báo từ server và trả lời server
Khi giai đoạn 3 bắt đầu thì client tạo một kết nối TCP để nghe
server gửi lệnh đóng file. Khi server gửi xong dữ liệu server sẽ kết nối
vào client để thông báo đã gửi xong file. Khi client nhận được thông báo
này thì sẽ kết thúc giai đoạn nhận dữ liệu. Sau đó client sẽ trả lời cho
server nếu trong quá trình nhận dữ liệu có mất mát thì client sẽ gửi danh
sách dữ liệu mất này đến server.
4.2.5 Nhận dữ liệu mất
Tương tự như quá trình nhận dữ liệu ở gian đoạn 3. Nhưng client
sẽ lọc những dữ liệu nào mà mình cần phải ghi. Vì khi server gửi những
dữ liệu mất nó sẽ gửi tất cả những packet mất của các client nên có thể
có những packet client nhận được không phải là của nó nên client phải
kiểm tra những dữ liệu này.
4.3 UDP kết nối truyền hình ảnh
Việc tiếp nhận các gói tin multicast có thể được chia thành các bước sau: 1. Trong bước đầu tiên trên socket multicast ist tạo ra bằng cách gọi MulticastSocket ()
trong đó có các cổng cắm là ràng buộc để làm tham số. 2. Bước tiếp theo là để tham gia vào nhóm Multicast.
Một nhóm Multicast được đại diện bởi một số IP từ 224.0.0.0 tới 239.255.255.255. To join the group the joinGroup() method is called. Để tham gia vào nhóm các joinGroup () phương thức được gọi.
3. Tạo một bộ đệm byte, DatagramPacket một đối tượng và gọi phương thức MulticastSocket nhận () để chấp nhận một gói tin datagram.
4. Sau khi nhận và xử lý các gói gói dữ liệu bằng cách gọi GetData () trên DatagramPacket bước cuối cùng là rời khỏi nhóm multicast và đóng socket multicast. Điều này được thực hiện bằng cách gọi leaveGroup phương pháp () và đóng () trên các socket multicast.
/ * Bước một * / int port = 4444; int port = 4444;
27
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
MulticastSocket ms = new MulticastSocket(port); MulticastSocket ms = new MulticastSocket (port);
/ * Bước hai * / String multicastAddress = "225.4.5.6"; MulticastAddress String = "225.4.5.6"; InetAddress ia = InetAddress.getByName(multicastAddress); InetAddress ia = InetAddress.getByName (multicastAddress); ms.joinGroup(ia); ms.joinGroup (ia);
/ * Bước ba * / DatagramPacket dp = new DatagramPacket(buffer, buffer.length); DatagramPacket dp = new DatagramPacket (buffer, buffer.length); ms.receive(dp); ms.receive (dp); byte[] data = dp.getData(); byte [] data = dp.getData ();
/ * Bước bốn * / ms.leaveGroup(ia); ms.leaveGroup (ia); ms.close(); ms.close ();
Truyền gói tin multicast
TTL - Time To Live TTL - Time To Live
Chỉ định số router để vượt qua (hopcount) trước khi gói tin sẽ bị loại. Mỗi bộ định tuyến đi qua các gói tin sẽ lượng giảm TTL một. Các gói tin với TTL bằng không sẽ bị loại bỏ. Đối với MulticastSockets (trong Java) giá trị mặc định TTL là 1, có nghĩa là tất cả các gói tin sẽ ở lại trong cùng một mạng. Tham số này có thể được thay đổi bởi setTimeToLive gọi () trên một MulticastSocket Time To Live (TTL)
Truyền các gói tin multicast là một ít nhận được các gói dữ liệu dễ dàng hơn, nhóm A đã không được tham gia nếu các gói tin chỉ được gửi. Đây là những bước cần thiết để truyền tải một gói tin multicast:
1. Trong bước đầu tiên một InetAddress cho các quy định Multicast Group Địa chỉ IP được tạo ra.
2. Bước tiếp theo là xây dựng một ổ cắm dategram multicast và gói tin. 3. Điều duy nhất bây giờ đó là lại là gửi các gói dữ liệu trên các ổ cắm multicast và đóng
socket.
/ * Bước một * / String multicastAddress = "225.4.5.6"; MulticastAddress String = "225.4.5.6"; InetAddress ia = InetAddress.getByName(multicastAddress); InetAddress ia = InetAddress.getByName (multicastAddress);
/ * Bước hai * / int port = 4444; int port = 4444; ms = new MulticastSocket(); ms = new MulticastSocket (); DatagramPacket dp = new DatagramPacket(imageData, imageData.length, DatagramPacket dp = new DatagramPacket (imageData, imageData.length, ia, port); ia, port);
/ * Bước ba * / ms.send(dp); ms.send (dp); ms.close(); ms.close ();
28
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Tạo Ảnh chụp màn hình
Gửi ảnh chụp màn hình qua mạng là khá thú vị vì nó cho chúng ta khả năng để hiển thị một bài thuyết trình hoặc nội dung của màn hình cho người khác. Tạo ảnh chụp màn hình trong Java ist rất dễ dàng. Từ Java 1,3 lớp Robot có sẵn, mà cũng cho chúng ta possiblity để tạo screenshot. Các createScreenCapture phương pháp () của lớp Robot có một hình chữ nhật mà xác định phần của màn hình để chụp. Trong trường hợp của chúng tôi, chúng tôi sẽ luôn luôn nắm bắt toàn bộ màn hình. Dưới đây là nguồn gốc cho các getScreenshot phương pháp () được sử dụng để có được ảnh chụp màn hình trong chương trình của chúng tôi.
công getScreenshot BufferedImage tĩnh () ném AWTException,
ImageFormatException, IOException {
Bộ công cụ bộ công cụ = Toolkit.getDefaultToolkit ();
Kích thước screenSize = toolkit.getScreenSize ();
Hình chữ nhật screenRect = new Rectangle (screenSize);
Robot robot = new Robot ();
BufferedImage hình = robot.createScreenCapture (screenRect);
trở lại hình ảnh;}
Đọc các hình ảnh từ các hệ thống tập tin
Trong addintion để gửi ảnh chụp màn hình ứng dụng cũng có thể gửi hình ảnh được lưu trữ trong hệ thống tập tin. Các ứng dụng sẽ đọc các định dạng ảnh JPEG từ một thư mục theo thứ tự ngẫu nhiên.
công getRandomImageFromDir BufferedImage tĩnh (File dir) throws IOException {String [] hình ảnh = dir.list (mới ImageFileFilter ());
int ngẫu nhiên = new Random () nextInt (images.length).
String FileName = dir.getAbsoluteFile () + File.separator + hình ảnh [ngẫu nhiên];
Tập tin imageFile = new File (tên tập tin);
trở lại ImageIO.read (imageFile);}
ImageFileFilter lớp thực hiện FilenameFilter{
boolean nào chấp nhận (File dir, String name){
String nameLc = name.toLowerCase ();
trở lại nameLc.endsWith (". jpg")? true : false; đúng: đúng;}}
Các giới hạn 65507 byte có thể được enought cho hình ảnh nhỏ, nhưng đối với ảnh chụp màn hình toàn màn hình nó sẽ không được đầy đủ. Nó sẽ có thể quy mô xuống các hình ảnh để chúng phù hợp với một gói UDP duy nhất nhưng điều này sẽ làm cho những hình ảnh khó xem.
29
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Trong giải pháp của chúng tôi, chúng tôi sẽ chia ra các hình ảnh vào một cách thích hợp khối có kích thước và chuyển chúng qua mạng. Như đã đề cập ở trên UDP không có người điều khiển giao thông xây dựng bên trong, vì vậy chúng tôi phải chăm sóc cho chính mình.
Kiểm soát giao thông
Để chắc chắn rằng những hình ảnh truyền qua đường lát được tập hợp lại theo thứ tự đúng một số tiêu đề được thêm vào các gói UDP. Điều này sẽ làm giảm lượng dữ liệu có thể được chuyển giao trong một gói tin, nhưng đó phải được chấp nhận.
Người gửi quyết định kích thước của mỗi slize hình ảnh, sau đó nó sẽ gửi các slice người một qua mạng cùng với tiêu đề bổ sung thông tin mô tả ở trên. Theo thông tin được đưa ra trong thông tin tiêu đề bổ sung thu hình ảnh có thể xác định kích thước cuối cùng của hình ảnh, vị trí của dữ liệu hình ảnh hiện tại và thời tiết hình ảnh được hoàn thành.
Đoạn mã người gửi được hiển thị dưới đây:
while (true) {
BufferedImage hình = getScreenshot ();
30
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
hình = thu nhỏ (hình ảnh, scalingFactor);
byte [] imageByteArray = bufferedImageToByteArray (hình ảnh, OUTPUT_FORMAT);
gói int = (int) Math.ceil (imageByteArray.length / (float) DATAGRAM_MAX_SIZE);
int HEADER_SIZE = 8;
int MAX_PACKETS = 255;
int session_start = 128;
SESSION_END int = 64;
if (gói> MAX_PACKETS) {
System.out.println ("Hình ảnh quá lớn được truyền đi!");
tiếp tục;}
for (int i = 0; i <= gói; i + +) {
int cờ = 0;
cờ = i == 0? flags | SESSION_START: flags; cờ | session_start: cờ;
cờ = (i + 1) * DATAGRAM_MAX_SIZE> imageByteArray.length? flags | SESSION_END : flags; cờ |
SESSION_END: cờ;
int size = (cờ&SESSION_END)!= SESSION_END? DATAGRAM_MAX_SIZE :
imageByteArray.length - i * DATAGRAM_MAX_SIZE; DATAGRAM_MAX_SIZE: imageByteArray.length - i *
DATAGRAM_MAX_SIZE;
byte [] dữ liệu = new byte [HEADER_SIZE + size];
dữ liệu [0] = (byte) cờ;
dữ liệu [1] = (byte) sessionNumber;
dữ liệu [2] = (byte) gói tin;
dữ liệu [3] = (byte) (DATAGRAM_MAX_SIZE>> 8);
dữ liệu [4] = (byte) DATAGRAM_MAX_SIZE;
dữ liệu [5] = (byte) i;
dữliệu[5]=(byte) i; data[6] = (byte)(size >> 8); dữ liệu [6] = (byte) (kích thước>> 8);
dữ liệu [7] = (byte) kích thước;
System.arraycopy (imageByteArray, i * DATAGRAM_MAX_SIZE, dữ liệu, HEADER_SIZE, kích
thước);
sender.sendImage (dữ liệu, "225.4.5.6", 4444);
if ((cờ & SESSION_END) == SESSION_END) break;}
Thread.sleep (SLEEP_MILLIS);
sessionNumber = sessionNumber <MAX_SESSION_NUMBER:? + + sessionNumber 0;}
Người nhận dữ liệu UDP kiểm tra và xác định thời tiết hình ảnh thuộc về phiên họp
hiện tại và nếu các slice hình ảnh đã được lưu trữ. Sau khi tất cả các lát habe được thu
thập hình ảnh được hiển thị.
byte [] buffer = new byte [DATAGRAM_MAX_SIZE];
while (true) {
DatagramPacket dp = new DatagramPacket (buffer, buffer.length);
31
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
ms.receive (dp);
byte [] data = dp.getData ();
int session_start = 128;
SESSION_END int = 64;
int HEADER_SIZE = 8;
ngắn phiên = (ngắn) (dữ liệu [1] & 0xFF);
lát ngắn = (ngắn) (dữ liệu [2] & 0xFF);
int maxPacketSize = (int) ((dữ liệu [3] và 0xFF) <<8 | (dữ liệu [4] & 0xFF)); / / mặt nạ bit dấu
ngắn slice = (ngắn) (dữ liệu [5] & 0xFF);
int size = (int) ((dữ liệu [6] & 0xFF) <<8 | (dữ liệu [7] & 0xFF)); / / mặt nạ bit dấu
if ((dữ liệu [0] & session_start) == session_start) {
if (session = currentSession!) {
currentSession = phiên;
slicesStored = 0;
imageData = new byte [lát * maxPacketSize];
slicesCol = new int [lát];
sessionAvailable = true;
}}
if (sessionAvailable & & phiên == currentSession) {
if (slicesCol null! = & & slicesCol [slice] == 0) {
slicesCol [slice] = 1;
System.arraycopy (dữ liệu, HEADER_SIZE, imageData, maxPacketSize * slice, kích thước);
slicesStored + +;}}
if (slicesStored == lát) {
ByteArrayInputStream bis = new ByteArrayInputStream (imageData);
BufferedImage hình = ImageIO.read (bis);
labelImage.setIcon (mới ImageIcon (hình ảnh));
indowImage.setIcon (mới ImageIcon (hình ảnh));
frame.pack ();}}
Tham số dòng lệnh
Các chương trình cũng có thể được chạy bằng cách xác định thông số dòng lệnh. Khi không có thông số dòng lệnh được quy định các giá trị mặc định sau được sử dụng:
IP Multicast Address: 225.4.5.6 IP Multicast Địa chỉ: 225.4.5.6 Port: Port: 4444 4444 Display Mouse Cursor: Hiển thị Mouse Cursor: 1 1 Update Interval in seconds (Sender): Thông tin gian trong vài giây (Tên người gửi): 2 2 Scaling Factor: Scaling Factor: 0.5 0.5
32
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Các tham số dòng lệnh sau đây có sẵn: java -jar ImageReceiver.jar port ip_address. Các tùy chọn dòng lệnh không cần phải được xác định hoàn toàn, nhưng không ai cóthểbỏquaởgiữa. Vì vậy, chỉ định các tuỳ chọn sau là ok: java-jar ImageSender.jar 0,7 3 1 năm 2048
5. KẾT QUẢ
5.1 Kết quả
Sau khi tìm hiểu về multicast cũng như qua việc phân tích thiết kế
chương trình, chúng tôi đã xây dựng chương trình Multicast hình ảnh và đạt
được những kết quả sau:
- Xây dựng xong tất cả các giai đoạn trong chương trình server cũng
như client.
- Truyền được một file từ server đến nhiều client.
5.2 Hướng phát triển
- Chương trình hiện nay chỉ truyền được một file. Hướng phát triển
là xây dựng chương trình có thể truyền được một thư mục.
- Phát triển chương trình có thể truyền được qua mạng rộng không
chỉ giới hạn như mạng LAN như hiện nay.
- Phát triển lên thành một chương trình ghost.
6. TÀI LIỆU THAM KHẢO
- Core Java 2 - tác giả: Cay S. Horstmann, Gary Cornell
- Java Network Programming, NXB: O’Reilly
- Java Swing, NXB: O’Reilly
- Web site: http://www.winnetmag.com Bài viết: IP Multicast and
Your Network, tác giả: Tao Zhou.
- Web site: http://www.tldp.org/HOWTO Bài viết: Multicast over
TCP/IP HOWTO, tác giả: Juan-Mariano
- Web site: http://www.inria.fr
7. GIAO DIỆN VÀ HƯỚNG DẪN SỬ DỤNG CHƯƠNG TRÌNH:
7.1 Server
Giao diện:
33
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
Cách sử dụng:
- Để copy file trước tiên ta phải chạy chương trình server trước.
- Accept: Quá trình nhận client kết nối vào bắt đầu khi nhấn nút
Accept.
- Browse: Để lấy file copy ta có thể nhập trực tiếp đường dẫn file
hoặc nhấn nút Browse để tìm đến file cần copy. Thông tin này
được hiển thị trên Source file.
- Destination Path: Muốn file này được lưu ơ đâu tại client, ta phải
nhập vào đường dẫn mà mình muốn lưu trên Destination Path. Ví
dụ: d:\tienhung thì sau khi copy thì file này sẽ được lưu trong thư
mục d:\tienhung của client.
- Start Copy: Sau khi client đã kết nối vào server, để copy file thì
nhấn vào nút Start copy, quá trình copy sẽ bắt đầu.
- ReSend Times: Ta có thể lựa chọn số lần gửi lại packet mất trong
phần ReSend Times. Ta nên để All Times vì lựa chọn này sẽ copy
dữ liệu đến tất cả các client cho đến khi tất cả các client nhận hết
34
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
dữ liệu. Nếu lựa chọn số lần ít thì có thể có client không nhận đủ
hết dữ liệu.
- Packet Size: Dùng để định độ lớn của mỗi packet
- Time Delay: Khoảng thời gian nghỉ giữa mỗi lần gửi packet
- New Copy: Sau khi copy xong ta có thể chọn nút New Copy để
copy lại một file mới.
7.2 Client
Giao diện:
Cách sử dụng:
- Sau khi server chạy và nhấn nút Accept thì client mới có thể kết
nối vào server.
- Accept: ta phải nhập địa chỉ IP vào rồi nhấn nút Accept để kết nối
vào server.
- Sau khi nhấn nút Accept, client sẽ chờ để nhận dữ liệu của server.
Khi server nhấn nút Start Copy thì client sẽ nhận dữ liệu và ghi
vào file cho đến khi nào kết thúc file.
- Reset: đặt client về trạng thái ban đầu
- Close: đóng chương trình client.
7.3 Server udp trực tiếp hình ảnh: thu ảnh truyền qua địa chỉ multicast.
35
Lập trình Java: Muticast hình ảnhGiảng viên hướng dẫn: Lê Đức Trị
7.4 Client udp trực tiếp hình ảnh: nhận và hiển thị trực tiếp
36
Recommended