Tại cácphòng máy đó các giảng viên có thể dễ dàng truyền đạt kiến thức một cách sinh động,trực quan cho các học viên bằng cách sử dụng chức năng chia sẻ màn hình của phầnmềm quản lý phòn
Trang 1TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
Giảng viên hướng dẫn: TH.S NGUYỄN TIẾN LỢI
Trang 2Hà Nội, 05/2012
PHIẾU GIAO ĐỀ TÀI
Trang 3NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN
Hà Nội, ngày tháng năm 2012 Giảng viên
Trang 4Th.S Nguyễn Tiến Lợi
LỜI NÓI ĐẦU
Công nghệ thông tin là ngành công nghiệp mũi nhọn của thế giới nói chung vàcủa Việt Nam nói riêng, nó đã phát triển mạnh mẽ không ngừng trong những năm gầnđây Số lượng các trường học có đào tạo nghành CNTT ngày một tăng cao, cùng với
đó là các trung tâm tin học mở ra ngày một nhiều Và lẽ tự nhiên khi các trường, cáctrung tâm muốn có các phòng máy chất lượng thì họ cũng sẽ có nhu cầu sử dụng các
hệ thống quản lý phòng máy đa năng, tiện dụng và thân thiện người sử dụng Tại cácphòng máy đó các giảng viên có thể dễ dàng truyền đạt kiến thức một cách sinh động,trực quan cho các học viên bằng cách sử dụng chức năng chia sẻ màn hình của phầnmềm quản lý phòng máy, hoặc giảng viên có thể chỉ dẫn cho học viên trực tiếp trênmàn hình của học viên chỉ bằng thao tác đơn giản giống như trực tiếp giảng viên ngồitại máy của học viên …
Do đó việc xây dựng một phần mềm lớp học ảo trong mạng Lan là một việc rấtcần thiết, nhằm hỗ trợ các giảng viên cũng như hỗ trợ các học viên có thể tiếp cậnđược với cách học tập trực quan dễ hiểu Nhận thức được tầm quan trọng cũng nhưcấp thiết phải có một hệ thống quản lý các máy tính trong phòng học mạng Lan Nhómchúng em đã đăng ký đề tài “Xây dựng phần mềm lớp học ảo trong mạng Lan” Với hivọng phần mềm sẽ giải quyết được phần nào trong quá trình dạy và học trong phòngmáy sử dụng mạng Lan Và tiến xa hơn đó là một phần mềm đào tạo thông qua mạngInternet, ở đó cả học viên và giảng viên có thể truy cập từ bất kỳ máy tính nào đượccài đặt phần mềm việc học tập và giảng dạy sẽ càng trở lên dễ dàng hơn
Để hoàn thành báo cáo thực tập tốt nghiệp này, chúng em đã được sự giúp đỡ
tận tình của giảng viên hướng dẫn - Th.S Nguyễn Tiến Lợi - Giảng viên khoa CNTT
trường Đại Học Công Nghiệp Hà Nội, Thầy đã tận tình hướng dẫn, góp ý chỉnh sửa rấtchi tiết cho bài báo cáo của chúng em Chúng em xin chân thành gửi lời cảm ơn sâusắc tới Thầy Xin chúc Thầy và gia đình luôn mạnh khỏe và thạnh phúc
Trang 5TÓM TẮT NỘI DUNG BÁO CÁO THỰC TẬP TỐT NGHIỆP
1 Những nội dung sẽ được trình bày trong bài báo cáo.
Đề xuất xây dựng một phần mềm lớp học ảo trong mạng Lan có những chứcnăng chính sau đây
Chia sẻ màn hình giảng dạy
Chia sẻ tài liệu học tập
Chat Message
Điều khiển máy tính từ xa (Remote Desktop)
Hỗ trợ giảng viên một số chức năng và tiện ích khác
Đưa ra các kiến thức, kỹ thuật cơ bản và quan trọng về lập trình mạng vớiSocket và Net Remoting
Nghiên cứu các lĩnh vực lập trình nâng cao như các hàm API, lập trình xử lýảnh có ứng dụng cụ thể trong bài toán
Báo cáo về quá trình để xây dựng các module chính của phần mềm, và sau đótiến hành xây dựng một phần mềm hoàn thiện
Đưa ra một phần mềm hoàn thiện và đánh giá về các kết quả thực nghiệm
2 Cấu trúc của báo cáo.
Chương 1 Tổng quan về đề tài
Chương 2 Lý thuyết cơ sở
Chương 3 Ứng dụng phần mềm quản lý lớp học ảo
Chương 4 Cài đặt và thử nghiệm
Chương 5 Kết luận
Tài liệu tham khảo và kiến nghị
Trang 6DANH SÁCH HÌNH ẢNH
Hình 2 1: Chức năng của Socket 16
Hình 2 2 Sơ đồ giao tiếp các máy tính khác nhau 17
Hình 2 3: Các chế độ giao tiếp các tầng mạng khác nhau 18
Hình 2 4 Minh họa quá trình khởi tạo TCP Socket Server 19
Hình 2 5 Mô tả quá trình khởi tạo TCP Socket Client kết nối tới Server 19
Hình 2 6 Mô tả quá trình truyền nhận thông tin giữa Server và Client 20
Hình 2 7 Mô tả kết thúc phiên làm việc giữa Client và Server 20
Hình 2 8 Mô tả quá trình khởi tạo UDP Socket Server 21
Hình 2 9 Mô tả quá trình khởi tạo UDP Socket Client 21
Hình 2 10 Mô tả quá trình truyền nhận dữ liệu bằng UDP 22
Hình 2 11 Mô hình trao đổi thông tin của Net Remoting 29
Hình 2 12 Lập trình sự kiện trong Windows 33
Hình 2 13 Gửi và nhận sự kiện trong Windows 34
Hình 2 14 Kết quả chương trình không sử dụng đồng bộ hóa 41
Hình 2 15 Kết quả chương trình sử dụng đồng bộ hóa 42
Hình 2 16 Biểu diễn ảnh trong hệ màu RGB 46
Hình 2 17 Mô tả thuật toán cắt ảnh 46
Hình 2 18 Mô tả ma trận điểm ảnh 47
Hình 2 19 Minh họa thuật toán so sánh ảnh 47
Hình 3 1 Mô hình phân cấp chức năng
56
Hình 3 2 Hình minh họa chức năng chia sẻ màn hình 57
Hình 3 3 Các nội dung giảng dạy có trên màn hình các máy học viên 57
Hình 3 4 Minh họa chia sẻ màn hình cho toàn bộ học viên 58
Hình 3 5 Minh họa các tài liệu được chia sẻ 58
Hình 3 6 Minh họa chức năng chia sẻ màn hình 59
Hình 3 7 Mô hình luồng dữ liệu 60
Trang 7DANH MỤC BẢNG BIỂU
Bảng 1 1 Cấu hình tối thiểu của phòng máy 13
Bảng 1 2 Cấu hình được khuyến cáo trong phòng máy 13
Bảng 2 1 Một số phương thức của lớp NetworkStream 23
Bảng 2 2 Một số phương thức lớp StreamRead 24
Bảng 2 3 Một số phương thức lớp StreamWriter 24
Bảng 2 4 Các thành viên của lớp TCPClient 25
Bảng 2 5 Các phương thành viên của lớp TCPListener 26
Bảng 2 6 các thành viên của lớp UDPClient 27
Bảng 2 7 Các phương thức của lập trình Socket bất đồng bộ 28
Bảng 2 8 Một số lớp thuộc tính của thư viện System.Thread 36
Bảng 2 9 Các thành phần static của lớp Thread 36
Bảng 2 10 Các thành viên cấp đối tượng của lớp Thread 37
Bảng 2 11 Các thành phần chính của Registry 53
Trang 8DANH MỤC CÁC THUẬT NGỮ VIẾT TẮT Danh sách từ viết tắt Nghĩa của từ
LanVC Lan Virual Class (Phần mềm lớp học ảo)
TCP Transmission Control Protocol
RGB Không gian màu gồm ba màu Red - Blue - Green
MỤC LỤC PHIẾU GIAO ĐỀ TÀI 2 NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN 3
Trang 9LỜI NÓI ĐẦU 4
TÓM TẮT NỘI DUNG BÁO CÁO THỰC TẬP TỐT NGHIỆP 5
DANH SÁCH HÌNH ẢNH 6
DANH MỤC BẢNG BIỂU 7
DANH MỤC CÁC THUẬT NGỮ VIẾT TẮT 8
MỤC LỤC 9
CHƯƠNG 1 TỔNG QUAN VỀ ĐỀ TÀI 12
1.1 Lý do chọn đề tài 12
1.2 Tình hình nghiên cứu trên thực tế 12
1.3 Vấn đề đặt ra của đề tài 13
1.3.1 Một số vấn đề về cấu hình của hệ thống 13
1.3.2 Đề xuất các module 13
1.4 Mục tiêu của đề tài 14
1.5 Đối tượng và phương pháp nghiên cứu 14
1.5.1 Đối tượng nghiên cứu 14
1.5.2 Phương pháp nghiên cứu 14
1.6 Dự kiến các kết quả nghiên cứu 15
1.7 Kết luận 15
CHƯƠNG 2 LÝ THUYẾT CƠ SỞ 16
2.1 Lập trình Socket C# 16
2.1.1 Socket là gì? 16
2.1.2 Chức năng của Socket 16
2.1.3 Phân loại Socket 16
2.1.4 Thành phần của một Socket 17
2.1.4.1 Số hiệu cổng (port number) 17
2.1.4.2 Địa chỉ IP 17
2.1.5 Các chế độ giao tiếp 18
2.1.6 Xây dựng ứng dụng Client-Server với Socket: 18
2.1.6.1 Mô hình Client-Server sử dụng Socket ở chế độ có kết nối (TCP) 19
2.1.6.2 Mô hình Client-Server sử dụng Socket ở chế độ không kết nối (UDP) 20
2.1.7 Sử dụng C# Stream với TCP 22
2.1.7.1 Lớp NetworkStream 22
2.1.7.2 Lớp StreamReader và StreamWriter 23
2.1.8 Sử dụng các lớp Helper Socket 24
2.1.8.1.TCPClient 24
2.1.8.2 TCPListener 25
2.1.8.3 UDPClient 26
2.1.9 Lập trình Socket bất đồng bộ 27
2.1.9.1 Thành lập kết nối 28
2.1.9.2 Trao đổi dữ liệu 28
2.2 Lập trình Net Remoting 29
2.2.1 Các khái niệm 29
2.2.2 Remote Objects trong NET Remoting 29
2.2.3.Domain 30
2.2.4.Channel 30
2.2.5 Object Activation 31
2.2.6 Client Activated Objects 31
2.2.7 Tạo một Remotable Object 32
2.3 Lập trình sự kiện trong Windows 33
2.3.1 Sử dụng Event và Delegate 33
Trang 102.4 Lập trình đa luồng 34
2.4.1 Khái niệm đa luồng (Thread) 34
2.4.2 Tham khảo thư viện System.Thread 35
2.4.2 Lớp Thread 36
2.4.3 Thao tác với luồng 37
2.4.4 Đồng bộ hóa (Synchronization) trong lập trình đa luồng 39
2.4.4.1 Đồng bộ hóa 39
2.4.4.2 Deadlock 42
2.4.4.3 Race condition 43
2.5 Lập trình xử lý ảnh trong C# 45
2.5.1 Một số khái niệm xử lý ảnh 45
2.5.1.1 Khái niệm ảnh 45
2.5.2 Kỹ thuật xử lý ảnh cơ bản 46
2.5.2.1 Thuật toán cắt ảnh 46
2.5.2.2 Thuật toán so sánh hai ảnh bitmap 47
2.6 Một số kỹ thuật khác 48
2.5.1 Các hàm API 48
2.5.1.1 Khái niệm API 48
2.5.1.2 Các thành phần của Windows API 48
2.5.1.3 Cách dùng các hàm API 48
2.5.1.4 Sử dụng các hàm API 49
2.5.2 XML 50
2.5.2.1 Khái niệm về XML 50
2.5.2.2 Các quy tắc viết thẻ XML 51
2.5.3 Registry trong C# 51
2.5.3.1 Khái niệm Registry 51
2.5.3.2 Các lớp Net Registry 51
2.7 Kết luận chương 53
CHƯƠNG 3 ỨNG DỤNG PHẦN MỀM QUẢN LÝ LỚP HỌC ẢO 54
3.1 Phân tích thiết kế hệ thống 54
3.1.1.Khảo sát hiện trạng và lập dự án 54
3.1.1.2 Đề xuất ý tưởng xây dựng hệ thống mới 54
3.1.1.3 Mô tả hoạt động của hệ thống 54
3.1.2 Phân tích các chức năng của hệ thống 55
3.1.2.1 Mô hình phân cấp chức năng 55
3.1.2.2 Giải thích rõ từng chức năng của hệ thống 56
3.1.2.3 Mô hình luồng dữ liệu 59
3.2 Xây dựng các lớp xử lý chính 60
3.2.1 Các lớp bên phía Server 60
3.2.1.1 Lớp ServerReceiver 60
3.2.1.2 Lớp ServerSender 62
3.2.1.3 Lớp ServerTCP 65
3.2.1.4 Lớp BuffData 70
3.2.2 Các lớp bên phía Client 71
3.2.2.1 Lớp ClientReceiver 72
3.2.2.2 Lớp ClientSender 74
3.2.2.3 Lớp ClientTCP 76
3.3 Thiết kế giao diện 79
CHƯƠNG 5 KẾT LUẬN 80
5.1 Những kết quả đạt được 80
Trang 115.2 Hướng phát triển 80 TÀI LIỆU THAM KHẢO 81
CHƯƠNG 1 TỔNG QUAN VỀ ĐỀ TÀI 1.1 Lý do chọn đề tài.
Trang 12Hiện nay, với sự phát triển vượt bậc của khoa học công nghệ trong đời sống xãhội Việc ứng dụng công nghệ mạng Lan vào trong việc giảng dạy tại các trường ĐạiHọc, và Cao Đẳng ngày càng phát triển Nhưng việc quản lý phòng học trong mạngLan còn nhiều bất cập
Tốn kém đầu tư tiền của vào hệ thống máy chiếu, bảng hiện tại
Khó khăn trong khâu chia sẻ tài liệu học tập
Giáo viên khó khăn trong quá trình giảng dạy, và giải đáp thắc mắc họcviên
Không có nhiều sự tương tác giữa giảng viên và học sinh
Vì vậy xuất phát từ vấn đề đó nhóm chúng em quyết định lựa chọn đề tài “Xây
dựng phần mềm lớp học ảo trong mạng Lan” Với mong muốn đem lại một phần
mềm giúp tận dụng sức mạnh của CNTT đem lại hiệu quả cho việc giảng dạy trongcác phòng học hiện tại
1.2 Tình hình nghiên cứu trên thực tế.
Hiện nay trên thị trường cũng đã có các sản phẩm phần mềm có tính năngtương tự hoặc một số phần mềm có tính năng như một module nhỏ của phần mềm lớphọc ảo
Farstone Virtual Class
Ưu điểm : Là một phần mềm của hãng FarStone đưa ra với mụcđích quản lý lớp học ảo gần như rất hoàn hảo, nó có thể cho phépgiảng viên và học sinh tương tác với nhau vô cùng đơn giản vàtiện lợi
Nhược điểm : giá cả của nó thì không hề dẻ chút nào với 299$
Và nó còn thiếu một tính năng đó là chức năng quay phim mànhình và Void chat trong lớp học
Remote Desktop Connection
Ưu điểm : là một phần mềm của hãng Micosoft được chạy trênWindows 7 và Windows Vista và nó là một phần mềm miễn phí,
và sử dụng được một cách linh hoạt
Nhược điểm : còn có nhiều thiếu sót đó là chỉ có chức năngremote desktop từ xa mà không hề có chức năng như giảng dạy,
Do đó phần mềm này chỉ giúp ích được không nhiều trong việcquản lý lớp học ảo Và thêm nữa là chúng ta cần phải nhớ tên củamáy Client và Password đây là việc cực kỳ bất tiện
FreeVC
Trang 13 Ưu điểm : là một phần mềm của người việt được viết bởi tác giảBùi Duy Hùng, phần mềm này đã nhận được giải thưởng phầnmềm sáng tạo của trường Đại học Công Nghiệp Hà Nội Phầnmềm này được đánh giá là tiện ích như phần mềm FarstoneVirtual Class nhưng nó là một phần mềm miễn phí và hiệu năng
và tính năng đơn giản dễ sử dụng
Nhược điểm : tuy vậy phần mềm này còn nhiều thiếu sót nhưquản lý Usb, Turn Off Computer, và một vài chức năng khác
Microsoft NetMeeting :
Ưu điểm : cũng là một phần mềm của hãng Microsoft có hỗ trợtrên Windows XP nó có thể cho phép người sử dụng dùng để tổchức hội thảo, nhìn thấy người nói chuyện với mình, hoặc có thểchia sẻ tài liệu một cách dễ dàng
Nhược điểm : tuy vậy phần mềm còn có khá nhiều vấn đề như nókhông thể xem các máy Client khi cần thiết, mà nó chỉ xem đượcdanh sách các máy Client Và một vài khuyết điểm khác như khóaUsb, quản lý các máy Client khi cần thiết
1.3 Vấn đề đặt ra của đề tài.
Dựa vào tình hình nghiên cứu các phần mềm trên thực tế chúng ta sẽ tiến hànhxây dựng lên một phần mềm hoàn hảo hơn, nhằm loại bỏ đi những khuyết điểm củacác phần mềm thực tế, và tận dụng hết các điểm mạnh của phần mềm thực tế
Ram 256 MB CPU Ce 1.8 GHz LAN network
Software
Window XP SQL Server 2005 Net framework 3.5
Trang 14LAN network LAN network
Software
Window Server 2003
SQL Server 2005 Net framework 3.5
Windows XP
.Net framework 3.5
Bảng 1 2 Cấu hình được khuyến cáo trong phòng máy.
1.3.2 Đề xuất các module
Như trong phần 1.1 và 1.2 chúng ta đã được biết mức độ cấp bách và cần thiết
phải thực hiện “Xây dựng phần mềm lớp học ảo trong mạng Lan” Do đó phần mềmcủa chúng em được đề xuất các module chính sau đây cần thiết phải thực hiện
Module chia sẻ (gồm chia sẻ tài liệu, chia sẻ màn hình, thực hiện việc trao đổithông tin bằng chat message)
Module tiện ích (gồm có Turn off computer, Disable/Enable Usb disk, Remotedesktop, và chức năng VoIP)
Trong đó có hai module chính quan trọng và cần thiết nhất cần giải quyết đó vàRemote desktop và chia sẻ màn hình Hai module này về giải thuật và cách xây dựng
là tương đối giống nhau
1.4 Mục tiêu của đề tài.
Đưa ra những giải pháp cụ thể của phần mềm để giải quyết các bất cập đãnêu
Đề xuất xây dựng một phần mềm với mục đích giúp việc học tập và giảngdạy tại lớp học trong mạng Lan trở lên dễ dàng và trực quan hơn
Xây dựng một mô hình cụ thể cho vấn đề đang nghiên cứu Và đưa mô hình
đó vào ứng dụng thực tế
1.5 Đối tượng và phương pháp nghiên cứu.
1.5.1 Đối tượng nghiên cứu
Tìm hiểu các kỹ thuật cơ bản của lập trình mạng với Socket, và .NetRemoting
Nghiên cứu về lập trình Thread, lập trình sự kiện Delegate
Tìm hiểu các kỹ thuật trong lập trình sử dụng các hàm API ứng dụng vàobài toán lập trình phần mềm lớp học ảo
Ngoài ra còn nghiên cứu lập trình xử lý ảnh trong C# trong vấn đề giảiquyết bài toán chia sẻ màn hình và điều khiển máy tính từ xa
1.5.2 Phương pháp nghiên cứu
Trang 15 Tìm hiểu các kiến thức về lập trình mạng với Socket và Net Remotingthông qua các giáo trình, các bài viết về lập trình mạng trên các diễn đàn -song song với việc tham khảo từ tài liệu của giáo viên hướng dẫn.
Tham khảo các kiến thức về lập trình xử lý ảnh, lập trình các hàm API vàThread trong sách vở cũng như trên các website
Tìm kiếm các mã nguồn mở về các mảng cần nghiên cứu trên các websitenhư codeproject.com, codeplex.com, sourceforge.net, github.com Nhằmmục đích tìm hiểu về quá trình cài đặt thuật toán xử lý cơ bản và nâng caotrên ngôn ngữ lập trình C/C++ và C#
Từng bước nghiên cứu, đánh giá và đề xuất các kỹ thuật sử dụng trong phầnmềm
Thực nghiệm dựa trên xây dựng ứng dụng và đánh giá các kết quả đã thựchiên được và những kết quả chưa thực hiện được Từ đó đưa ra các giảipháp và các triển vọng của đề tài
1.6 Dự kiến các kết quả nghiên cứu.
Hoàn thiện quá trình nghiên cứu, đưa ra một số kỹ thuật cơ bản trong quátrình lập trình mạng
Xây dựng một báo cáo cụ thể và chi tiết về các kỹ thuật lập trình Thread,API và xử lý ảnh được ứng dụng trong bài toán
Cài đặt và xây dựng một phần mềm lớp học ảo thực tế Và sau đó đánh giácác kết quả thực nghiệm
Kết luận chương.
Nội dung chương này chúng em sẽ trình bầy lý do để chọn ra đề tài, các nộidung và các mục cần thiết để nghiên cứu, đưa ra các module cần thiết phải xây dựngtrong chương trình Và đưa ra dự kiến thực hiện đề tài gồm : báo cáo và chương trìnhdemo các kết quả đã đạt được
Trang 16CHƯƠNG 2 LÝ THUYẾT CƠ SỞ 2.1 Lập trình Socket C#.
2.1.1 Socket là gì?
Socket là một phương pháp để thiết lập kết nối truyền thông giữa một chươngtrình yêu cầu dịch vụ ( client) và một chương trình cung cấp dịch vụ (server) trênmạng LAN, WAN hay Internet và đôi lúc là giữa những tiến trình ngay trong một máytính Mỗi socket có thể được xem như một điểm cuối (EndPoint) trong một kết nối
Một socket trên máy yêu cầu dịch vụ có địa chỉ mạng được cấp sẵn để “gọi”một socket trên máy cung cấp dịch vụ Một khi socket đã được thiết lập phù hợp, haimáy tính có thể trao đổi dịch vụ và dữ liệu
Socket được giới thiệu lần đầu tiên trong ấn bản UNIX - BSD 4.2 dưới dạngcá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 (WinSock), Linux và được sử dụng trong nhiều ngônngữ lập trình khác nhau: như C, C++, C#, Java, Visual Basic, Visual C++
Dữ liệu gởi và nhận bằng Socket bắt buộc phải là mảng các byte
2.1.2 Chức năng của Socket
Socket cho phép thiết lập các kênh giao tiếp mà hai đầu kênh được xác định bởihai cổng (port) Thông qua các cổng này một tiến trình có thể nhận và gởi dữ liệu vớicác tiến trình khác
Hình 2 1: Chức năng của Socket.
2.1.3 Phân loại Socket
Có các loại Socket chính là:
Socket kiểu AF_UNIX chỉ cho phép giao tiếp giữa các tiến trình trong cùngmột máy tính
Trang 17 Socket kiểu AF_INTET cho phép giao tiếp giữa các tiến trình trên nhưngmáy tính khác nhau trên mạng
Phân loại theo kiểu kết nối:
Socket hướng kết nối (TCP Socket)
Socket không hướng kết nối (UDP Socket)
2.1.4 Thành phần của một Socket
2.1.4.1 Số hiệu cổng (port number)
Để có thể thực hiện các cuộc giao tiếp, một trong hai tiến trình phải cho biết 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 một hệ thống Khi tiến trình được gán một số hiệu cổng (Server), nó có thểnhận dư liệu gởi đến cổng này từ tiến trình khác (Client) Tiến trình còn lại cũng 8 yêucầu tạo ra một socket
2.1.4.2 Địa chỉ IP
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 Trongkhi 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 thì
IP dùng để phân biệt các máy tính khác nhau trên cùng một mạng TCP/IP
Hình 2 2 Sơ đồ giao tiếp các máy tính khác nhau.
Trong hình trên, địa chỉ của tiến trình B1 được xác định bằng 2 thông tin: (Host
Trang 182.1.5 Các chế độ giao tiếp
Xét kiến trúc của hệ thống mạng TCP/IP:
Hình 2 3: Các chế độ giao tiếp các tầng mạng khác nhau.
Tầng vận chuyển (Transport Layer) giúp chuyển tiếp các thông điệp giữa cácchương trình với nhau Nó có thể hoạt động theo hai chế độ:
Giao tiếp có nối kết, nếu giữa chúng sử dụng giao thức TCP
Giao tiếp không kết nổi, nếu sử dụng giao thức UDP
Socket là giao diện giữa chương trình và lớp vận chuyển Nó cho phép ta chọngiao thức sử dụng ở tầng vận chuyển là TCP hay UDP cho chương trình ứng dụng củamình
Bảng so sánh sự khác biện giữa hai chế độ giao tiếp có kết nối và không kết nối.
- 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 bảo đảm: có
kiểm tra lỗi, truyền lại gói tin lỗi hay mất,
đảm báo thứ tự của các gói tin
- Dữ liệu chính xác nhưng tốc độ truyền
- Dữ liệu không chính xác, tốc độ truyền nhanh
2.1.6 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 Server Các ứng dụng trên Internet như Web, Mail, FTP là các ví dụ điển hình
Trang 19Client-Chúng ta sẽ tìm hiểu về các bước cơ bản trong việc xây dựng các ứng dụngClient-Server sử dụng Socket làm phương tiện giao tiếp theo chế độ hướng kết nối(được ứng dụng trong phần gởi file và gởi hình ảnh trong chương trình).
2.1.6.1 Mô hình Client-Server sử dụng Socket ở chế độ có kết nối (TCP)
Giai đoạn 1: Server tạo Socket, gán số hiệu cổng và lắng nghe các kết nối.
Hình 2 4 Minh họa quá trình khởi tạo TCP Socket Server.
Socket() : Server yêu cầu tạo ra một Socket để có thể sử dụng các dịch vụcủa tầng vận chuyển
Bind() : Socket khi được tạo ra cần phải được gắn vào một port cục bộ
Listen() : Server lắng nghe các yêu cầu kết nối từ Client trên cổng đã đượcgán
Giai đọan 2: Client tạo Socket, yêu cầu thiết lập một nối kết với Server
Hình 2 5 Mô tả quá trình khởi tạo TCP Socket Client kết nối tới Server.
Socket() : Client yêu cầu tạo một Socket để có thể sử dụng dịch vụ của tầngvận chuyển, thông thường hệ thống thường tự động gán một port còn dảnhcho Socket của Client Nhưng ở đây ta sẽ tự động đưa vào port cho Socketcủa Client
Connect() : Client gửi yêu cầu kết nối tới Server có địa chỉ ip và port xácđịnh
Trang 20 Accept() : Sau khi bên phía Client kết nối tới Server thì Server sẽ chấp nhậnkết nối 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 giao tiếp ảo này.
Giai đoạn 3: Trao đổi thông tin giữa Client và Server
Hình 2 6 Mô tả quá trình truyền nhận thông tin giữa Server và Client.
Sau khi chấp nhận yêu cầu kết nối, Server đợi Client gửi yêu cầu đến Ở đâyClient sẽ sử dụng hàm Send() gửi lần lượt các byte dữ liệu
Server phân tích và thực thi yêu cầu Kết quả và nó gửi lại dữ liệu cho Clientbằng lệnh Send()
Trong giai đoạn này, việc trao đổi thông tin giữa Server và Client phải tuânthủ theo giao thức ứng dụng Thông thường thì Client sẽ là bên gửi yêu cầuđến Server trước
Giai đoạn 4: Kết thúc phiên làm việc.
Hình 2 7 Mô tả kết thúc phiên làm việc giữa Client và Server.
Việc trao đổi dữ liệu giữa Server và Client được thực hiện nhiều lần
Kênh ảo sẽ bị xóa khi Server hoặc Client đóng Socket bằng lệnh Close().2.1.6.2 Mô hình Client-Server sử dụng Socket ở chế độ không kết nối (UDP)
Trang 21UDP là giao thức theo phương thức không liên kết được sử dụng thay thế choTCP Nó khác với TCP, không có chức năng thiết lập liên kết và kết thúc liên kết Dovậy việc trao đổi thông tin dữ liệu là không đáng tin cậy.
Các giai đoạn thực hiện của Socket không hướng kết nối
Giai đoạn 1: Server tạo ra Socket và gán số hiệu cổng.
Hình 2 8 Mô tả quá trình khởi tạo UDP Socket Server.
Socket(): Server yêu cầu tạo ra một Socket để sử dụng các dịch vụ của tầngvận chuyển
Bind(): Sau khi đã khởi tạo Socket thì cần phải gắn một port cục bộ cho nó
Giai đoạn 2: Client tạo Socket.
Hình 2 9 Mô tả quá trình khởi tạo UDP Socket Client.
Bên phía Client sẽ yêu cầu tạo ra một Socket để sử dụng dịch vụ của tầngvận chuyển
Sau đó Client có thể Send dữ liệu tới một địa chỉ ip và port cục bộ củaServer
Giai đoạn 3: Trao đổi thông tin giữa Client và Server
Trang 22Hình 2 10 Mô tả quá trình truyền nhận dữ liệu bằng UDP.
Client và Server có thể trao đổi thông tin với nhau nhiều lần qua hai hàm đó
2.1.7.1 Lớp NetworkStream
Lớp này được nằm trong thư viện System.Net.Socket Lớp NetworkStream cóthể được tạo lập bằng nhiều phương thức khác nhau, nhưng một phương thức tạo lập
mà ta hay sử dụng đó là gán vào Socket của Server và Client đã được tạo lập sẵn
Socket newsock = new Socket ( AddressFamily InterNetwork, SocketType Stream, ProtocolType Tcp);
NetworkStream ns = new NetworkStream (newsock);
Một số phương thức của lớp NetworkStream
DataAvailable() true nếu có dữ liệu để đọc
BeingWrite() Bắt đầu ghi NetworkStream bất đồng bộ
Trang 23EndWrite() Kết ghi đọc NetworkStream bất đồng bộ
Bảng 2 1 Một số phương thức của lớp NetworkStream
Chú ý : Phương thức Flush() được dùng sau mỗi phương thức Write() để đảmbảo dữ liệu được đặt vào NetworkStream sẽ lập tức gửi đến hệ thống ở xa
NetworkStream khi truyền dữ liệu cũng có gặp một số vấn đề về biên dữ liệu.Vấn đề này đã được giải quyết với hai lớp StreamReader và lớp StreamWriter.2.1.7.2 Lớp StreamReader và StreamWriter
Hai lớp này nằm trong thư viện System.IO để điều khiển đọc và ghi các thôngđiệp text từ mạng Cả hai lớp đều triển khai với đối tượng NetworkStream để xác địnhcác hệ thống đánh dấu cho thông điệp TCP
Các phương thức tạo lập lớp StreamRead và StreamWriter, trong đó mộtphương thức tạo lập mà ta hay được sử dụng nhất đó là gắn hai lớp trên vào lớpNetworkStream đã được tạo lập từ trước
Socket newsock = new Socket(AddressFamily InterNetwork , SocketType Stream , ProtocolType Tcp )
NetworkStream ns = new NetworkStream( newsock )
StreamReader nr = new StreamReader( ns )
StreamWriter nw = new StreamWriter( ns )
Một số phương thức của lớp StreamRead
StreamReader
Không gỡ bỏ nó khỏi Stream
StreamRead trở lên cho tới khi bắt gặp ký tựxuống dòng đầu tiên
Trang 24ToString() Tạo ra một chuỗi mô tả đối tượng Stream.
Bảng 2 2 Một số phương thức lớp StreamRead
Một số phương thức của lớp StreamWriter
Lớp StreamWriter cũng có nhiều phương thức kết hợp với nó, một số phương thức củalớp StreamRead cũng có trong đối tượng StreamWriter, ngoài ra nó còn có một số phươngthức giêng dưới đây
StreamWriter ra Stream
WriterLine() Gửi dữ liệu cùng với ký tự xuống dòng ra
2.1.8.1.TCPClient
TCPClient được thiết kế nhằm hỗ trợ cho việc viết các ứng dụng TCP Clientđược dễ dàng
Bảng các thành viên của lớp TCPClient
Phương thức khởi tạo Mô tả
TcpClient() Tạo một đối tượng TcpClient Chưa đặt thông số gì
TcpClient(IPEndPoint
)
Tạo một TcpClient và gắn cho nó một EndPoint cục bộ.(Gán địa chỉ máy cục bộ và số hiệu cổng để sử dụngtrao đổi thông tin về sau)
TcpClient(String,Int32
)
Tạo một đối tượng TcpClient và kết nối đến một máy cóđịa chỉ và số hiệu cổng được truyền vào RemoteHost cóthể là địa chỉ IP chuẩn hoặc tên máy
Các thuộc tính Mô tả
Available Cho biết số byte đã nhận về từ mạng và có sẵn để đọc
Trang 25Connected Trạng thái cho biết đã kết nối được đến Server hay
Kết nối đến một máy TCP khác có Tên và số hiệu cổng
GetStream() Trả về NetworkStream để từ đó giúp ta gửi hay nhận dữ
liệu (Thường làm tham số khi tạo StreamReader vàStreamWriter để gửi và nhận dữ liệu dưới dạng xâu kýtự)
Khi đã gắn vào StreamReader và StreamWriter rồi thì ta
có thể gửi và nhận dữ liệu thông qua các phương thứcReadline, writeline tương ứng của các lớp này
Bảng 2 4 Các thành viên của lớp TCPClient.
Từ các thành viên của lớp TcpClient ở trên ta thấy rằng, việc kết nối và thựchiện gửi nhận rất đơn giản Theo các trình tự sau:
Bước 1: Tạo một đối tượng TcpClient
Bước 2: Kết nối đến máy chủ (Server) dùng phương thức Connect.
Bước 3: Tạo 2 đối tượng StreamReader (Receive)và StreamWriter
(Send) và "nối" với GetStream của TCPClient.
Bảng các thành viên của lớp TCPListener
Trang 26Phương thức khởi tạo Mô tả
TcpListener ( Int32) Tạo một TcpListener và lắng nghe tại cổng chỉ
AcceptSocket( ) Chấp nhận một yêu cầu kết nối đang chờ
AcceptTcpClient() Chấp nhận một yêu cầu kết nối đang chờ (Ứng
dụng sẽ dừng tại lệnh này cho đến khi nào cómột kết nối đến – “Blocking”)
Pending() Cho biết liệu có kết nối nào đang chờ đợi khôngStart() Bắt đầu lắng nghe các yêu cầu kết nối
Bảng 2 5 Các phương thành viên của lớp TCPListener.
2.1.8.3 UDPClient
Giao thức UDP (User Datagram Protocol hay User Define Protocol) là một giaothức phi kết nối (connectionless) có nghĩa là một bên có thể gửi dữ liệu cho bên kia màkhông cần biết là bên đó đã sẵn sàng hay chưa? (Nói cách khác là không cần thiết lậpkết nối giữa hai bên khi tiến hành trao đổi thông tin) Giao thức này không tin cậybằng giao thức TCP nhưng tốc độ lại nhanh và dễ cài đặt Ngoài ra, với giao thức UDP
ta còn có thể gửi các gói tin quảng bá (Broadcast) cho đồng thời nhiều máy
Trong NET, lớp UDPClient (nằm trong namesapce System.Net.Sockets) đónggói các chức năng của giao thức UDP
Bảng các thành viên của lớp UDPClient
Phương thức khởi tạo Mô tả
UdpClient () Tạo một đối tượng (thể hiện) mới của lớp
UDPClient
UdpClient (AddressFamily) Tạo một đối tượng (thể hiện) mới của lớp
UDPClient Thuộc một dòng địa chỉ(AddressFamily) được chỉ định
UdpClient (Int32) Tạo một UdpClient và gắn (bind) một cổng cho nó.UdpClient (IPEndPoint) Tạo một UdpClient và gắn (bind) một IPEndpoint
(gán địa chỉ IP và cổng) cho nó
Trang 27BeginReceive() Nhận dữ liệu Không đồng bộ từ máy ở xa
BeginSend() Gửi không đồng bộ dữ liệu tới máy ở xa
Connect() Thiết lập một Default remote host
EndReceive() Kết thúc nhận dữ liệu không đồng bộ ở trên
EndSend() Kết thúc việc gửi dữ liệu không đồng bộ ở trên
Receive (ref IPEndPoint) Nhận dữ liệu (đồng bộ) do máy ở xa gửi (Đồng bộ
có nghĩa là các lệnh ngay sau lệnh Receive chỉđược thực thi nếu Receive đã nhận được dữ liệu
về Còn nếu nó chưa nhận được – dù chỉ một chút– thì nó vẫn cứ chờ (blocking))
Send() Gửi dữ liệu (đồng bộ) cho máy ở xa
Bảng 2 6 các thành viên của lớp UDPClient.
2.1.9 Lập trình Socket bất đồng bộ
Ở phần đầu của báo cáo chúng ta đã lập trình Socket trong chế độ blocking.Socket blocking sẽ chờ mãi cho đến khi hoàn thành nhiệm vụ của nó Trong khi nó bịblocking thì các chức năng khác của chương trình không thực hiện được
Khi lập trình Windows thì lúc gọi một phương thức bị blocking thì toàn bộchương trình sẽ đứng lại và không thể thực hiện các chức năng khác được Do đó việclập trình bất đồng bộ là cần thiết để cho chương trình khỏi bị treo
Lớp AsyncCallback cung cấp các phương thức để bắt đầu một chức năng bấtđồng bộ và cung cấp một phương thức delegate để gọi chức năng bất đồng bộ kết thúc
Các phương thức bất đồng bộ trong Socket chia các chức năng mạng làm haiphần
Một phương thức Begin bắt đầu các chức năng mạng và đăng ký phươngthức AsyncCallback
Một phương thức End hoàn thành chức năng mạng khi phương thứcAsyncCallback được gọi
Trang 28BeginConnect() Kết nối đến thiết bị ở xa EndConnect()
BeginReceive() Nhận dữ liệu từ Socket EndReceive()
BeginReceiveFrom() Nhận dữ liệu từ thiết bị ở xa EndReceiveFrom()
BeginSend() Gửi dữ liệu từ Socket EndSend ()
BeginSendTo() Gửi dữ liệu đến thiết bị ở xa EndSendTo()
Bảng 2 7 Các phương thức của lập trình Socket bất đồng bộ.
2.1.9.1 Thành lập kết nối
Phương thức dùng để thành lập kết nối với thiết bị ở xa phụ thuộc vào chươngtrình đóng vai trò là Server hay Client Nếu là Server thì phương thức BeginAccept()được dùng, còn bên Client thì phương thức BeginConnect() được sử dụng
Phương thức BeginAccept() và EndAccept()
Server.BeginAccept( new AsyncCallback (CallAccept), Server);
Socket s = (Socket)ia.AsyncState;
Server = s.EndAccept(ia);
Sau khi phương thức BeginAccept() kết thúc, phương thức AsyncCallback địnhnghĩa sẽ được gọi khi kết nối xảy ra Phương thức AsyncCallback phải bao gồmphương thức EndAccept() để kết thúc việc chấp nhận Socket Sau đây là định dạng củaphương thức EndAccept()
Phương thức Beginconnect() và EndConnect()
_clientsocket.BeginConnect(_ipep,
new AsyncCallback (CallPConnect), _clientsocket);
_clientsocket.EndConnect(ia);
2.1.9.2 Trao đổi dữ liệu
Sau khi Server và Client đã thiết lập kết nối, ta có thể thực hiện việc trao đổi dữliệu giữa Server và Client
Phương thức BeginSend() và EndSend()
_ServerSocket.BeginSend(data, 0, data.Length, SocketFlags None, new AsyncCallback (SendcmdMessage), _ServerSocket);
Socket s = ( Socket ) ia.AsyncState;
Trang 29.Net Remoting là cơ chế giao tiếp giữa các đối tượng (object) mà không cùngthuộc một Process Giúp các lớp đối tượng thuộc các ứng dụng khác nhau có thể liênlạc được với nhau Các đối tượng của các ứng dụng này có thể được thiết lập trên cùngmột máy tính hay các máy tính khác nhau và được giao tiếp từ xa thông qua các giaothức kết nối như HTTP,TCP.
Microsft .Net Remoting được giới thiệu từ .Net Framework 1.1 cùng vớiWebservice Cung cấp các kĩ thuật cho phép một đối tượng này truy xuất đến một đốitượng khác nằm ở các Application Domain khác nhau
Hình 2 11 Mô hình trao đổi thông tin của Net Remoting.
2.2.2 Remote Objects trong NET Remoting
Nếu như ở một chương trình đơn thì các đối tượng sẽ cùng thuộc trong ứngdụng đó, và chúng dễ dàng giao tiếp được với nhau; đây có thể được coi là LocalObjects Tuy nhiên nếu các đối tượng lại thuộc những ứng dụng khác nhau (cácApplication domain khác nhau) thì cần có những Remote Object để giao tiếp với nhau.Remote Object có thể được dẫn xuất từ MarshalByRefObject hay sử dụng
[Serializable] tag hoặc bằng cách tạo các giao diện ISerializable
Các loại Remote Object:
Trong NET Remoting, có hai cơ chế để tạo instance của Remote Object rồi từ
đó thực thi request Đó là Singleton và Singlecall Tùy vào mục đích sử dụng, nhu cầucủa ứng dụng mà server có thể khai báo theo cơ chế
WellKnownObjectMode.SingleCall, hay WellKnownObjectMode.Singleton
Single Call Object: Remote Object sẽ được sinh ra, thực thi request, trảlời cho client, sau đó Object này vẫn được lưu lại chứ không bị hủy đi.Đến khi nào process chạy chương trình Server kết thúc thì instance nàymới bị trình hốt rác Garbage Collection hốt đi
Trang 30 Singleton Object: Ngược lại với Single Call, khi khai báo Remote Object
là Singleton thì Remote Object sẽ được khởi tạo và hủy đi đối với mỗilần nhận request từ phía Client Cơ chế này tương tự như mô hình NETWebservice truyền thống
Client-Activated Objects (CAO): Thuộc kiểu “Server-side object”,chúng chỉ được kích hoạt mỗi khi có request đến từ Client Khi mộtClient gửi một request tới Server sử dụng toán tử “new”, một thông điệp
sẽ được gửi tới Remote Application Server sau đó sẽ tạo ra một Instancecủa lớp được yêu cầu, và trả về một ObjRef cho Client Application.2.2.3.Domain
Trong NET, khi một ứng dụng được nạp vào trong bộ nhớ, một tiến trình đượctạo ra, và trong quá trình này, một miền ứng dụng (Application Domain) cũng đượctạo ra Trên thực tế, ứng dụng này sẽ được nạp vào Application Domain Mỗi ứngdụng có thuộc các Application Domain khác nhau, vì thế nếu chúng muốn giao tiếpđược với nhau thì phải sử dụng Remoting chứ không thể giao tiếp trực tiếp với nhauđược Các Application Domain có thể cùng thuộc một process hoặc khác process
2.2.4.Channel
Trong kỹ thuật Net Remoting thì Channel được hiểu như là một kênh để giaotiếp giữa Client và Server Một Object từ Client sẽ thông qua Channel để giao tiếp vớiObject phía Server, Channel sẽ truyền tải những Message từ hai phía Như giới thiệuphía trên thì có hai Channel chính là TcpChannel và HttpChannel tương ứng với cácgiao thức TCP và HTTP Ngoài ra, TcpChannel và HttpChannel đều có khả năngExtend thành những Custom Channel
Các nguyên tắc khi thiết lập một Channel
Cần có ít nhất một Channel được đăng ký với NET Remoting trước khiRemote Object được gọi Và các Channels này cần đăng ký trước cácRemote Object
Channel được đăng ký trong mỗi Application Domain hoặc nhiềuApplication Domain thuộc một Process Khi Process kết thúc thì cácChannel này cũng tự động được hủy đi
Không thể đăng ký các Channel khác nhau trên cùng một port thuộccùng một máy tính mặc dù các Channel này có thể ở các ApplicationDomai khác nhau Khi thiết lập nhiều Channel trên cùng một máy tínhthì chúng cần listen ở các port khác nhau
Client liên lạc với Remote Object thông qua các kênh đã đăng ký bằngviệc gọi các RegisterChannel trên lớp ChannelService
2.2.5 Object Activation
Trang 31Server Actived Object chỉ được tạo ra ở lần đầu tiên Client thiết lập cuộc gọi tớicác Remote Method Hay nói cách khác, Khi một Client yêu cầu tạo ra các RemoteObject thì chỉ các proxy cục bộ được tạo ra ở Client, còn Remote Object thực tế nằmtrên Server Các Remote Object này sẽ được khởi tạo ở lần đầu tiên Client thiếp lậpcuộc gọi cho Server Ví dụ tạo ra các Proxy như sau.
2.2.6 Client Activated Objects
Đối tượng Client Activated Object được tạo ra mỗi trên Server ngay lập tức mỗikhi có request từ Client hoặc cũng có thể tạo ra bằng từ khóa new hoặc
Trang 32 Singleton object được dùng để tham chiếu đến những đối tượng cùngtrên một server, và bất kỳ thay đổi của Client cũng sẽ “visible” (hiệnhữu) với những Client khác Ví dụ như trong hệ điều hành Windows, khimột chương trình thay thì các Client Program khác cũng biết được Dữliệu sẽ được lưu trên máy chủ và được truy cập bởi tất cả các Client.
Chúng ta sử dụng SingleCall khi muốn cung cấp một môi trường
“stateless” (Kiểu giống của Web services truyền thống
Chúng ta sử dụng Client Activation nếu đối đượng cần phải được duy trìtrạng thái kết nối liên tục, trao đổi thông tin với các client khác
2.2.7 Tạo một Remotable Object
Một Remote Object là một đối tượng được kế thừa từ lớp MarshalByRefObject.Trong C#, khi tạo một lớp thư viện mới Ta Add thêm lớp có tênMarshalByRefObject như đã nói ở trên Khai báo using System.Runtime.Remoting để
có thể sử dụng được các TcpChannel hay HttpChannel
2.3 Lập trình sự kiện trong Windows.
Trong lập trình sự kiện của Windows, mỗi khi sự kiện sảy ra, một phương thứcđược gọi để thực thi dựa trên sự kiện đó như trong hình dưới đây
Trang 33Hình 2 12 Lập trình sự kiện trong Windows.
2.3.1 Sử dụng Event và Delegate
Evetn là một thông điệp được gửi bởi một đối tượng mô tả một hoạt động mà
nó diễn ra Thông điệp này xác định hoạt động và truyền các dữ liệu cần thiết cho hoạtđộng Event có thể mô tả hoạt động nào đó, chẳng hạn như hoạt động click mộtButton, hoạt động nhận và gửi dữ liệu trên Socket Event sender không cần thiết phảibiết đối tượng nào sẽ điều khiển thông điệp sự kiện mỗi khi nó được gửi thông qua hệthống Windows Nó để cho bộ phận sự kiện đăng ký với hệ thống Windows và thôngbáo kiểu sự kiện mà bộ phận nhận sự kiện muốn nhận như hình minh họa sau
Hình 2 13 Gửi và nhận sự kiện trong Windows.
Bộ nhận sự kiện được xác định trong hệ thống Windows bởi một con trỏ lớpđược gọi là Delegate Một Delegate là một lớp nó giữ tham chiếu đến một phươngthức mà phương thức này điều khiển sự kiện được nhận Khi hệ thống Windows nhận
sự kiện, nó kiểm tra xem thử có Delegate nào đăng ký để xử lý nó không Nếu cóDelegate đăng ký để sử lý sự kiện, thông điệp sự kiện được truyền vào phương thứcđược định nghĩa bởi Delegate Sau khi phương thức hoàn tất, hện thống Windows sẽ
xử lý sự kiện tiếp theo xảy ra cho tới khi sự kiện kết thúc chương trình được phát ra
Trang 342.4 Lập trình đa luồng.
2.4.1 Khái niệm đa luồng (Thread)
Một luồng (Thread) là một chuỗi liên tiếp những sự thực thi trong chương
trình Trong một chương trình C#, việc thực thi bắt đầu bằng phương thức main() vàtiếp tục cho đến khi kết thúc hàm main() Cấu trúc này rất hay cho những chương trình
có một chuỗi xác định những nhiệm vụ liên tiếp Nhưng thường thì một chương trìnhcần làm nhiều công việc hơn vào cùng một lúc Ví dụ trong Internet Explorer khi tađang tải một trang web thì ta nhấn nút back hay một link nào đó, để làm việc nàyInternet Explorer sẽ phải làm ít nhất là 3 việc:
Lấy dữ liệu được trả về từ Internet cùng với các tập tin đi kèm
Thể hiện trang Web
Xem người dùng có nhập để làm thứ gì khác không
Để đơn giản vấn đề này ta giả sử Internet Explorer chỉ làm hai công việc:
Trình bày trang Web
Xem người dùng có nhập gì không
Để thực hành việc này ta sẽ viết một phương thức dùng để lấy và thể hiện trangWeb Giả sử rằng việc trình bày trang Web mất nhiều thời gian (do phải thi hành cácđoạn javascript hay các hiệu ứng nào đó …) Vì vậy sau một khoảng thời gian ngắnkhoảng 1/12 giây, phương thức sẽ kiểm tra xem người dùng có nhập gì không Nếu cóthì nó sẽ đuơc xử lí, nếu không thì việc trình bày trang sẽ được tiếp tục Và sau 1/12giây việc kiểm tra sẽ được lặp lại Tuy nhiên viết phương thức này thì rất phức tạp do
đó ta sẽ dùng kiến trúc event trong Window nghĩa là khi việc nhập xảy ra hệ thống sẽthông báo cho ứng dụng bằng cách đưa ra một event Ta sẽ cập nhật phương thức đểcho phép dùng các event:
Ta sẽ viết một bộ xử lí event để đáp ứng đối với việc nhập của ngườidùng
Ta sẽ viết một phương thức để lấy và trình bày dữ liệu Phương thức nàyđược thực thi khi ta không làm bất cứ điều gì khác
Ta hãy xem cách phương thức lấy và trình bày trang web làm việc: đầu tiên nó
sẽ tự định thời gian Trong khi nó đang chạy, máy tính không thể đáp ứng việc nhậpcủa người dùng Do đó nó phải chú ý đến việc định thời gian để gọi phương thức kiểmtra việc nhập của người dùng, nghĩa là phương thức vừa chạy vừa quan sát thời gian.Bên cạnh đó nó còn phải quan tâm đến việc lưu trữ trạng thái trước khi nó gọi phươngthức khác để sau khi phương thức khác thực hiện xong nó sẽ trả về đúng chỗ nó đãdừng Vào thời Window 3.1 đây thực sự là những gì phải làm để xử lí tình huống này.Tuy nhiên ở NT3.1 và sau đó là Windows 95 trở đi đã có việc xử lí đa luồng điều nàylàm việc giải quyết vấn đề tiện lợi hơn Dưới đây chúng ta sẽ tìm hiểu một vài lớp cơ
Trang 35bản trong ngôn ngữ lập trình C# và vấn đề đồng bộ hóa (Synchronization) trong lậptrình đa luồng.
2.4.2 Tham khảo thư viện System.Thread
Namespace System.Threading cung cấp một số kiểu dữ liệu cho phép bạn thựchiện lập trình đa luồng Ngoài việc cung cấp những kiểu dữ liệu tượng trưng cho mộtluồng cụ thể nào đó, namespace này còn định nghĩa những lớp có thể quản lý mộtcollection các luồng (ThreadPool), một lớp Timer đơn giản (không dựa vào GUI) vàcác lớp cung cấp truy cập được đồng bộ vào dữ liệu được chia sẽ sử dụng
Các lớp thành viên Mô tả
Interlocked Lớp này dùng cung cấp truy cập đồng bộ hóa vào dữ liệu được chia
sẽ sử dụng (shared data)
Moniter Lớp này cung cấp việc đồng bộ hóa các đối tượng luồng sử dụng
khóa chốt (lock) và tín hiệu chờ (wait signal)
Mutex Lớp này cung cấp việc đồng bộ hóa sơ đẳng có thể được dùng đối
với inter process synchronization
Thread Lớp này tượng trưng cho một luồng được thi hành trong lòng
Common Language Runtime Sử dụng lớp này bạn có khả năng bổsung những luồng khác trong cùng AppDomain
ThreadPool Lớp này quản lý những luồng có liên hệ với nhau trong cùng một
Process nào đó
Timer Cho biết một delegate có thể được triệu gọi vào một lúc được khai
báo nào đó Tác vụ wait được thi hành bởi luồng trong thread pool.WaitHandle Lớp này tượng trưng cho tất cả các đối tượng đồng bộ hóa (cho
phép multiple wait) vào lúc chạy
ThreadStart Lớp này là một delegate chỉ về hàm hành sự nào đó phải được thi
hành đầu tiên khi một luồng bắt đầu
TimerCallBack Delegate đối với Timer
WaitCallBack Lớp này là một delegate định nghĩa hàm hành sự kêu gọi lại
(callback) đối với ThreadPool user work item
Bảng 2 8 Một số lớp thuộc tính của thư viện System.Thread.
2.4.2 Lớp Thread
Lớp đơn giản nhất trong tất cả các lớp thuộc Namespace System.Threading làlớp Thread Lớp này tượng trưng cho một vỏ bọc hướng đối tượng bao quanh một lộtrình thi hành trong lòng một AppDomain nào đó Lớp này định nghĩa một số hàmthực thi (cả static lẫn shared) cho phép bạn tạo mới những luồng từ luồng hiện hành,cũng như cho Sleep, Stop hay Kill một luồng nào đó
Các thành phần Static Mô tả
Trang 36CurrentThread Thuộc tính read-only này trả về một quy chiếu về luồng hiện
đang chạy
GetData() Đi lấy vị trí từ slot được khai báo trên luồng hiện hành đối với
domain hiện hành trong luồng
SetData() Cho đặt để trị lên slot được khai báo trên luồng hiện hành đối
với domain hiện hành trong luồngGetDomain()
GetDomainID()
Đi lấy một qui chiếu về AppDomain hiện hành (hoặc mã nhậndiện ID của domain này) mà luồng hiện đang chạy trên đó.Sleep() Cho ngưng luồng hiện hành trong một thời gian nhất định được
khai báo
Bảng 2 9 Các thành phần static của lớp Thread.
Ngoài ra lớp Thread cũng hỗ trợ các thành viên cung cấp đối tượng
Các lớp thành viên Mô tả
IsAlive Thuộc tính này trả về một trị boolean cho biết liệu xem luồng đã
khởi đông hay chưa
IsBackground Đi lấy hoặc đặt để giá trị cho biết liệu xem luồng là một luồng nền
hay không
Name Thuộc tính này cho phép bạn thiết lập một tên văn bản mang tính
thân thiện đối với luồng
Priority Đi lấy hoặc đặt để ưu tiên của một luồng Có thể được gán một trị
lấy từ enumeration ThreadPriority (chẳng hạn Normal, Lowest,Highest, BelowNormal, AboveNormal)
ThreadState Đi lấy hoặc đặt để tình trạng của luồng Có thế được gán từ
enumeration ThreadState (chẳng hạn Unstarted, Running,WaitSleepJoin, Suspended, SuspendRequested, AbortRequested,Stopped)
Interrup() Cho ngưng chạy luồng hiện hành
Join() Yêu cầu luồng chờ đối với luồng bị ngưng chạy
Resume() Tiếp tục lại đối với một luồng bị ngưng chạy
Start() Cho bắt đầu thi hành luồng được khai báo bởi delegate ThreadStart.Suspend() Cho ngưng chạy một luồng Nếu luồng đã bị ngưng rồi, một triệu
gọi hàm Suspend() sẽ không có tác dụng
Bảng 2 10 Các thành viên cấp đối tượng của lớp Thread.
2.4.3 Thao tác với luồng
Trang 37Luồng được thao tác bằng cách dùng lớp Thread nằm trong thư việnSystem.Threading Một thể hiện của luồng đại diện cho một luồng Ta có thể tạo cácluồng khác bằng cách khởi tạo một đối tượng Thread.
Giả sử rằng ta đang viết 1 trình biên tập hình ảnh đồ hoạ, và người dùng yêucầu thay đổi độ sâu của màu trong ảnh Ta bắt đầu khởi tạo một đối tượng luồng nhưsau:
// entryPoint được khai báo trước là 1 delegate kiểu ThreadStart
Thread depthChangeThread = new Thread (entryPoint);
Đoạn mã trên biểu diễn một hàm khởi tạo của Thread với một thông số chỉ địnhđiểm nhập của một luồng Đó là phương thức nơi luồng bắt đầu thi hành Trong tìnhhuống này ta dùng thông số là delegate, một delegate đã được định nghĩa trongSystem.Threading gọi là ThreadStart, chữ kí của nó như sau:
public delegate void ThreadStart ();
Thông số ta truyền cho hàm dựng phải là 1 delegate kiểu này Ta bắt đầu luồngbằng cách gọi phương thức Thread.Start(), giả sử rằng ta có phương thức ChanColor():
void ChanColor()
{
// xử lí để thay đổi màu
}
Sắp xếp lại ta có đoạn mã sau
ThreadStart entryPoint = new ThreadStart (ChangeColorDepth);
Thread depthChangeThread = new Thread (entryPoint);
depthChangeThread.Name = “Depth Change Thread”;
depthChangeThread.Start();
Sau điểm này, cả hai luồng sẽ chạy đồng bộ với nhau
Trong đoạn mã này ta đăng kí tên cho luồng bằng cách dùng thuộc tínhThread.Name Không cần thiết làm điều này nhưng nó có thể hữu ích
Lưu ý vì điểm đột nhập vào luồng (trong ví dụ này là ChanColor() ) không thểlấy bất kì thông số nào Ta sẽ phải tìm một cách nào đó để truyền thông số cho phươngthức nếu cần Cách tốt nhất là dùng các trường thành viên của lớp mà phương thức này
là thành viên Cũng vậy phương thức không thể trả về bất cứ thứ gì
Mỗi lần ta bắt đầu một luồng khác, ta cũng có thể đình chỉ, hồi phục hay bỏ qua
nó Đình chỉ nghĩa là cho luồng đó ngủ (sleep) - nghĩa là không chạy trong 1 khoảngthời gian Sau đó nó thể đưọc phục hồi, nghĩa là trả nó về thời diểm mà nó bị định chỉ.Nếu luồng đưọc bỏ, nó dừng chạy Window sẽ huỷ tất cả dữ liệu mà liên hệ đến luồng
đó, để luồng không thể được bắt đầu lại Tiếp tục ví dụ trên, ta giả sử vì lí do nào đó
Trang 38luồng giao diện người dùng trình bày một hộp thoại cho người dùng cơ hội để đình chỉtạm thời sự đổi tiến trình Ta sẽ soạn mã đáp ứng trong luồng main :
ThreadAbortException là một lớp biệt lệ đặc biệt mà không bao giờ được xử lí.Nếu luồng đó thực thi mã bên trong khối try, bất kì khối finally sẽ được thực thi trướckhi luồng bị huỷ Sau khi huỷ luồng ta có thể muốn đợi cho đến khi luồng thực sự bịhuỷ trước khi tiếp tục luồng khác ta có thể đợi bằng cách dùng phương thức join():
depthChangeThread.Abort();
depthChangeThread.Join();
Join() cũng có một số overload khác chỉ định thời gian đợi Nếu hết thời giannày việc thi hành sẽ được tiếp tục Nếu một luồng chính muốn thi hành một vài hànhđộng trên nó, nó cần một tham chiếu đến đối tượng luồng mà đại diện cho luồng riêng
Nó có thể lấy một tham chiếu sử dụng thuộc tính static -CurrentThread- của lớpThread:
Thread myOwnThread = Thread CurrentThread;
Có hai cách khác nhau mà ta có thể thao tác lớp Thread:
Ta có thể khởi tạo một đối tượng luồng, mà sẽ đại diện cho luồng đangchạy và các thành viên thể hiện của nó áp dụng đến luồng đang chạy
Ta có thể gọi một số phương thức static, những phương thức này sẽ ápdụng đến luồng mà ta thực sự đang gọi phương thức từ nó Một phươngthức static mà ta muốn Sleep(), đơn giản đặt luồng đang chạy ngủ mộtkhoảng thời gian, sau đó tiếp tục
2.4.4 Đồng bộ hóa (Synchronization) trong lập trình đa luồng
2.4.4.1 Đồng bộ hóa
Đôi khi có thể bạn muốn điều khiển việc truy cập vào một nguồn lực, chẳng hạncác thuộc tính hoặc các hàm của một đối tượng, làm thế nào chỉ một mạch trình đượcphép thay đổi hoặc sử dụng nguồn lực đó mà thôi Việc đồng bộ hóa được thể hiệnthông qua một cái khóa được thiết lập trên đối tượng, ngăn không cho luồng nào đótruy cập khi mạch trình đi trước chưa xong công việc
Trang 39Trong phần này, ta sẽ là quen với cơ chế đồng bộ hóa mà Common LanguageRuntime cung cấp: lệnh lock Nhưng trước tiên, ta cần mô phỏng một nguồn lực đượcchia sẽ sử dụng bằng cách sử dụng một biến số nguyên đơn giản: counter
Để bắt đầu, ta khai báo biến thành viên và khởi gán về zero:
int counter = 0;
Bài toán được đặt ra ở đây như sau: luồng thứ nhất sẽ đọc trị counter (0) rồi gángiá trị này cho biến trung gian (temp) Tiếp đó tăng trị của temp rồi Sleep một khoảngthời gian Luồng thứ nhất xong việc thì gán trị của temp trả về cho counter và cho hiểnthị trị này Trong khi nó làm công việc, thì luồng thứ hai cũng thực hiện một công việcgiống như vậy Ta cho việc này lập này khoảng 1000 lần Kết quả mà ta chờ đợi là hailuồng trên đếm lần lượt tăng biến counter lên 1 và in ra kết quả 1, 2, 3, 4 … tuy nhiên
ta sẽ xét đoạn chương trình dưới đây và thấy rằng kết quả hoàn toàn khác với những gì
private int counter = 0;
static void Main( string [] args)
Console WriteLine( "Start thread {0}" , t1.Name);
Thread t2 = new Thread ( new ThreadStart (Incrementer));
Trang 40Console WriteLine( "Thread {0} Incrementer: {1}" ,
Thread CurrentThread.Name, counter);