TRƯỜNG ĐẠI HỌC SƯ PHẠM TP.HCM
KHOA TOÁN – TIN
BỘ MÔN TIN
TRẦN THANH PHƯỚC
LẬP TRÌNH MẠNG TRÊN MÁY POCKET PC
Giáo viên hướng dẫn :
Th.s : HOÀNG THÂN ANH TUẤN
TP.HCM, 2006.
Lời cảm ơn
Sau gần sáu tháng làm việc cật lực cuối cùng thì em cũng đã hoàn thành được
luận văn tốt nghiệp của mình. Mặc dù kiến thức trong luận văn này chỉ là một phần nhỏ
trong kho tàng kiến thức của chuyên đề lập trình mạng trong môi trường Pocket PC
nhưng đối với em đó là một thành tựu tuyệt vời. Đó là thành quả của gần sáu tháng trời
nghiên cứu học tập. Và xa hơn nữa chính là kết quả của bốn năm đèn sách dưới mái
trường Đại Học Sư Phạm.
Có được dù thành tựu dù không lớn lao nhưng nó cũng đã thể hiện phần nào sự
quyết tâm gắng của bản thân cũng như sự chỉ bảo tận tình của các thầy cô đã dạy bảo
em trong suốt thời gian học vừa qua. Em xin chân thành cảm ơn đến tất cả các thầy cô
trong trong Khoa Toán Tin đặc biệt là Tổ Bộ môn Tin Học đã tận tình chỉ bảo truyền
đạt những kinh nghiệm kiến thức cho chúng em để chúng em có được những cơ sở
kiến thức cần thiết hoàn thành luận văn này. Những kỷ niệm những ân tình mà thầy
Quang Tấn thầy Ngọc Trung thầy Bảo.... đối với chúng em sẽ mãi là những kỷ niệm
đẹp chúng em sẽ mãi không bao giờ quên. Vượt lên trên cả em xin chân thành cảm ơn
thầy Hoàng Thân Anh Tuấn thầy đã hướng dẫn em hoàn thành tốt luận văn này. Thầy
đã cung cấp cho em rất nhiều tài liệu hỗ trợ cũng như kinh nghiệm lập trình cần thiết
để vượt qua những khó khăn do hạn chế về chuyên môn cũng như kinh nghiệm lập
trình của bản thân em. Mặc dù thầy có rất nhiều công việc nhưng mỗi lần chúng em
gặp những vướng mắc thầy luôn sẵn sàng gặp mặt để giúp đỡ dù đó là những lúc không
phải là giờ gặp chính thức giữa thầy hướng dẫn và người làm luận văn.
Tuy đã rất cố gắng nhằm đạt được những gì tốt nhất cho luận văn này nhưng do
kiến thức có hạn nên luận văn này nhất định sẽ có những khiếm khuyết cần được sửa
chữa. Kính mong các thầy cô cùng các bạn đọc thông cảm và nhiệt tình đóng góp
những ý kiến nhằm khắc phục những khiếm khuyết của luận văn. Qua đó em sẽ củng
-1-
cố lại kiến thức của mình khắc phục lại những sai lầm cũ làm cho luận văn này được
mới mẽ hơn hữu ích hơn.
Một lần nữa em xin gửi lời cảm ơn đến tất cả các thầy cô đã dạy bảo em trong
suốt thời gian qua. Sự dạy bảo đóng góp của các thầy cô chính là những nền tảng cơ
bản nhất giúp chúng em có đủ tự tin trên bước đường hoàn thiện kiến thức của mình.
-2-
Mục lục
2TChương 12T
2TGiới thiệu về đề tài.2T ...................................................................................... 6
2T1.1.2T
2TCơ sở của đề tài :2T ............................................................................................... 6
2T1.2.2T
2TMục tiêu của đề tài :2T .......................................................................................... 6
2T1.3.2T
2TPhạm vi của đề tài :2T ........................................................................................... 6
2T1.4.2T
2TCấu trúc của luận văn :2T ...................................................................................... 7
2TChương 22T
2TKhảo sát những vấn đề kỹ thuật liên quan2T ................................................... 8
2T2.1.2T
2TMáy tính Pocket PC :2T......................................................................................... 8
2T2.1.12T
2TĐịnh nghĩa :2T .................................................................................................. 8
2T2.1.22T
2TMột vài khái niệm về phần cứng Pocket PC :2T .............................................. 8
2T2.2.2T
2TPocket PC Emulator (2003) :2T ......................................................................... 11
2T2.2.12T
2TĐịnh nghĩa Emulator:2T ................................................................................. 11
2T2.2.22T
2TSử dụng Emulator :2T .................................................................................... 11
2T2.2.32T
2TCác yêu cầu cho Emulator:2T ........................................................................ 11
2T2.2.42T
2TĐịnh cấu hình Emulator:2T ............................................................................ 12
2T2.2.52T
2TTắt Emulator:2T ............................................................................................. 16
2T2.2.62T
2TNhững hạn chế của Emulator:2T .................................................................... 16
2T2.3.2T
2TSơ lược về mạng :2T ............................................................................................ 17
2T2.3.12T
2TNguồn đích và các gói dữ liệu :2T ................................................................ 17
2T2.3.22T
2TMôi trường truyền dẫn :2T ............................................................................. 18
2T2.3.32T
2TGiao thức :2T .................................................................................................. 18
2T2.3.42T
2TMô hình tham chiếu OSI :2T .......................................................................... 19
2T2.3.52T
2TSự đóng gói dữ liệu :2T .................................................................................. 21
2T2.4.2T
2TLập trình mạng :2T .............................................................................................. 23
2T2.4.12T
2TLiên lạc trên Internet :2T ................................................................................ 23
-3-
2T2.4.22T
2TDịch vụ từ phía máy chủ và khái niệm cổng (PORT):2T .............................. 26
2T2.4.32T
2TGiao tiếp trên mạng theo mô hình khách/chủ (client/server) và khái niệm
2T2.4.42T
2TLập trình mạng thông qua Socket :2T ............................................................ 28
2TChương 32T
2TLập trình mạng trên môi trường Pocket PC2T ............................................... 29
2T3.1.2T
2TCài đặt các phần mềm cần thiết:2T ...................................................................... 29
2T3.1.12T
2TCài đặt eMbedded Visual C++ 4.02T ............................................................. 29
2T3.1.22T
2TCài đặt eVC4SP3.2T ...................................................................................... 31
2T3.1.32T
2TCài đặt Pocket PC 2003 SDK.2T ................................................................... 33
2T3.1.42T
2TCài đặt Emulator:2T ....................................................................................... 35
2T3.1.52T
2TCài đặt LoopBack Adapter.2T ........................................................................ 37
2T3.1.62T
2TCấu hình mạng:2T .......................................................................................... 40
2T3.2.2T
2TCác bước xây dựng một ứng dụng mạng trên máy Pocket PC2T ....................... 43
2T3.2.12T
2TXây dựng dịch vụ trên Server :2T .................................................................. 44
2T3.2.22T
2TXây dựng ứng dụng trên Client :2T ................................................................ 45
2T3.3.2T
2TChi tiết các hàm sử dụng trong từng bước2T ...................................................... 45
2T3.3.12T
2TSử dụng API:2T .............................................................................................. 45
2T3.3.22T
2TSử dụng MFC:2T ............................................................................................ 61
2TChương 42T
2TỨng dụng minh họa2T .................................................................................... 69
2T4.1.2T
2TMô tả ứng dụng minh họa:2T .............................................................................. 69
2T4.1.12T
2TỨng dụng chat giữa Pocket PC với máy tính để bàn:2T ................................ 69
2T4.1.22T
2TỨng dụng điều khiển Power Point:2T ............................................................ 69
2T4.2.2T
2TChi tiết các hàm liên quan đến ứng dụng:2T ....................................................... 70
2T4.3.2T
2TMô tả hoạt động của ứng dụng minh họa.2T ....................................................... 72
2T4.3.12T
2TỨng dụng chat giữa Pocket PC với máy tính để bàn:2T ................................ 72
2T4.3.22T
2TỨng dụng điều khiển Power Point:2T ............................................................ 73
2T4.4.2T
2TMô tả thuộc tính phương thức chủ yếu của ứng dụng minh họa:2T ................... 74
Socket:2T 27
-4-
2T4.4.12T
2TỨng dụng chat giữa Pocket PC với máy tính để bàn:2T ................................ 74
2T4.4.22T
2TỨng dụng điều khiển Power Point:2T ............................................................ 76
2T4.5.2T
2TMô tả màn hình kết quả của ứng dụng2T ............................................................ 77
2T4.5.12T
2TỨng dụng chat giữa Pocket PC với máy tính để bàn:2T ................................ 78
2T4.5.22T
2TỨng dụng điều khiển Power Point:2T ............................................................ 80
2TChương 52T
2TĐánh giá đề tài và đề xuất hướng phát triển kế tiếp2T .................................. 82
2T5.1.2T
2TNhững kết quả đã đạt được2T.............................................................................. 82
2T5.2.2T
2TĐề xuất hướng phát triển.2T ................................................................................ 82
2TDanh mục tài liệu tham khảo.2T ........................................................................................ 83
2TPhụ lục.2T ........................................................................................................................... 84
-5-
Chương 1 0BGiới thiệu về đề tài.
6BUCơ sở của đề tài :
1.1.
Ngày nay với trình độ khoa học kĩ thuật phát triển cao các thiết bị điện tử hỗ trợ
con người đã trở thành một vật dụng hữu ích và không thể thiếu như máy vi tính laptop
điện thoại di động iPod … Các thiết bị này có thể đáp ứng mọi nhu cầu của người dùng
trong việc học tập giải trí thông tin liên lạc… ở mọi lúc mọi nơi khi người dùng cần
đến và có xu hướng phát triển rất nhanh.
Một trong những thiết bị hữu ích trên mà tác giả muốn trình bày đó là PDA.
Thiết bị này đang có xu hướng phát triển rất nhanh và mạnh. Trong phạm vi của
luận văn này tác giả chỉ xem xét đến một loại của PDA là Pocket PC; đặc biệt là về
7BUMục tiêu của đề tài :
môi trường lập trình mạng trên Pocket PC.
1.2.
Khảo sát việc lập trình trên máy Pocket PC bằng eVC++.
Xây dựng tài liệu tham khảo cho sinh viên về chủ đề lập trình mạng trên máy
Pocket PC.
Xây dựng một ứng dụng nhỏ minh họa (chương trình chat giữa Pocket PC và
8BUPhạm vi của đề tài :
máy tính để bàn hoặc chương trình điều khiển Power Point bằng Pocket PC).
1.3.
Như trên đã nói chủ đề của luận văn này là lập trình mạng trên máy Pocket PC.
Do đó tác giả sẽ chỉ trình bày những kiến thức cơ bản nhất mà qua đó sinh viên có thể
đọc hiểu và áp dụng vào việc tạo ra một ứng dụng mạng đơn giản giữa các Pocket PC
hoặc giữa máy tính để bàn với Pocket PC. Cụ thể hơn tác giả sẽ trình bày những vấn
đề sau đây:
-6-
Giới thiệu về Pocket PC và Emulator.
Giới thiệu sơ lược về mạng và lập trình mạng.
Tìm hiểu cách xây dựng ứng dụng mạng đơn giản trên Pocket PC.
9BUCấu trúc của luận văn :
Xây dựng ứng dụng minh họa.
1.4.
2TChương 1: Giới thiệu về đề tài.2T Chương này trình bày những mục sau: Cơ sở đề
tài mục tiêu đề tài phạm vi đề tài cấu trúc luận văn
Chương 2: Khảo sát những vấn đề kỹ thuật liên quan. Khảo sát những vấn đề
sau: Tìm hiểu về máy tính Pocket PC trình giả lập Pocket PC Emulator 2003 tìm
hiểu sơ lược về mạng tìm hiểu về lập trình mạng lập trình mạng thông qua
socket.
Chương 3: Lập trình mạng trên môi trường Pocket PC. Chương này tìm hiểu các
phần sau: Cài đặt các phần mềm cần thiết để có thể lập trình cho máy Pocket PC
trên máy tính để bàn tìm hiểu các bước xây dựng một ứng dụng mạng trên máy
Pocket PC nghiên cứu các chi tiết các hàm được sử dụng trong từng bước.
Chương 4: Ứng dụng minh họa bao gồm: Mô tả ứng dụng minh họa nghiên cứu
các hàm có liên quan đến ứng dụng mô tả họat động của ứng dụng minh hoa
trình bày các thành phần dữ liệu và các phương thức chủ yếu của ứng dụng mô
tả màn hình kết quả của ứng dụng.
Chương 5: Đánh giá đề tài và đề xuất hướng phát triển kế tiếp. Chương này
trình bày hai phần: Một là trình bày những kết quả đã đạt được hai là đề xuất
hướng phát triển.
Danh mục tài liệu tham khảo: Trình bày những tài liệu tham khảo hỗ trợ cho
việc hoàn thành luận văn này.
Phần Phụ lục: Trình bày ví dụ chat tuần tự minh họa cách sử dụng socket để lập
trình mạng.
-7-
Chương 2 1BKhảo sát những vấn đề kỹ thuật liên quan
10BUMáy tính Pocket PC :
2.1.
2.1.1 24BĐịnh nghĩa :
“Pocket” trong tiếng Anh có nghĩa là “túi” và “Pocket PC” có nghĩa là “máy vi
tính bỏ túi” ý nói là thiết bị này cũng thông minh như PC nhưng rất nhỏ gọn có thể bỏ
vào túi một cách vừa vặn tiện lợi.
Hệ điều hành :
Như trên đã nói Pocket PC cũng là một PC nên để Pocket PC chạy được nó cần
phải có hệ điều hành. Pocket PC sử dụng Windows Mobile - sản phẩm độc quyền của
Microsoft. Có thể xem hệ điều hành này là phiên bản thu nhỏ hệ điều hành Windows.
Vì thế hầu hết người sử dụng khi dùng Pocket PC sẽ cảm thấy giao diện vô cùng quen
thuộc. Cũng là các cửa sổ Windows cũng là nút Start để ra Menu cũng là Word Exel
PowerPoint và Internet Explorer…
Hiện tại Windows Mobile cũ nhất còn được sử dụng là Windows Mobile 2002;
tiếp theo là Windows Mobile 2003 với khả năng hỗ trợ multimedia cao hơn; Windows
Mobile 2003 Second Edition là phiên bản hệ điều hành gần như mới nhất với khả năng
hỗ trợ xoay ngang màn hình rất tiện lợi cho việc duyệt web trên Pocket PC. Hệ điều
hành mới nhất là Windows Mobile 2005 – đang được cộng đồng Pocket PC mong đợi!
Windows Mobile giống như Windows trên máy vi tính là hệ điều hành đa nhiệm
nghĩa là: bạn có thể vừa mở cửa sổ của trình nghe nhạc vừa xem duyệt web vừa sử
dụng từ điển.
59BMàn hình xúc cảm :
2.1.2 25BMột vài khái niệm về phần cứng Pocket PC :
2.1.2.1
-8-
Hình 2.1 Pocket PC.
Màn hình xúc cảm (touch screen) là một màn hình tinh thể lỏng (LCD) được
bao phủ bởi một touch panel có điện trở. LCD hướng thẳng đứng với độ phân giải là
240×320-pixel cho phép người dùng nhìn thấy các thành phần giao diện một cách rõ
ràng. Độ dẫn điểm (dot pitch) dành cho Pocket PC là.22 tới.24 tùy thuộc OEM. Chạm
nhẹ lên màn hình xúc cảm bằng một cây bút (stylus) hoặc ngón tay sẽ gửi cùng một
loại thông điệp giống như click chuột trái lên máy desktop mặc dù việc hỗ trợ con trỏ
bị giới hạn đến đồng hồ cát quay vòng cho tín hiệu chờ đợi. Người dùng cũng có thể
chọn và drag các item. Để cảm thấy được những thay đổi nhanh chóng trong việc nhập
liệu màn hình xúc cảm có tốc độ refresh (refresh rate) nhỏ nhất là 100 mẫu/giây
(samples per second). Pocket PC cũng hỗ trợ độ sâu màu (color depth) lên đến 16
60BBút và bàn phím :
bit/pixel (bits per pixel).
2.1.2.2
Pocket PC không có bàn phím vật lí tiêu chuẩn. Việc nhập liệu văn bản
được hoàn thành bằng cách sử dụng bảng nhập liệu (input panel) và bút (stylus). Nói
chung bảng nhập liệu là một cửa sổ tiêu chuẩn trên màn hình xúc cảm mà hiển thị một
phương thức nhập liệu cho phép người dùng nhập dữ liệu bằng nhiều cách. Phần mềm
Pocket PC có phương thức nhập liệu bàn phím QWERTY được đơn giản hóa và
-9-
phương pháp nhập liệu nhận biết chữ viết tay.
Stylus là một con trỏ dành cho cho việc truy xuất màn hình xúc cảm và
các phương thức nhập liệu. Stylus này có một điểm nhỏ hơn ngón tay người dùng
nhưng không làm làm xước màn hình xúc cảm.
OEM hoặc người dùng có thể thêm vào các phương thức nhập liệu.
Chẳng hạn một đại lí phần mềm độc lập (ISV) có thể tạo ra một phương thức nhập liệu
để chạm nằm trong mã Morse. Người dùng có thể mua phương thức nhập liệu mã
61BIn ấn :
Morse và cài đặt nó ở nhà.
2.1.2.3
62BNguồn điện:
In ấn hiện nay không được hỗ trên Pocket PC.
2.1.2.4
Bởi vì Pocket PC di chuyển được nên tuổi thọ pin rất quan trọng. Pocket
PC có thể hoạt động nhiều giờ trên nguồn pin tiêu chuẩn của nó và nó có thể có pin dự
63BCPU:
phòng để tránh mất dữ liệu nếu pin chính hết năng lượng.
2.1.2.5
Pocket PC sử dụng họ vi xử lí ARM. Bộ xử lí ARM cung cấp sự kết hợp
64BBộ nhớ:
xuất sắc giữa độ thực thi cao và tiêu hao năng lượng ít.
2.1.2.6
Tất cả các thiết bị Pocket PC có ít nhất 24 megabytes (MB) ROM và 16
MB RAM. Bản nâng cấp được đưa ra bởi một số OEM dành cho các thiết bị Pocket PC
của họ được làm cho thích ứng để ăn khớp với 16 MB flash RAM sẵn có trên các thiết
bị được nâng cấp đó.
Bởi vì bảo quản bộ nhớ trên Pocket PC rất quan trọng nên nhiều thành phần hệ
điều hành Pocket PC được nén trong ROM. Khi người dùng cần thành phần nào hệ
-10-
điều hành giải nén thành phần đó và chuyển nó tới RAM. Vì cần có thời gian cho giải
65BCổng nối tiếp cài đặt sẵn:
nén và chuyển nên các file nén thực thi chậm.
2.1.2.7
Pocket PC có thể kết nối đến một máy desktop bằng cách sử dụng cáp nối tiếp
hoặc bệ nối tùy chọn (optional docking cradle) thường là có sẵn từ nhiều nhà sản xuất
Pocket PC được kết nối đến máy desktop. Một số thiết bị Pocket PC hỗ trợ giao tiếp dữ
66BCổng giao tiếp hồng ngoại:
liệu thông qua một modem kết nối đến cradle.
2.1.2.8
Pocket PC có cổng nối tiếp thích hợp với kĩ thuật Infrared Data
Association (IrDA). Các thiết bị Pocket PC có thể giao tiếp với các thiết bị Pocket PC
khác các thiết bị nền Windows CE khác các thiết bị vi tính cầm tay nền Palm OS hoặc
11BUPocket PC Emulator (2003) :
máy desktop.
2.2.
2.2.1 26BĐịnh nghĩa Emulator:
Pocket PC SDK có một môi trường giả lập mới. Môi trường này cung cấp một
máy ảo chạy phần mềm Pocket PC được biên dịch cho bộ xử lí x86. Máy ảo này sao y
phần cứng được biết như là CEPC là một cấu hình phần cứng chạy Windows CE trên
một máy tính desktop Intel x86.
2.2.2 27BSử dụng Emulator :
Ta không được dùng phím Windows + L để đóng hệ thống khi đang sử dụng
emulator. Đóng máy tính của bạn trong khi trình giả lập đang chạy có thể làm cho
emulator không sử dụng được nữa khi bạn mở computer.
2.2.3 28BCác yêu cầu cho Emulator:
-11-
Emulator có những yêu cầu về phần cứng và phầm mềm như sau:
Microsoft Windows 2000 Professional hay Windows 2000 Server có cài đặt
Service Pack 2 hoặc Microsoft Windows XP Home Edition hay Windows XP
Professional.
Intel Pentium II hoặc bộ xử lí sau này chạy với tốc độ 400 MHz hoặc nhanh
hơn.
196 MB RAM.
Có card mạng và kết nối hoặc là Microsoft Loopback Adapter.
2.2.4 29BĐịnh cấu hình Emulator:
Trước khi cấu hình Emulator đảm bảo rằng chúng ta đã cài đặt thành công
Microsoft eMbedded Visual C++® và trình giả lập Emulator. Cách thức 2TUcài đặtU2T như thế
nào sang chương 3 chúng ta sẽ tìm hiểu.
67BĐịnh cấu hình Platform Manager:
Phần này mô tả cách định cấu hình cho emulator trước khi sử dụng lần đầu.
2.2.4.9
Chủ đề này mô tả cách định cấu hình Platform Manager bằng cách sử dụng
Microsoft eMbedded Visual C++®. Làm theo các bước sau:
Khởi động eMbedded Visual C++.
Trong eMbedded Visual C++ trên menu Tools click Configure Platform
Manager.
Hình 2.2 Platform Manager.
-12-
Mở các kiểu thiết bị ra sau đó click Pocket PC 2003. Trong hộp thoại Windows
CE Platform Manager Configuration click Pocket PC 2003 Emulator. Tùy theo
các công cụ Windows CE khác được cài đặt trên máy tính có thể có những thiết
bị và platform khác được liệt kê trong hộp thoại.
Click Properties.
Cả transport và Startup Server đều có những tùy chọn cấu hình có thể điều chỉnh
được. Click vào nút Configure dành cho TCP/IP transport để hiển thị các thiết lập
mạng; tuy nhiên đề nghị là cấu hình tiêu chuẩn được giữ nguyên không đổi.
Click nút Configure dành cho the Emulator Startup Server để mở hộp thoại
Emulation Configuration Settings.
Hình 2.3 Màn hình Emulation Configuration Settings.
Hộp thoại này cho phép những thay đổi sau:
Thay đổi phím chủ (host).
Chọn hỗ trợ mạng sẵn có (available).
68BĐịnh cấu hình Pocket PC Connection Manager:
Ánh xạ một cổng được giả lập đến một cổng thực trên trạm công tác phát triển.
2.2.4.10
Thiết bị Pocket PC giả lập sẽ yêu cầu những điều chỉnh đến các thiết lập mạng
trước khi có thể truy cập Internet. Nếu mạng sử dụng proxy server để truy cập Internet
thì thông tin proxy cũng phải được định cấu hình.
Để định cấu hình thông tin proxy cho emulator:
-13-
Định cấu hình emulator với hỗ trợ mạng và khởi động emulator.
Trong cửa sổ emulator Pocket PC trên menu Start click Settings.
Click tab Connections.
Click biểu tượng Connections.
Click tab Advanced.
Click nút Network Card.
Đặt thiết lập My network card connects to thành Work.
Click OK ở góc trên bên phải.
Click tab Tasks.
Phía dưới tiêu đề My Work Network click vào link Edit my proxy server.
Chọn check box This network connects to the Internet box.
Nếu mạng sử dụng proxy server:
Chọn check box This network uses a proxy server to connect to the Internet.
Gõ vào thông tin proxy server.
Click OK ở góc trên bên phải trên.
Click OK ở góc trên bên phải một lần nữa
Triển khai ứng dụng eMbedded Visual C++ cho Emulator:
Chủ đề này mô tả cách triển khai một ứng dụng nền eMbedded Visual C++ đến
emulator. Làm theo các bước sau:
Bảo đảm emulator được định cấu hình đúng trước khi sử dụng nó lần đầu tiên.
Bảo đảm đã có thanh công cụ WCE Configuration.
Hình 2.4 Màn hình eVC4.0.
-14-
Bảo đảm rằng cả Win32 (WCE emulator) Release lẫn Win32 (WCE emulator)
Debug được chọn trong list box Active Configuration xổ xuống và Pocket PC
Emulator được chọn trong list box Default Device.
Ứng dụng sẽ được tải xuống đến emulator khi bất kì chọn lựa nào sau đây được
thực hiện: Rebuild All Go (F5) hoặc Execute (CTRL+F5). Go và Execute cũng
khởi động ứng dụng. Cũng có thể thay đổi cách hoạt động tải xuống mặc định
của eMbedded Visual C++ bằng cách click Tools click Options tiếp đó click tab
Download trong hộp thoại Options.
69BDi chuyển các file đến và đi khỏi Emulator:
Lưu ý: eMbedded Visual Basic không còn được hỗ trợ nữa.
2.2.4.11
Bạn có thể di chuyển các tập tin đến hoặc đi khỏi trình giả lập bằng cách sử
dụng bất kì phương pháp nào sau đây:
Sử dụng tính năng Explore của ActiveSync.
Sử dụng công cụ Remote File Viewer mà sẵn có trong eMbedded Visual C++
4.0. Chức năng Export di chuyển một file từ hệ thống file của trạm công tác phát
triển đến hệ thống file của thiết bị Pocket PC thực hoặc giả lập. Chức năng
Import di chuyển các file từ thiết bị Pocket PC thực hoặc giả lập sang hệ thống
file của trạm công tác phát triển.
Chia sẻ (dùng chung) các file trong hệ thống file của trạm công tác phát triển và
truy xuất những file đó bằng cách sử dụng File Manager trong image Pocket PC
giả lập.
-15-
2.2.5 30BTắt Emulator:
Hình 2.5 Màn hình tắt Emulator.
Bạn có thể tắt emulator bằng cách sử dụng bất kì phương pháp nào sau đây:
Click Close trong thanh tiêu đề của cửa sổ emulator click Shut Down trên menu
Emulator hoặc xài phím tắt để làm hộp thoại xuất hiện Shut Down. Hộp thoại Shut
Down được minh họa như hình trên.
Danh sách xổ xuống trong hộp thoại Shut Down cung cấp 2 tùy chọn:
Turn off Emulator: Tắt image giả lập mà không lưu lại trạng thái hiện tại.
Save Emulator State: Lưu trạng thái hiện tại của emulator để nó có sẽ trả về điểm này
trong lần khởi động emulator kế tiếp.
Việc chọn không lưu tình trạng emulator cung cấp một image sạch trong
emulator khi khởi động lần tới. Image sạch này bao gồm cả hệ thống file và registry
mới.
Lưu trạng thái emulator cung cấp cơ hội tiếp tục làm việc từ điểm dừng làm việc
trước đó. Trạng thái emulator được lưu vào file nhị phân với phần mở rộng là.vsv; file
này được lưu trong thư mục C:\Documents and Settings\logonname\Application Data.
Chẳng hạn với logon name của Michael tên đường dẫn sẽ là C:\Documents and
Settings\Michael\Application Data. File.vsv này sẽ có kích thước xấp xỉ 14 MB. Xóa
file này sẽ làm cho emulator mất đi trạng thái lưu lại trước đó của nó.
2.2.6 31BNhững hạn chế của Emulator:
Mặc dù emulator mới là một bước tiến ấn tượng (dramatic) về độ trung thực và
sự thuận tiện cho việc phát triển mỗi emulator có những hạn chế của nó khi so sánh với
-16-
thiết bị mà nó giả lập. Emulator được có trong Pocket PC SDK vận hành mã Pocket PC
thực mà được biên dịch để nhắm tới CPU x86. Trong đa số các kịch bản (scenarios)
phát triển ứng dụng thiết lập này là đủ. Tuy nhiên vẫn có một số hạn chế đối với loại
giả lập này:
Để sử dụng emulator các ứng dụng phải được biên dịch để chạy trên CPU x86.
Ứng dụng này sẽ khó tránh khỏi những khác biệt tiềm tàng trong các trình biên dịch
x86 runtime và các file hỗ trợ khi được so sánh với các thiết bị dựa trên ARM.
Bởi vì những khác biệt trong cấu trúc CPU (x86 CISC so với ARM RISC) và
những thiết lập chỉ thị không thể dùng emulator để trình diễn việc thực thi tuyệt đối tối
tỉ mỉ và sự tối ưu memory footprint. Tuy nhiên đối với hầu hết trình ứng dụng mức
phân tích này không thành vấn đề.
Màn hình xúc cảm của thiết bị được thay thế bằng con chuột. Mặc dù con chuột
về mặt chức năng tương đương với màn hình xúc cảm nhưng những nhà phát triển ứng
dụng phải xem xét thêm kinh nghiệm của người dùng chạy ứng dụng trên thiết bị mà
cần có bút (stylus).
Việc ghi âm không được hỗ trợ trong emulator bất chấp các khả năng ghi âm
12BUSơ lược về mạng :
của máy tính phát triển chạy emulator.
2.3.
Mục đích của việc xây dựng hệ thống mạng (dù nhỏ hay lớn) là để trao đổi
thông tin chia sẽ thông tin chia sẽ thiết bị với nhau ….. Do đó điều chúng ta cần quan
tâm trong phần này là tìm hiểu xem thông tin được truyền như thế nào và các máy tính
trong mạng (host) gửi và nhận thông tin ra sao. Muốn thế ta hãy tìm hiểu một số khái
niệm sau đây.
2.3.1 32BNguồn đích và các gói dữ liệu :
Để cho các máy tính gửi thông tin xuyên qua một mạng tất cả các hoạt
động truyền tin trên một mạng đều xuất phát từ một nguồn sau đó di chuyển đến một
-17-
đích. Thông tin được di chuyển trên một mạng được tham chiếu đến như là dữ liệu gói
hay gói dữ liệu. Một gói dữ liệu là một đơn vị thông tin được nhóm lại theo luận lý và
di chuyển giữa các hệ thống máy tính. Bao gồm trong đó là thông tin về nguồn tin cùng
với các phần tử cần thiết khác để thực hiện một hoạt động truyền tin cậy với thiết bị
đích. Địa chỉ nguồn trong một gói chỉ ra danh định của máy tính đã gửi gói này. Địa
chỉ đích chỉ danh định của máy tính sau cùng tiếp nhận gói.
2.3.2 33BMôi trường truyền dẫn :
Môi trường truyền dẫn trong mạng là một miền vật chất mà qua đó các gói dữ
liệu di chuyển. Nó có thể là bất kỳ loại nào sau đây :
Các dây điện thoại.
Cáp UTP loại 5 (được dùng cho 10 BASE – T).
Các cáp đồng trục (được dùng cho truyền hình).
Sợi quang. (sợi thủy tinh mảnh truyền ánh sáng).
Có hai loại mội trường không rõ ràng cho lắm nhưng dẫu sao nó cũng tham gia
vào hoạt động thông tin trên mạng. Trước hết là không khí (hầu hết là oxy nitơ và hơi
nước) nó mang sóng radio sóng vi ba và ánh sáng.
Hoạt động thông tin không dùng dây dẫn hay cáp được gọi là thông tin không
dây hay thông tin không gian tự do (wireless hay free – space communication). Đó là
khả năng dùng sóng điện từ EM (electromagnetic). Các sóng điện từ lan truyền trong
chân không với tốc độ ánh sáng gồm có sóng năng lượng sóng radio sóng vi ba ánh
sáng hồng ngoại ánh sáng nhìn thấy tia cực tím tia X tia gamma. Các sóng điện từ
lan truyền trong không khí nhưng chúng cũng lan truyền qua khoảng chân không
2.3.3 34BGiao thức :
Để các gói dữ liệu có thể di chuyển từ nguồn đến đích trên mạng điều quan
trọng là tất cả các thiết bị trên mạng phải nói cùng một ngôn ngữ hay giao thức. Một
giao thức là một tập các quy định giúp thực hiện hoạt động thông tin trên mạng.
-18-
Sự phát triễn của các chuẩn lập lập mạng ISO :
Nhằm giải quyết vấn đề không tương thích của các mạng và không thể
trao đổi thông tin với nhau giữa các mạng tổ chức tiêu chuẩn hóa quốc tế ISO đã
nghiên cứu lược đồ mạng như DECNET SNA và TCP/IP để tìm ra một bộ luật. Kết
quả của nghiên cứu này ISO đã tạo ra được một mô hình mạng giúp cho các nhà chế
tạo có thể tạo ra các mạng riêng của mình nhưng vẫn đảm bảo tương thích và liên kết
hoạt động với các mạng khác.
Quá trình này chia hoạt động thông tin phức tạp thành các tác vụ rời rạc
nhỏ hơn. Mô hình tham chiếu OSI được công bố vào năm 1984 nó mô tả lược đồ phân
lớp mà tổ chức này đã xây dựng được. Mô hình cung cấp cho các nhà chế tạo một tập
các tiêu chuẩn đảm bảo tương thích và liên kết hoạt động tốt hơn giữa các kỹ thuật
mạng khác nhau được tạo ra bởi nhiều công ty trên thế giới.
2.3.4 35BMô hình tham chiếu OSI :
Mô hình tham chiếu OSI là mô hình chủ yếu cho các hoạt động thông tin
trên mạng. Mặc dù đã có các mô hình khác nhưng hầu hết các nhà chế tạo ngày nay
đều tạo ra các sản phẩm của họ trên cơ sở tham chiếu đến mô hình OSI.
Mô hình tham chiếu OSI cho phép bạn nhận ra được các chức năng mạng
diễn ra tại mỗi lớp. Nó là một khuôn mẫu giúp bạn hiểu thông tin di chuyển xuyên qua
một mạng như thế nào. Nó được chia thành 7 lớp :
* Lớp 7: Lớp ứng dụng (the application layer)
Lớp ứng dụng là lớp gần gũi với người dùng hơn hết nó cung cấp
các dịch vụ mạng cho các ứng dụng của người dùng. Nó khác với các lớp khác ở chỗ
không cung cấp các dịch vụ cho bất kỳ lớp nào thay vì vậy nó chỉ cung cấp các dịch vụ
cho các ứng dụng nằm bên ngoài mô hình OSI. Các chương trình ứng dụng như
chương trình xử lý bảng tính các chương trình xử lý văn bản các chương trình đầu
cuối…. Lớp ứng dụng thiết lập tính sẵn sàng cho các đối tác thông tin đồng bộ hóa và
-19-
thiết lập tính nhất quán trên các thủ tục khắc phục lỗi và kiểm soát tính toàn vẹn dữ
liệu. Nếu bạn muốn ghi nhớ lớp 7 chỉ bằng vài từ ngắn gọn thì hãy nghĩ đến các trình
duyệt web.
* Lớp 6: Lớp trình bày (the presentation layer)
Lớp trình bày đảm bảo thông tin mà lớp ứng dụng của một hệ
thống đầu cuối gởi đi lớp ứng dụng của hệ thống khác có thể đọc được. Nếu cần lớp
trình bày thông dịch giữa nhiều dạng dữ liệu khác nhau thông qua một dạng chung.
Nếu bạn muốn ghi nhớ lớp 6 một cách ngắn gọn thì hãy nghĩ đến dạng dữ liệu chung.
* Lớp 5: Lớp phiên (the session layer)
Như bao hàm trong tên của lớp lớp phiên thiết lập quản lý và kết
thúc các phiên thông tin giữa hai chủ thể truyền nhận. Nó cũng đồng bộ hội thoại giữa
2 lớp trình bày của hai host và quản lý các cuộc trao đổi dữ liệu giữa chúng. Bên cạnh
sự điều khiển phiên làm việc lớp phiên còn chuẩn bị những thứ cần thiết cho truyền dữ
liệu hiệu quả phân lớp dịch vụ và thông báo mở rộng các sự cố của lớp phiên lớp trình
bày và lớp ứng dụng. Nếu bạn muốn ghi nhớ lớp 5 bằng vài từ thì đó là hội thoại.
* Lớp 4: Lớp vận chuyển (the transport layer)
Lớp vận chuyển phân đọan dữ liệu từ hệ thống host truyền và tái
thiết lập dữ liệu vào một luồng dữ liệu tại hệ thống host nhận. Ranh giới giữa lớp vận
chuyển và lớp phiên có thể được xem như ranh giới giữa giao thức ứng dụng
(application protocol) và giao thức luồng dữ liệu. Trong khi các lớp ứng dụng lớp trình
bày và lớp phiên liên quan mật thiết đến ứng dụng thì bốn lớp dưới lại liên quan đến
việc truyền dữ liệu.
Lớp vận chuyển cố gắng cung cấp một dịch vụ vận chuyển dữ liệu
tạo nên một dải ngăn cách bảo vệ các lớp trên tránh các chi tiết hiện thực vận chuyển
bên đưới. Đặc biệt các vấn đề như làm thế nào vận chuyển giữa hai host thật sự tin cậy
là trách nhiệm liên quan đến lớp vận chuyển. Trong việc cung cấp dịch vụ truyền tin
lớp vận chuyển thiết lập duy trì và kết thúc một cách tốt đẹp các mạch ảo. Trong việc
-20-
cung cấp các dịch vụ tin cậy sự phát hiện lỗi khắc phục lỗi cũng như điều khiển luồng
thông tin đều được sử dụng triệt để. Nếu bạn muốn ghi nhớ tóm tắt lớp 4 thì hãy nghĩ
ngay đến chất lượng dịch vụ và độ tin cậy.
* Lớp 3:lớp mạng (the network layer)
Lớp mạng là lớp phức tạp nó cung cấp kết nối và chọn lựa đường
dẫn giữa hai hệ thống host tọa lạc trên các mạng tách biệt về mặt địa lý. Nếu bạn muốn
ghi nhớ lớp 3 chỉ với một vài từ ngắn gọn hãy ngay đến sự chọn đường định tuyến và
đánh địa chỉ.
* Lớp 2:lớp liên kết dữ liệu (the data link layer)
Lớp liên kết dữ liệu cung cấp khả năng chuyển dữ liệu tin cậy
xuyên qua một liên kết vật lý. Trong khi làm công việc này lớp liên kết dữ liệu gắn
liền với lược đồ đánh địa chỉ vật lý (đối nghịch với địa chỉ luận lý) cấu hình mạng truy
xuất mạng thông báo lỗi thứ tự phân phối frame và điều khiển luồng. Nếu bạn muốn
ghi nhớ lớp 2 bằng vài từ ngắn gọn bạn hãy nghĩ ngay đến các frame và điều khiển
truy xuất môi trường.
* Lớp 1: Lớp vật lý (the physical layer)
Lớp vật lý định nghĩa các qui cách về điện cơ thủ tục và các đặc tả
chức năng để kích hoạt duy trì và dừng một liên kết vật lý giữa các hệ thống đầu cuối.
Các đặc trưng như các mức điện áp định thời thay đổi điện áp tốc độ chuyển dữ liệu vật
lý cự ly truyền tối đa các đầu nối vật lý và những thuộc tính tương tự khác đều được
định nghĩa bởi các đặc tả lớp vật lý. Nếu bạn muốn ghi nhớ lớp 1 bằng vài từ ngắn gọn
thì hãy nghĩ ngay đến các tín hiệu và môi trường.
2.3.5 36BSự đóng gói dữ liệu :
Bạn biết rằng tất cả các hoạt động truyền tin trên mạng đều bắt đầu từ một
nguồn và nhắm đến một đích thông tin được gởi lên mạng được tham khảo đến như là
dữ liệu hay là các gói dữ liệu. Nếu một máy tính A (host A) muốn gởi dữ liệu đến một
-21-
máy tính B (host B) trước hết dữ liệu phải được gói bởi một quá trình gọi là đóng gói
(encapsulation).
Hoạt động đóng gói sẽ gói dữ liệu cùng với các thông tin giao thức cần thiết
trước khi chuyển đi. Do đó khi dữ liệu chuyển xuống xuyên qua các lớp của mô hình
OSI nó tiếp nhận các header các trailer và các thông tin khác (lưu ý rằng: từ header có
nghĩa là thông tin địa chỉ được thêm vào). Các mạng phải thực hiện theo 5 bước đàm
thoại để đóng gói dữ liệu:
Xây dựng dữ liệu: khi một user gởi một bức thư các ký tự alphabet được chuyển đổi
thành dạng dữ liệu có thể di chuyển xuyên qua liên mạng.
Gói dữ liệu để vận chuyển đầu cuối đến đầu cuối : dữ liệu được đóng gói để vận
chuyển qua liên mạng. Bằng cách dùng các phân đoạn dữ liệu (Segment) chức năng
vận chuyển đảm bảo rằng các chủ các thông điệp tại cả hai đầu cuối của hệ thống e-
mail có thể liên lạc một cách tin cậy.
Gắn địa chỉ mạng vào header: dữ liệu được đặt trong một gói (packet) hay
datagram chứa một header mạng với các địa chỉ luận lý của nguồn và đích. Các địa chỉ
này giúp các thiết bị mạng gởi các gói qua mạng dọc theo đường dẫn đã chọn.
Gắn địa chỉ cục bộ vào header liên kết dữ liệu: mỗi thiết bị mạng phải đặt gói
vào trong một frame. Frame cho phép kết nối với thiết bị mạng kế tiếp được nối trực
tiếp trên liên kết. Mỗi thiết bị mạng trên đường dẫn mạng đã chọn yêu cầu đóng frame
để nó kết nối được đến thiết bị kế tiếp.
Chuyển đổi thành các bit để truyền: frame phải được chuyển đổi thành các mẫu
bit 1 và 0 để truyền trên môi trường. Một chức năng đồng bộ (clocking) cho phép các
thiết bị phân biệt các bit này khi chúng di chuyển xuyên qua môi trường. Môi trường
trên liên mạng về mặt vật lý có thể thay đổi dọc theo đường dẫn. Ví dụ thông điệp e-
mail có thể bắt nguồn từ một LAN xuyên qua một backbone của khuôn viên trường đi
ra một liên kết WAN cho đến khi đạt đến đích của nó trên một LAN khác ở xa. Các
header và trailer được thêm vào khi dữ liệu di chuyển xuống các lớp của mô hình OSI.
-22-
13BULập trình mạng :
2.4.
70BHọ giao thức TCP/IP :
2.4.1 37BLiên lạc trên Internet :
2.4.1.1
Như trên đã nói để hai hay nhiều máy tính nói chuyện được với nhau chúng
phải dùng chung một ngôn ngữ chẳng hạn máy này phải gửi những tín hiệu gì đến máy
kia và máy kia phải gửi trả lại những tín hiệu nào để nhận biết. Trên Internet ngày nay
việc hai máy có thể trao đổi được với nhau đa số đề dựa theo giao thức cốt lõi là
TCP/IP (Transmission Control Protocol / Internet Protocol). Theo giao thức này mỗi
máy sẽ được đặt cho một số riêng biệt gọi là địa chỉ IP (IP address) có vai trò tương tự
số điện thoại chẳng hạn máy tính có tên www.microsoft.com thì có số IP là …Các số
IP này phải là duy nhất và không được trùng nhau (trên toàn thế giới). Khi bạn muốn
có máy tính của mình có địa chỉ IP để tham gia vào hệ thống Internet toàn cầu như là
một máy chủ (host hay server) ta phải đăng ký với tổ chức quốc tế InterNIC (Internet
Network Information Center) để nhận được một số IP riêng biệt.
Vậy tại sao vừa có địa chỉ IP lại vừa có tên riêng cho từng máy ? Dùng cái nào
để liên lạc với một máy chủ (như ở trên ta nên dùng 2TUwww.microsoft.comU2T hay ……..để
kết nối với máy chủ). Thật ra tên và địa chỉ IP là một nhưng địa chỉ IP được ghi bằng
số còn tên cho máy chủ lại được biểu diễn bằng chữ có ý nghĩa và gần gũi hơn với con
người. Với mỗi hệ thống đều có sự chuyển đổi trực tiếp từ tên vùng thành địa chỉ IP
thích hợp trước khi dữ liệu được gửi đi.
Ví dụ đối với Windows có thể tham khảo hai tập tin HOSTS và LMHOSTS đây
là hai tập tin văn bản (được coi như một cơ sở dữ liệu) để lưu trữ tập hợp các số IP
cùng với tên tương ứng. Ta có thể tự thêm vào địa chỉ IP và tên máy chủ cách nhau
bằng khoảng trắng. Khi có nhu cầu truy cập đến một máy ở xa qua giao thức mạng
ICP/IP nếu gõ vào tên máy chủ thì hệ thống sẽ tự động tìm địa chỉ IP tương ứng trong
-23-
tập tin này.
Tên của máy chủ còn được gọi là tên vùng (domain name) bởi vì chúng được
đặt theo thứ tự phân cấp của tên lãnh thỗ vùng tổ chức hay tên cá nhân … Mỗi nhóm
phân cấp cách nhau bằng một dấu chấm (.). Công việc theo dõi sự thay đổi tên được
phân phối qua Internet nhờ các máy chủ lớn DNS (Domain Name System) theo dõi các
máy chủ khác trong vùng con của chúng. Trước đây mỗi máy có thể tự mình lưu trữ
một tập tin chứa phần lớn các tên và địa chỉ của những máy chủ thông dụng (như trong
Windows là tập tin HOSTS hay LMHOSTS) nhưng ngày nay ta không làm như vậy
nữa mà đa số các gên vùng cũng như địa chỉ IP được lấy xuống từ các máy chủ DNS.
Khi đọc tên của một máy chủ ta đi từ trái sang phải. Nói chung là theo quy ước
từ phần riêng biệt đến phần chung nhất. Tuy nhiên không bắt buộc là như vậy ta vẫn
có thể đặt tên theo cách khác không nhất thiết chỉ gồm 3 hay 4 nhóm (ví dụ:
here.is.along.name.address.com.vn là hợp lệ) bởi vì cuối cùng thì tên vùng cũng được
hệ thống DNS chuyển thành địa chỉ IP mà thôi.
Giả sử bạn muốn trình duyệt (browser)) như IE hay Netscape truy tìm một tập
tin hay trang web của máy chủ Microsoft. Microft cung cấp cho bạn địa chủ của máy
chủ là 2TUwww.microsoft.comU2T. Đây chỉ là một chuỗi tên bình thường muốn kết nối được
với máy chủ trước tiên trình duyệt phải chuyển đổi được tên 2TUwww.microsoft.comU2T
thành địa chỉ IP tương ứng. Quá trình truy tìm địa chỉ IP diễn ra như sau:
2TUwww.microsoft.comU2T thành địa chỉ IP.
1-Trình duyệt yêu cầu hệ điều hành trên máy khách chuyễn chuỗi
2–Máy khách truy tìm xem tên 2TUwww.microsoft.comU2T có được ánh xạ trong tập
2TUwww.microsoft.comU2T thành địa chỉ IP gửi về cho trình duyệt. Nếu không máy khách tìm
tin HOSTS hay LMHOST hay không. Nếu có máy khách sẽ đổi tên
cách liên lạc với máy chủ DNS. Máy DNS lưu rất nhiều địa chỉ IP của các máy chủ
theo tên.
3 – Nếu tìm thấy địa chỉ IP của tên 2TUwww.microsoft.comU2T máy DNS sẽ gửi địa
-24-
chỉ IP về cho máy khách.
4 – Máy khách chuyển địa chỉ IP cho trình duyệt.
5 – Trình duyệt sử dụng địa chỉ IP liên lạc với máy chủ của Microsoft.
6 – Quá trình kết nối thành công. Máy chủ Microsoft sẽ trả thông tin yêu cầu về
cho máy khách.
* Lưu ý :
- Một địa chỉ IP cũng có thể được đặt cho nhiều tên khác nhau. Ví dụ bạn có thể
đặt trong tập tin HOSTS như sau:
HOSTS :
129.74.250.103 my.server.home
129.74.250.103 my.company.net
71BCách chuyển dữ liệu trên mạng giao thức TCP và UDP :
- Một máy cũng có thể có nhiều địa chỉ IP nếu có nhiều card giao tiếp mạng.
2.4.1.2
Quá trình chuyển dữ liệu trên mạng diễn ra khá phức tạp. Chi tiết quá
trình này diễn ra tương tự như trong thực tế ta gửi thư hay bưu phẩm trước hết phải ghi
rõ địa chỉ nơi đến (trường hợp này là địa chỉ IP của máy chủ) sau đó có thể gửi thông
thường hay gửi bảo đảm (tùy theo cách gửi mà thư hay bưu phẩm có chắc chắn đến
được tay người nhận hay không) người nhận sau khi nhận được có thể hồi âm trả lời là
đã nhận đủ hoặc bị mất mát gì đó trong quá trình chuyển tải. Người gửi có thể gửi tiếp
những phần bị mất (hoặc không cần gửi nữa).
Cách chuyển dữ liệu bảo đảm dựa vào giao thức TCP (Transmission
Control Protocol) còn cách chuyển không bảo đảm dựa vào giao thức UDP (User
Datagram Protocol).
Giao thức TCP gửi từng gói dữ liệu đi nơi nhận theo giao thức này phải
có trách nhiệm thông báo và kiểm tra xem dữ liệu đã đến đủ hay chưa có lỗi hay
không có lỗi. Trước khi chuyển dữ liệu bao giờ cũng có sự kết nối giữa máy gửi và
-25-
máy nhận. Do phải bảo đảm dữ liệu được truyền chính xác và luôn duy trì két nối nên
sử dụng giao thức TCP cần chiếm thêm một số tài nguyên của hệ thống và cách lập
trình cho giao thức này hơi khó (phải thực hiện các bước kiểm tra dữ liệu theo yêu cầu
của TCP). Truyền dữ liệu theo TCP thường áp dụng cho các dịch vụ như truyền tập tin
các dịch vụ trực tuyến trên Internet đòi hỏi độ tin cậy cao ….
Giao thức UDP ngược lại không đáng tin cậy lắm không có sự két nối
trước nào giữa nơi gửi và nơi nhận dữ liệu gửi đi mặc định rằng máy tính ở đầu nhận
luôn ở trạng thái sẵn sàng để tiếp đón dữ liệu gửi đến. Nếu dữ liệu gửi đến bị lỗi trong
quá trình truyền hay không nhận được đậy đủ giao thức UDP cũng không có thông tin
phản hồi gì lại cho nơi gửi. Tuy nhiên UDP không đòi hỏi nhiều tài nguyên của hệ
thống và cách lập trình lại tỏ ra đơn giản. Truyền dữ liệu theo giao thức UDP thường
được dùng trong những ứng dụng không đòi hỏi sự chính xác cao như dịch vụ thông
72BKết nối với Internet :
báo giờ tỉ giá hay các dịch vụ gửi nhắn tin ….
2.4.1.3
Ta có thể kết nối vào Internet thông qua dịch vụ của nhà cung cấp còn
gọi là ISP (hư VDC Cnet …) bằng đường điện thoại thông qua modem ADSL Leased
Line. Các nhà dịch vụ này đóng vai trò như những máy chủ (server) giúp dễ dàng truy
cập dữ liệu từ những vùng khác nhau trên mạng.
2.4.2 38BDịch vụ từ phía máy chủ và khái niệm cổng (PORT):
Khi kết nối vào máy chủ ta có thể yêu cầu máy chủ nhiều dịch vụ khác nhau
như dịch vụ truy tìm và đọc các trang web trên Internet dịch vụ gửi nhân e- mail dịch
vụ dò tìm hệ thống tên vùng DNS dịch vụ truyền file FTP ….. Mỗi dịch vụ đều có
cách gửi nhân dữ liệu theo quy ước riên. TCP và UDP chỉ chịu trách nhiệm đưa dữ liệu
từ một máy tính này đến một máy tính khác còn dữ liệu đó sẽ được gửi cho dịch vụ
nào thì phải thông qua một quy đinh nữa là cổng (hay Port). Mỗi chương trình dịch vụ
sẽ sử dụng một cổng khác nhau để truy xuất thông tin. Cổng là một số nguyên dương
-26-
có giá trị từ 1 đến 16383.
Máy chủ (server) sẽ quy định cổng được sẻ dụng cho mỗi loại dịch vụ. Thông
tin giữa máy khách (client) và máy chủ (server) phải sử dụng cổng tương ứng nhau thì
mới trao đổi với nhau được. Tuy nhiên hầu hết các chương trình dịch vụ nổi tiếng hiện
nay đều có quy định chuẩn cổng dành riêng cho mình như :
Dịch vụ : Cổng (Port).
FTP 21
HTTP 80
Telnet 23
Finger 79
SMTP 25
TFTP 69
Gopher 70
POP3 110
Nếu tự xây dựng một ứng dụng làm dịch vụ trên máy chủ ta phải chọn cho mình
một số cổng có giá trị khác với những giá trị cổng mà những dịch nổi tiếng đã sử dụng.
2.4.3 39BGiao tiếp trên mạng theo mô hình khách/chủ (client/server) và khái niệm
Socket:
Giao tiếp theo mô hình khách/chủ (Client/Server):
Có rất nhiều dịch vụ hỗ trợ trên Internet như e-mail nhóm tin (newsroup)
chuyển tập tin (file transfer) đăng nhập từ xa (remote login) truy tìm các trang web
….Những dịch vụ này được tổ chức và kiến trúc theo mô hình khách/chủ
(client/server). Các chương trình ở máy khách (client) như trình duyệt (web browser)
hay chương trình gửi nhận email sẽ tạo ra kết nối (connection) với một máy chủ ở xa
(server) sau đó gửi các yêu cầu đến máy chủ các chương trình dịch vụ trên máy chủ
như Web Server hay Mail server … sẽ xử lý những yêu cầu này và kết quả ngược về
-27-
cho máy khách (chẳng hạn Web server sẽ truy tìm và trả về cho máy khách các trang
web theo địa chỉ mà máy khách đưa đến còn Mail server thì lưu giữ và gửi về cho máy
khách những bức e-mail mới). Thông thường một dịch vụ trên máy chủ phục vụ rất
nhiều máy khách.
2.4.4 40BLập trình mạng thông qua Socket :
Như vậy trước khi yêu cầu một dịch vụ trên máy chủ thực hiện điều gì đó máy
khách (client) phải có khả năng kết nối được với máy chủ. Quá trình kết nối này được
thông qua một cơ chế trừu tượng hóa gọi là Socket (tạm dịch là “ cơ chế ổ cắm “). Kết
nối giữa máy khách và máy chủ tương tự như việc cắm phích điện vào ổ cắm điện.
Máy khách thường được coi như phích cắm điện còn máy chủ được coi như ổ cắm điện
một ổ cắm có thể cắm vào đó nhiều phích điện khác nhau cũng như một máy chủ có
thể kết nối và phục vụ cho rất nhiều máy khách.
Nếu kết nối Socket thành công thì máy khách và máy chủ có thể trao đổi dữ liệu
với nhau thực hiện các yêu cầu về dịch vụ trên máy chủ. Việc kết nối theo cơ chế
Socket cần biết hai thông tin chủ yếu đó là địa chỉ của máy cần kết nối và số hiệu cổng
của chương trình dịch vụ.
-28-
Chương 3 2BLập trình mạng trên môi trường Pocket PC
14BUCài đặt các phần mềm cần thiết:
3.1.
Các file cài đặt nằm trong thư mục soft.
3.1.1 41BCài đặt eMbedded Visual C++ 4.0
Bung nén tập tin eVC4.exe trong thư mục Soft\eVC trong đĩa CD kèm theo.
Bung nén xong tìm file CDKey.txt để lấy số Cdkey. (RT7H-KD36T-FRH8D-
6QH8P-VFJHQ).
Chạy file setup.exe để setup eVC4.
Chọn Next.
Hình 3.1
Chọn I accept the agreement chọn Next.
-29-
Hình 3.2
Điền số Cdkey vào rồi chọn Next.
Hình 3.3
Chọn Next.
Hình 3.4
Chọn nút Browse… để chọn thư mục cài đặt rồi chọn Next.
-30-
Hình 3.5
Ta chọn Continue để bắt đầu quá trình cài đặt.
Hình 3.6
Chọn các tùy chọn trong ô Option và thư mục cài đặt trong Change
Folder…chọn Continue.
Hình 3.7
Chờ khoảng vài phút xuất hiện hộp thoại chọn OK để kết thúc quá trình cài đặt.
Hình 3.8
3.1.2 42BCài đặt eVC4SP3.
-31-
Bung nén tập tin evc4sp3.exe trong thư mục SOFT\eVC4SP3 trong đĩa
CD kèm theo.
Chạy tập tin setup.exe
Chọn next.
Hình 3.9
Chọn I accept the terms in the License Agreement chọn next.
Hình 3.10
Chọn Install.
Hình 3.11
-32-
Chờ vài phút.
Hình 3.12
Chọn Finish để kết thúc quá trình cài đặt.
Hình 3.13
3.1.3 43BCài đặt Pocket PC 2003 SDK.
Chạy tập tin Microsoft Pocket PC 2003 SDK.msi trong thư mục SOFT\ PPC
2003 SDK trong CD kèm theo để cài đặt Microsoft Pocket PC 2003 SDK.
Chọn next.
.
Hình 3.14
-33-
Chọn I accept the terms in the License Agreement chọn Next.
Hình 3.15
Chọn next.
Hình 3.16
Chọn bản Custom hoặc Complete chọn next.
Hình 3.17
Chọn Change… để chọn thư mục cài đặt chọn Next>
-34-
Hình 3.18
Chọn Install để bắt đầu quá trình cài đặt.
Hình 3.19
Chọn Finish để hoàn thành cài đặt.
3.1.4 44BCài đặt Emulator:
Chúng ta lần lượt cài đặt 3 tập tin Windows Mobile 2003 Second Edition
Developer Resources.msi Windows Mobile 2003 Second Edition Emulator Images for
Pock.msi UK English Emulation Image; bung nén tập tin English-NoRadio. Các phần
mềm này nằm trong thư mục SOFT\Emulator.
Ở đây chỉ trình bày cách cài đặt Windows Mobile 2003 Second Edition
Developer Resources.msi. Hai phần sau ta cài tương tự.
Cài đặt Windows Mobile 2003 Second Edition Developer Resources.msi
Chạy tập tin Windows Mobile 2003 Second Edition Developer Resources.msi
trong đĩa CD kèm theo.
Chọn next.
-35-
Hình 3.20
Chọn I agree chọn Next.
Hình 3.21
Chọn thư mục cài đặt chọn next.
Hình 3.22
Chọn next.
-36-
Hình 3.23
Chọn close để kết thúc.
Hình 3.24
73BĐịnh nghĩa:
3.1.5 45BCài đặt LoopBack Adapter.
3.1.5.1
Loopback Adapter là một phần mềm có chức năng như card mạng. Nó là một
74BCách cài đặt:
thành phần của Windows XP Professional.
3.1.5.2
Sau đây là cách thiết lập Loopback Adapter:
Vào Control Panel chọn Add Hardware.
-37-
Hình 3.25 Màn hình Control panel.
Chọn Next.
Trong hộp thọai Is the hardware connected chọn Yes I have already
connected the hardware sau đó chọn Next.
Hình 3.26
Trong danh sách các phần cứng đã được kết nối chọn Add a new
hardware device sau đó chọn Next.
Hình 3.27
-38-
Trong hộp thọai kế tiếp chọn Install the hardware that I manually
select from a list(Advanced) sau đó chọn Next.
Hình 3.28
Trong danh sách Common hardware types chọn Network adapters sau
đó chọn Next.
Hình 3.29
Trong danh sách Manufacturer chọn Microsoft chọn Microsoft
Loopback Adapter trong danh sách Network Adapter sau đó chọn
Next.
-39-
Hình 3.30
Tiếp tục chọn Next.
Hình 3.31
Chọn Finish hoàn thành cài đặt Add Hardware Wizard.
3.1.6 46BCấu hình mạng:
Vào Control Panel mở Network Connections chọn Create a new connection.
Hình 3.32
-40-
Chọn next.
Hình 3.33
Chọn connect to the internet; chọn next
Hình 3.34
Chọn set up my connection manually. Chọn next.
Hình 3.35
Chọn connect using a dial-up modem chọn next.
-41-
Hình 3.36
Chọn next.
Hình 3.37
Chọn next.
Hình 3.38
Chọn next.
-42-
Hình 3.39
Chọn finish để hoàn thành.
15BUCác bước xây dựng một ứng dụng mạng trên máy Pocket PC
Hình 3.40
3.2.
(sử dụng lớp CSocket):
Hình 3.41 Mô hình lập trình mạng giữa Client và Server (Dùng API)
-43-
Create()
Create() Listen()
Connect() Accept()
Send() and Receive() Messages Send() and Receive() Messages
Client Server
Hình 3.42 Mô hình lập trình mạng giữa Client và Server
(Dùng MFC)
3.2.1 47BXây dựng dịch vụ trên Server :
Sử dụng API:
B1 : Khởi tạo winsock.
B2 : Tạo một socket nghe ngóng kết nối vào.
B3 : Gọi hàm bind() để kết buộc socket mới vừa tạo với một địa chỉ cục bộ.
B4 : Gọi hàm listen() để nghe ngóng kết nối vào từ Client.
B5 : Gọi hàm accept() để chấp nhận kết nối vào.
B6 : Dùng các hàm send() và recv() để trao đổi dữ liệu với client.
B7 : Đóng socket bằng hàm closesocket().
B8 : Làm sạch winsock.
-44-
Sử dụng MFC:
B1 : Tạo một socket có cổng xác định để thiết lập dịch vụ.
B2 : Gọi hàm Listen() để nghe ngóng kết nối vào từ Client.
B3 : Gọi hàm Accept() để chấp nhận kết nối vào.
B4 : Dùng các hàm Send() và Recieve() để trao đổi dữ liệu với client.
B5 : Đóng socket bằng hàm Close().
3.2.2 48BXây dựng ứng dụng trên Client :
Sử dụng API:
B1 : Khởi tạo winsock.
B2 : Tạo một socket để truy cập kết nối trên mạng
B3 : Gọi hàm connect() để kết nối đến Server.
B4 : Dùng các hàm send() và recv() để trao đổi dữ liệu với Server.
B5 : Đóng socket bằng hàm closesocket().
B6 : Làm sạch winsock
Sử dụng MFC:
B1 : Tạo một socket để truy cập kết nối trên mạng
B2 : Gọi hàm Connect() để kết nối đến Server.
B3 : Dùng các hàm Send() và Receive() để trao đổi dữ liệu với Server.
16BUChi tiết các hàm sử dụng trong từng bước
B4 : Đóng socket bằng hàm Close();
3.3.
75BClient:
3.3.1 49BSử dụng API:
3.3.1.1
Để sử dụng các hàm của Winsock trong ứng dụng ta cần phải include
Winsock.h vào trong mã nguồn của chúng ta để ta có thể liên kết với thư viện
-45-
93BKhởi tạo và làm sạch winsock.
winsock.lib.
3.3.1.1.1
Điều đầu tiên mà chúng ta cần làm để sử dụng được Winsock là cần phải bảo
đảm được rằng : phiên bản đúng của winsock.dll được tải vào bộ nhớ. Để làm được
chúng ta gọi hàm WSAStartup() được xác định như sau :
int WSAStartup(WORD wVersionRequired LPWSADATA lpWSAData)
wVersionRequired xác định phiên bản của Winsock mà ta muốn tải về. Đối với
Pocket PC giá trị này cần thiết cho phiên bản 1.1 được tạo bằng cách dùng macro
MAKEWORD(11). Tham số lpWSAData là một con trỏ trỏ đến cấu trúc WSAData
mà hàm WSAStartup() sẽ điền vào đó những thông tin về phiên bản của Winsock cần
tải xuống.
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR *lpVendorInfo;
} WSADATA;
Cả hai tham số wVersion và wHighVersion sẽ trả về phiên bản hiện hành của
Winsock thực sự được tải xuống bộ nhớ thường được thiết lập là 0x0101. Hai tham số
szDescription và szSystemStatus không được sử dụng trên Pocket PC và được thiết lập
là NULL. Tham số iMaxSockets chỉ số lượng socket tối đa mà ứng dụng của chúng ta
có thể mở ra. Không có sự bảo đảm nào cho ứng dụng của ta có thể mở những socket
này. Tham số iMaxUdpDg xác định kích thước tối đa của gói UDP datagram. Nếu giá
-46-
trị này là 0 thì không có giới hạn trong winsock này. Tham số cuối cùng lpVendorInfo
là con trỏ trỏ đến thông tin tùy chọn liên quan đến máy tính.
WSAStartup() sẽ trả về giá trị 0 nếu thành công ngược lại sẽ trả về một mã lỗi.
Trước khi ứng dụng kết thúc chúng ta nên gọi hàm WSACleanup() được xác
định như sau:
int WSACleanup(void);
Tuy nhiên hàm này thực sự không làm gì hết nó chỉ duy trì sự tương thích với
những ứng dụng desktop đã được nối cổng đến Windows CE.
Nếu có lỗi xảy ra khi gọi hàm winsock (ngoại trừ gọi hàm WSAStartup() nó sẽ
trả về một mã lỗi) hầu hết những hàm sẽ trả về SOCKET_ERROR của Winsock chuẩn
(được xác định trong winsock.h thường là -1).
Để lấy những thông tin về lỗi đã xảy ra bạn có thể gọi hàm WSAGetLastError()
để tìm nguyên nhân hàm bị lỗi.
int WSAGetLastError(int iError);
Tham số iError xác định mã lỗi mới.
Chúng ta có thể tìm những thông tin về mã lỗi riêng của Winsock trong tập tin
94BLuồng Socket :
tiêu đề winsock.h.
3.3.1.1.2
Luồng Socket có lẽ là loại giao thức truyền tin được dùng phổ biến nhất trên
TCP/IP. Socket TCP cung cấp cho ta dạng ống dữ liệu (data pipe) đáng tin cậy gần
như không bị lỗi giữa hai máy hai máy có thể gửi và nhận những luồng byte qua lại
95BTạo socket :
với nhau mà không có dữ liệu bị mất hay bị sao lại (dupliacate).
3.3.1.1.3
Bước đầu tiên trong việc thiết lập một kết nối mạng dùng winsock là tạo một
socket. Socket là một loại dữ loại tương tự như file handle xác định descriptor duy
nhất cho phép truy cập đến đối tượng mạng của bạn. Những thứ mà descriptor này xác
-47-
định không được trình bày chi tiết trong winsock specification mà được xác định rõ
trong winsock implementation cho nên chúng ta không thực sự biết giá trị đó có nghĩa
là gì. Tuy nhiên nội dung của desciptor là không quan trọng đối với chúng ta điều
quan trọng là chúng ta hiểu được Socket là cái mà chúng ta dùng để truy cập đến kết
nối mạng của bạn.
Để tạo một Socket ta dùng hàm socket() được xác định như sau :
SOCKET socket(int af int type int protocol)
Tham số af thể hiện address family của giao thức xác định loại giao thức của
socket sẽ được tạo. Pocket PC hỗ trợ cả socket AF_INET hoặc AF_IRDA. Nếu bạn
muốn tạo một socket cho giao tiếp hồng ngoại thì ta dùng AF_IRDA ngược lại ta dùng
AF_INET cho TCP/IP. Tham số type là loại giao tiếp của giao thức và có thể thiết lập
là SOCK_STREAM hay SOCK_DGRAM. Để tạo một Socket TCP ta dùng
SOCK_STREAM và SOCK_DGRAM cho UDP. Ta cũng dùng SOCK_STREAM cho
việc tạo Socket dùng giao tiếp hồng ngoại. Tham số cuối cùng protocol xác định loại
giao thức nào dùng với socket này. Nếu bạn muốn sử dụng giao thức TCP thì hãy
dùng giá trị IPPROTO_TCP và IPPROTO_UDP dành cho giao thức UDP.
Giá trị trả về của hàm này là một handle socket mới hoặc lỗi
INVALID_SOCKET. Nếu bạn muốn tìm nguyên nhân vì sao bạn không thể tạo ra
được socket bạn hãy dùng hàm WSAGetLastError ().
Đoạn mã sau trình bày cách tạo ra một kết nối socket.
// Create a connection-oriented socket
SOCKET s = socket(AF_INET SOCK_STREAM IPPROTO_TCP);
// Check to see if we have a valid socket
if(s == INVALID_SOCKET) {
int iSocketError = WSAGetLastError();
return FALSE;
}
-48-
96BKết nối đến Server (từ Client) :
3.3.1.1.4
Khi bạn đã tạo một socket bạn có thể dùng nó để thiết lập một kết nối đến
server. Ta dùng hàm connect() để thực hiện việc này :
int connect (SOCKET s const struct sockaddr *name int namelen);
Tham số đầu tiên s xác định socket descriptor được trả về bởi hàm socket().
Tham số name là socket address structure SOCKADDR_IN xác định server mà
ta định kết nối.Tham số namelen là chiều dài của bộ đệm dành cho tham số name
Nếu ta thành công trong việc thiết lập một kết nối đến Server xác định bởi tham
số name thì hàm này sẽ trả về giá trị 0 ngược lại lỗi một SOCKET_ERROER sẽ xảy
ra. Để tìm xem thông tin vì sao không thiết lập được kết nối ta gọi hàm
WSAGetLastError (). Nên nhớ rằng ta không thể gọi hàm connect() trên một socket đã
được kết nối.
Một khi một kết nối đã được thiết lập thì socket sẵn sàng gửi và nhận dữ liệu.
Chú ý rằng : Nếu một kết nối đã bị đứt (broken) trong lúc Client và Server đang truyền
tin với nhau thì ứng dụng của ta cần phải bỏ socket cũ và tạo một socket mới để thiết
lập lại việc truyền tin giữa Client và Server.
Ví dụ sau trình bày cách kết nối đến Server :
// First get the host information
HOSTENT *hostServer = gethostbyname("www.microsoft.com");
if(hostServer == NULL) {
int iSocketError = WSAGetLastError();
return FALSE;
}
// Set up the target device address structure
SOCKADDR_IN sinServer;
memset(&sinServer 0 sizeof(SOCKADDR_IN));
sinServer.sin_family = AF_INET;
-49-
sinServer.sin_port = htons(80);
sinServer.sin_addr =
*((IN_ADDR *)hostServer->h_addr_list[0]);
// Connect with a valid socket
if(connect(s (SOCKADDR *)&sinServer sizeof(sinServer)) ==
SOCKET_ERROR) {
int iSocketError = WSAGetLastError();
return FALSE;
}
// Do something with the socket
97BGửi và nhận dữ liệu :
closesocket(s);
3.3.1.1.5
Chúng ta đã thiết lập một kết nối đến server đã sẵn sàng cho việc gửi và nhận
dữ liệu giữa hai máy trên mạng. Trên một kết nối socket dữ liệu có thể được truyền cả
hai hướng Server và Client có thể dùng cùng phương thức để truyền tin với nhau.
Để truyền dữ liệu trên một kết nối socket ta dùng phương thức send() được xác
định như sau :
int send (SOCKET s const char *buf int len int flags);
Tham số s là socket handle mà ta đã dùng với hàm connect () ở trên và nó được
tạo lúc đầu bằng hàm socket(). Tham số buf là một con trỏ trỏ đến bộ đệm chứa dữ
liệu mà ta muốn gửi và chiều dài của nó được xác định bởi tham số len. Tham số cuối
cùng flags được dùng để xác định cách dữ liệu được gửi có giá trị là 0 hoặc
MSG_DONTROUTE. Thông thường tham số này được thiết lập là 0 và
MSG_DONTROUTE chỉ dùng cho việc kiểm tra hoặc định đường đi cho thông điệp.
Giá trị trả về của hàm send() là số byte thực sự được gửi trên mạng hoặc một
SOCKET_ERROR nếu có lỗi trong việc truyền dữ liệu.
-50-
Để nhận dữ liệu trên một socket ta dùng hàm recv() :
int recv (SOCKET s char *buf int len int flags);
Tương tự như trên tham số s chỉ socket mà chúng ta thiết lập để nhận dữ liệu.
Tham số thứ hai buf là một bộ đệm để nhận dữ liệu kích thước của nó được xác định
bởi tham số len. Cuối cùng tham số flags thường được thiết lập là 0.
Giá trị trả về của hàm recv() là số byte nhận được hoặc là 0 nếu kết nối bị đóng.
Hàm cũng sẽ trả về một SOCKET_ERROR nếu có lỗi xảy ra.
Chú ý rằng: cả hai hàm send() và recv() không luôn luôn đọc hoặc ghi chính xác
số lượng dữ liệu mà ta đã yêu cầu. Điều này là do TCP/IP cấp phát một số lượng không
gian bộ đệm có hạn cho hàng đợi dữ liệu đi và vào và thường thì bộ đệm này đầy khá
nhanh. Ví dụ nếu chúng ta yêu cầu một file 10 MB từ một trang web hàng đợi dữ liệu
vào của ta sẽ khóa cho đến khi ta đọc được dữ liệu từ hàng đợi này (dùng hàm
receive()). Việc truyền dữ liệu cũng tương tự như thế cho nên chúng ta cần đảm bảo
rằng : tất cả dữ liệu ra của chúng ta đã được gửi.
Ví dụ sau thể hiện việc gửi dữ liệu bộ đệm trên TCP :
// Send a request to the server
char cBuffer[1024] = "";
int nBytesSent = 0;
int nBytesIndex = 0;
// Set up the buffer to send
sprintf(cBuffer "GET / HTTP/1.0\r\n\r\n");
int nBytesLeft = strlen(cBuffer);
// Send the entire buffer
while(nBytesLeft > 0) {
nBytesSent = send(s &cBuffer[nBytesIndex] nBytesLeft 0);
if(nBytesSent == SOCKET_ERROR)
break;
-51-
// See how many bytes are left. If we still need to send loop
nBytesLeft -= nBytesSent;
nBytesIndex += nBytesSent;
98BVí dụ:
}
3.3.1.1.6
Ví dụ sau trình bày cách dùng socket TCP để tạo một client cơ bản để kết nối
với một trang web gửi yêu cầu và nhận trang web HTML mặc định. Khi thực hiện
thành công nó sẽ nội dung trên Message Box. Bộ đệm thực sự được trả về từ yêu cầu
này được trình bày trong hình sau :
Hình 3.43
// Initialize Winsock
WSADATA wsaData;
memset(&wsaData 0 sizeof(WSADATA));
if(WSAStartup(MAKEWORD(11) &wsaData) != 0)
return FALSE;
// Create a connection-oriented socket
SOCKET s = socket(AF_INET SOCK_STREAM IPPROTO_TCP);
// Check to see if we have a valid socket
if(s == INVALID_SOCKET) {
-52-
int iSocketError = WSAGetLastError();
return FALSE;
}
// Get the host information
HOSTENT *hostServer = gethostbyname("www.microsoft.com");
if(hostServer == NULL) {
int iSocketError = WSAGetLastError();
return FALSE;
}
// Set up the target device address structure
SOCKADDR_IN sinServer;
memset(&sinServer 0 sizeof(SOCKADDR_IN));
sinServer.sin_family = AF_INET;
sinServer.sin_port = htons(80);
sinServer.sin_addr =
*((IN_ADDR *)hostServer>h_addr_list[0]);
// Connect
if(connect(s (SOCKADDR *)&sinServer sizeof(sinServer)) ==
SOCKET_ERROR) {
int iSocketError = WSAGetLastError();
return FALSE;
}
// Send a request to the server
char cBuffer[1024] = "";
int nBytesSent = 0;
int nBytesIndex = 0;
// Set up the buffer to send
-53-
sprintf(cBuffer "GET / HTTP/1.0\r\n\r\n");
int nBytesLeft = strlen(cBuffer);
// Send the entire buffer
while(nBytesLeft > 0) {
nBytesSent = send(s &cBuffer[nBytesIndex] nBytesLeft 0);
if(nBytesSent == SOCKET_ERROR)
break;
// See how many bytes are left. If we still need to send loop
nBytesLeft -= nBytesSent;
nBytesIndex += nBytesSent;
}
// Get the response
TCHAR tchResponseBuffer[1024] = TEXT("\0");
char cResponseBuffer[1024] = "";
BOOL fBreak = FALSE;
int nBytesReceived = 0;
while(!fBreak) {
nBytesReceived = recv(s &cResponseBuffer[0] 1024 0);
if(nBytesReceived == SOCKET_ERROR)
break;
// Convert the data from ANSI to Unicode
mbstowcs(tchResponseBuffer cResponseBuffer nBytesReceived);
// Show the MessageBox
MessageBox(NULL tchResponseBuffer TEXT("Web Output") MB_OK);
// Check to see if this is the end of the HTTP response by
// looking for \r\n\r\n
if(_tcsstr(tchResponseBuffer TEXT("\r\n\r\n")))
-54-
fBreak = TRUE;
// Clear the buffers
memset(tchResponseBuffer 0 1024);
memset(cResponseBuffer 0 1024);
}
closesocket(s);
76BServer:
WSACleanup();
99BNhận một kết nối vào (Server) :
3.3.1.2
3.3.1.2.1
Sự khác nhau cơ bản của việc truyền dữ liệu giữa luồng kết nối Server và Client
là cách kết nối được thiết lập (lient thì tạo kết nối còn Server thì lắng nghe kết nối).
Mặt khác, cả hai đều sử dùng phương thức send() và recv() để trao đổi dữ liệu giữa hai
máy. Chúng ta đã tìm hiểu ở phía Client giờ đây ta bắt đầu tìm hiểu cách tạo một ứng
dụng theo yêu cầu của những dịch vụ kết nối vào (hình thành do gọi hàm connect()).
Điều đầu tiên mà chúng ta cần làm là tạo một socket; giống như ta đã làm ở phía Client
bằng cách gọi hàm socket().
Sau khi đã tạo socket rồi thay vì kết nối đến một Server ta để socket mới này ở
trạng thái lắng nghe kết nối vào. Để làm được việc đó chúng ta cần kết buộc (bind)
socket mới được tạo này với một địa chỉ cục bộ. Để tạo kết buộc này ta dùng hàm
bind().
int bind(SOCKET s const struct sockaddr *addr int namelen);
Tham số đầu tiên s là một handle của socket được tạo bởi hàm socket() và ta
sẽ dùng socket này để chở kết nối. Tham số addr là một con trỏ trỏ đến address buffer
được xác định bởi giao thức mà ta muốn sử dụng. Nếu ta muốn dùng giao thức TCP/IP
chuẩn thì chúng ta sẽ dùng bộ đệm SOCKADDR_IN. Nếu dùng giao thức hồng ngoại
thì sử dùng SOCKADDR_IRDA. Tham số cuối cùng namelen chỉ kích thước của cấu
-55-
trúc địa chỉ (address structure) mà tham số addr đã dùng.
Nếu không có lỗi hàm bind() sẽ trả về 0 ngược lại một SOCKET_ERROR sẽ
xuất hiện.
Ví dụ sau sẽ kết buộc kết nối TCP trên cổng 80 đến một socket cho tất cả địa chỉ
IP trên thiết bị.
SOCKADDR_IN sListener;
memset(&sListener 0 sizeof(SOCKADDR_IN));
// Set up the port to bind on
sListener.sin_family = AF_INET;
sListener.sin_port = htons(80);
sListener.sin_addr.s_addr = htonl(INADDR_ANY);
// Create a TCP socket
SOCKET s = socket(AF_INET SOCK_STREAM IPPROTO_TCP);
if(s == INVALID_SOCKET)
return FALSE;
// Bind to the socket
if(bind(s (SOCKADDR *)&sListener sizeof(sListener)) ==
SOCKET_ERROR) {
int iSocketError = WSAGetLastError();
return FALSE;
}
Chú ý rằng: Ta đã dùng địa chỉ IP INADDR_ANY thay vì địa chỉ IP của
Adapter. Dùng INADDR_ANY làm cho chúng ta có thể kết buộc socket vào tất cả
những địa chỉ IP có sẵn trên thiết bị của chúng ta do đó những kết nối vào trên bất kỳ
giao diện nào cũng được chấp nhận bởi socket của chúng ta.
Khi socket đã được kết buộc vào địa chỉ (hoặc nhiều địa chỉ) chúng ta cần đặt
socket này ở chế độ lắng nghe. Điều này làm cho socket có thể chờ những kết nối vào
-56-
int listen(SOCKET s int backlog);
Tham số s chỉ socket đã kết buộc. Tham số backlog xác định kích thước của
hàng đợi cho kết nối vào thường được thiết lập là SOMAXCONN (trên Pocket PC
hiện nay chỉ giới hạn cho hai kết nối). Hàng đợi backlog được dùng khi cùng lúc có
nhiều kết nối vào. Khi hàng đợi đầy tất cả những yêu cầu khác sẽ bị từ chối cho đến
khi một yêu cầu kết nối được lấy ra khỏi hàng đợi bởi hàm accept().
Nếu có lỗi hàm listen() sẽ trả về giá trị SOCKET_ERROR ngược lại là giá trị 0
Cuối cùng để nhận socket của kết nối vào chúng ta cần gọi hàm accept() được
xác định như sau.
SOCKET accept(SOCKET s struct sockaddr *addr int * addrlen);
Tham số s chỉ socket mà chúng ta đã đặt ở chế độ lắng nghe ở trên. Tham số
addr chỉ bộ đệm dùng để nhận hoặc là một cấu trúc SOCKADDR_IN hoặc là
SOCKADDR_IRDA tùy thuộc vào giao thức mà socket đã dùng chứa những thông tin
về kết nối vào. Tham số cuối cùng addrlen chỉ kích thước của cấu trúc addr.
Chú ý rằng: phương thức accept() không trả về giá trị ngay lập tức. Điều này là
do accept() là hàm khóa nghĩa là nó sẽ không trả về giá trị cho đến khi có kết nối từ
một client hoặc socket lắng nghe bị hủy (ta cũng có thể thiết lập một tùy chọn socket
để đặt nó ở chế độ không khóa). Khi hàm accept() trả về thì giá trị của nó hoặc là một
socket handle mới cho client kết nối vào hoặc là một lỗi SOCKET_ERROR. Tất cả
những thông tin về client kết nối vào sẽ được thể hiện ở socket handle mới này trong
100BVí dụ:
khi socket ban đầu tiếp tục lắng nghe nhiều kết nối khác.
3.3.1.2.2
Ví dụ sau thể hiện việc Server lắng nghe kết nối vào của một Client yêu cầu một
trang Web dùng giao thức HTTP và trả về cho Client một hồi đáp.
// Initialize Winsock
WSADATA wsaData;
-57-
memset(&wsaData 0 sizeof(WSADATA));
if(WSAStartup(MAKEWORD(11) &wsaData) != 0)
return FALSE;
// Create a connection-oriented socket
SOCKET s = socket(AF_INET SOCK_STREAM IPPROTO_TCP);
// Check to see if we have a valid socket
if(s == INVALID_SOCKET) {
int iSocketError = WSAGetLastError();
return FALSE;
}
SOCKADDR_IN sListener;
memset(&sListener 0 sizeof(SOCKADDR_IN));
// Setup the port to bind on
sListener.sin_family = AF_INET;
sListener.sin_port = htons(80);
sListener.sin_addr.s_addr = htonl(INADDR_ANY);
// Bind to the socket
if(bind(s (SOCKADDR *)&sListener sizeof(sListener)) ==
SOCKET_ERROR) {
int iSocketError = WSAGetLastError();
return FALSE;
}
// Listen for incoming connections
if(listen(s SOMAXCONN) == SOCKET_ERROR) {
int iSocketError = WSAGetLastError();
return FALSE;
}
-58-
// Wait for a connection
SOCKADDR_IN sIncomingAddr;
memset(&sIncomingAddr 0 sizeof(SOCKADDR_IN));
int iAddrLen = sizeof(SOCKADDR_IN);
SOCKET sIncomingSocket = accept(s (SOCKADDR *)
&sIncomingAddr &iAddrLen);
if(sIncomingSocket == SOCKET_ERROR) {
int iSocketError = WSAGetLastError();
return FALSE;
}
// We have an incoming socket request
char cResponseBuffer[1024] = "";
int nBytesReceived = 0;
// Get a basic request. In reality we would want to check
// the HTTP request to see if it's valid but let's just
// send a simple response.
nBytesReceived = recv(sIncomingSocket &cResponseBuffer[0]
1024 0);
if(nBytesReceived == SOCKET_ERROR) {
int iSocketError = WSAGetLastError();
return FALSE;
}
// Send out a response
char cBuffer[1024] = "";
int nBytesSent = 0;
int nBytesIndex = 0;
// Setup the buffer to send
-59-
sprintf(cBuffer &"HTTP/1.0 200 OK\r\n\r\nTest
Response\r\n\r\n");
int nBytesLeft = strlen(cBuffer);
// Send the entire buffer
while(nBytesLeft > 0) {
nBytesSent = send(sIncomingSocket &cBuffer[nBytesIndex]
nBytesLeft 0);
if(nBytesSent == SOCKET_ERROR)
break;
// See how many bytes are left. If we still need to send loop
nBytesLeft -= nBytesSent;
nBytesIndex += nBytesSent;
}
// Close the sockets
closesocket(sIncomingSocket);
closesocket(s);
77BĐóng Socket :
WSACleanup();
3.3.1.3
Một khi đã hoàn thành việc sử dụng socket dù ở trên Server hay Client chúng
ta phải giải phóng tài nguyên thiết bị đã được liên kết với socket đó
Trước khi ta thực sự đóng một socket ta nên gọi hàm shutdown(). Chúng ta có
thể trực tiếp hủy một socket bằng cách đóng nó nhưng tốt hơn ta nên gọi hàm
shutdown() trước tiên bởi vì điều này đảm bảo rằng: tất cả dữ liệu trong hàng đợi vận
chuyển TCP đã được gửi hoặc nhận hết trước khi socket bị đóng:
int shutdown(SOCKET s int how);
Tham số s là handle của socket mà ta muốn đóng. Tham số how xác định cách
-60-
thức những hàm socket xảy ra sau được xử lý trên socket này. Có ba tùy chọn :
SD_RECEIVE SD_SEND SE_BOTH. Chọn SD_RECEIVE sẽ ngăn chặn việc gọi
hàm recv() và SD_SEND sẽ ngăn chặn việc gọi hàm send(). Rõ ràng SD_BOTH sẽ
dừng việc gửi và nhận dữ liệu trên socket (tuy nhiên tất cả dữ liệu đã nằm trong hàng
đợi sẽ được xử lý).
Nếu không có lỗi hàm shutdown() sẽ trả về 0. Một khi socket đã bị shutdown()
chúng ta không thể dùng nó được nữa trừ khi chúng ta đóng nó bằng hàm
closesocket().
int closesocket(SOCKET s);
với s làm handle của socket mà ta muốn đóng.
78BGiới thiệu về lớp CSocket:
3.3.2 50BSử dụng MFC:
3.3.2.1
Hình 3.44 ơ đồ kế thừa của lớp CSocket.
Lớp CSocket kết thừa từ lớp cha của nó là CAsyncSocket do đó nó thừa hưởng
những thành phần Windows sockets API của lớp CasyncSocket.Xem chi tiết trong
MSDN.
Những phần tiếp theo chúng ta sẽ khảo sát những thành phần cơ bản của lớp
79BClient:
CSocket hỗ trợ cho việc lập trình mạng.
3.3.2.2
Để có thể sử dụng được thư viện CSocket cần phải làm hai công việc một là
thêm dòng #include
Công việc thứ hai cần làm là để có thể sử dụng thư viện CSocket là phải gọi
-61-
hàm AfxSocketInit(NULL) trước khi sử dụng các hàm của lớp Csocket mục đích là để
khởi tạo thư viện. Nếu không mọi hàm sử dụng thư viện tuy được biên dịch thành công
nhưng vẫn báo lỗi khi thi hành chương trình.
Để kết nối đến một cổng chở kết nối trước tiên ta phải khởi tạo một socket với
hàm như sau:
BOOL Create(): Hàm tạo socket ở phia Client không có tham số. Nếu việc tạo
socket thành công thì hàm sẽ trả về kết quả khác 0; nếu xảy ra lỗi thì hàm sẽ trả về kết
quả là 0. Ta có thể dùng hàm int GetLastError() để lấy thông tin mã lỗi.
Sau khi đã tạo một socket thành công bước tiếp theo là ta sẽ dùng socket đó để
kết nối đến Server đang mở dịch vụ ta sẽ dùng hàm sau để kết nối:
BOOL Connect( LPCTSTR Error! Hyperlink reference not valid. UINT
Error! Hyperlink reference not valid.)
lpszHostAddress: là địa chỉ của Server mà ta cần kết nối đến. Ta có thể truyền
cho tham số này theo tên miền hoặc theo địa chỉ IP. Ví dụ: “2TUftp.microsoft.comU2T” hoặc
“128.56.22.8” đều được. Mỗi máy tính đều có một địa chỉ IP mặc định là “127.0.0.1”
hoặc “localhost”. Do đó nếu như chúng ta thực hành kết nối cho cả Server và Client
trên cùng một máy thì ta có thể kết nối đến địa chỉ này.
nHostPort: Là số cổng của dịch vụ mà server đang mở. Ví dụ cổng của dịch vụ
web là 80 cổng của dịch vụ ftp là 21......
Sau đây là ví dụ cho việc tạo và kết nối đến dịch vụ cổng 1111 trên Server.
CSocket skConnect;
If(!skConnect.Create() || !skConnect.Connect(“localhost”1111))
{
cout<<”ket noi khong thanh cong”< exit(0); } else cout<<”kết nối thành công”; -62- Sau khi đã kết nối được server ta sẽ dùng hai hàm sau đây để gửi và nhận thông điệp. Hàm gửi thông điệp: int Send(const void* Error! Hyperlink reference not valid.int Error! Hyperlink reference not valid.int Error! Hyperlink reference not valid. = 0); lpBuf: là bộ đệm dùng để chứa dữ liệu được gửi. nBuffeLen: Chiều dài của dữ liệu lpBuf dưới dạng Byte. nFlags: Mặc định là 0 ta có thể không cần truyền tham số này. Nếu không có lỗi xảy ra thì hàm này sẽ trả về giá trị tổng số kí tự được gửi(giá trị này phải nhỏ hơn giá trị của nBufLen). Nếu xảy ra lỗi thì hàm sẽ trả về giả trị SOCKET_ERROR. Chúng ta có thể tìm được mã lỗi thông qua hàm int GetLastError(). Xem thêm trong MSDN. Hàm nhận thông điệp từ socket: virtual int Receive( void*Error! Hyperlink reference not valid.int Error! Hyperlink reference not valid.int Error! Hyperlink reference not valid. = 0); Tất cả những tham số này đều có ý nghĩa tương tự như các tham số của hàm Send() ở trên.Nếu không có lỗi xảy ra thì giá trị trả về của hàm này là tổng số byte nhận được. Nếu đã đóng kết nối socket thì kết quả trả về là 0. Nếu xảy ra lỗi thì kết quả trả về sẽ là một SOCKET_ERROR được xác định trong hàm int GetLastError(). Tham khảo mã lỗi trong MSDN. Ví dụ sau sẽ trình bày minh họa cho việc gửi và nhận dữ liệu: Char msg[1000]; Int msg_len; While(1) { cout<<”Nhap thong diep: “; gets(msg); -63- msg_len = strlen(msg); //Gửi thông điệp đến server skConnect.Send(&msg_len sizeof(msg_len)); //Gửi chiều dài thông điệp. skConnect.Send(msgmsg_len);//Gửi nội dung thông điệp. //Nhận thông điệp đến server skConnect.Receive(&msg_len sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msgmsg_len);//Nhận nội dung thông điệp. } Cuối cùng sau khi hoàn tất truyền dữ liệu đóng kết nối với câu lệnh như sau: virtual void Close(); Sau đây là toàn bộ nội dung đã thực hiện cho client. CSocket skConnect; If(!skConnect.Create() || !skConnect.Connect(“localhost”1111)) { cout<<”ket noi khong thanh cong”< exit(0); } else cout<<”kết nối thành công”; Char msg[1000]; Int msg_len; While(1) { cout<<”Nhap thong diep: “; gets(msg); msg_len = strlen(msg); -64- //Gửi thông điệp đến server skConnect.Send(&msg_len sizeof(msg_len)); //Gửi chiều dài thông điệp. skConnect.Send(msgmsg_len);//Gửi nội dung thông điệp. //Nhận thông điệp đến server skConnect.Receive(&msg_len sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msgmsg_len);//Nhận nội dung thông điệp. skConnect[msg_len] = 0;//Kết thúc chuỗi. } 80BServer: skConnect.Close(); 3.3.2.3 Cũng tương tự như các phía Client điều trước tiên chúng ta cần làm là khởi tạo một socket dùng để tạo dịch vụ. Câu lệnh khởi tạo socket phía server có hơi khác so với phía Client. Nguyên mẫu của hàm như sau: BOOL Create(UINT Error! Hyperlink reference not valid. = 0int Error! Hyperlink reference not valid. = SOCK_STREAMLPCTSTR Error! Hyperlink reference not valid. = NULL); nSocketPort: Số cổng mà ta sử dụng để mở dịch vụ. nSocketType: SOCK_STREAM(tương ứng với giao thức TCP) hoặc là SOCK_DGRAM(tương ứng với giao thức UDP). Mặc định của hàm là SOCK_STREAM. Error! Hyperlink reference not valid. :là chuỗi con trỏ chứa địa chỉ mạng của một kết nối socket. Mặc định là NULL. Giá trị khác 0 sẽ được hàm này trả về nếu không có lỗi xảy ra. Ngược lại là 0.Chúng ta có thể tham khảo mã lỗi thông qua hàm int GetLastError(); Trong CSocket chúng không cần thiết phải gọi hàm bind() bởi vì sau khi gọi hàm Create() thì tự động hàm bind() sẽ được gọi để kết buộc socket đến địa chỉ xác -65- định. Sau khi đã khởi tạo socket thành công tiếp theo ta sử dụng hàm Listen để nghe ngóng kết nối. BOOL Listen(int Error! Hyperlink reference not valid. = 5); Error! Hyperlink reference not valid.: Chiều dài tối đa có mà hàng đợi của những kết nối vào có thể chứa được. Giá trị này giới hạn trong khoảng từ 1 đến 5; mặc định là 5. Nếu không có lỗi thì hàm này sẽ trả về giá trị khác không; ngược lại sẽ cho giá trị là không và mã lỗi sẽ được xác định thông qua hàm GetLastError. Để chấp nhận một kết nối vào trước tiên cần phải khởi tạo socket bằng hàm Create sau đó một backlog (dãy) các kết nối vào sẽ được xác định bởi hàm Listen. Sau đó những kết nối này sẽ được chấp nhận bởi hàm Accept. Hàm Listen chỉ áp dụng cho những socket hỗ trợ kết nối điển hình là dạng SOCK_STREAM. Socket này được đặt ở chế độ “bị động”_ chế độ mà những kết nối vào được thừa nhận và được xếp hàng chờ đợi bởi tiến trình này. Hàm này thường được sử dụng ở Server(hoặc có thể ở bất kỳ ứng dụng nào muốn chấp nhận kết nối vào) cho phép có nhiều hơn một kết nối được yêu cầu ở cùng một thời điểm. Nếu có yêu cầu kết nối nhưng hàng đợi đã đầy(nConnectionBacklog = 5) thì client sẽ nhận một lỗi WSAECONNREFUSED. Tiếp theo ta sử dụng hàm Accept để chấp nhận kết nối. virtual BOOL Accept( CAsyncSocket& Error! Hyperlink reference not valid. SOCKADDR* Error! Hyperlink reference not valid. = NULL int* Error! Hyperlink reference not valid. = NULL ); rConnectedSocket: Tham chiếu đến socket mới được lấy tự Client. lpSockAdd : Là một con trỏ đến cấu trúc SOCKADDR socket kết nối đến. Nếu -66- lpSockAddr hoặc lpSocketAddrLen có giá trị là NULL thì sẽ không có thông tin nào về địa chỉ của socket vừa được kết nối được trả về. Mặc định là NULL. Error! Hyperlink reference not valid. : Là con trỏ trỏ đến chiều dài chương trình của của địa chỉ trong lpSockAddr dưới dạng byte. Tương tự như các phương thức ở trên giá trị trả về của hàm này là khác 0 nếu hàm chương trình thực hiện thành công ngược lại sẽ bằng 0. Mã lỗi sẽ được xác định thông qua hàm GetLastError.(xem chi tiết trong MSDN). Sau khi đã chấp nhận kết nối ta có thể dùng các hàm Send Receive để truyền và nhận thông điệp và hàm Close để đóng socket giống như đã làm ở Client. Ví dụ sau sẽ trình bày cách thức một server chấp nhận một kết nối vào: Các biến được sử dụng trong ví dụ này sẽ gồm 2 biến CSocket một để mở cổng và một để truyền dữ liệu (Trong thực tế một cổng có thể cho phép nhiều client nối vào khi đó vẫn chỉ có một CSocket để mở cổng nhưng sẽ có nhiều CSocket để truyền dữ liệu). CSocket skListen skConnect; If(!skListen.Create(1111) || !skListen.Listen() || !skListen.Accept(skConnect)) { cout<<”server socket bi loi”; exit(0); } else { //truyền thông điệp qua lại giữa client và server. char msg[1000]; int msg_len; while(1); { //Nhận thông điệp từ Client -67- skConnect.Receive(&msg_len sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msgmsg_len);//Nhận nội dung thông điệp. skConnect[msg_len] = 0; //Kết thúc chuỗi. //Gửi thông điệp đến Client skConnect.Send(&msg_len sizeof(msg_len)); //Gửi chiều dài thông điệp. skConnect.Send(msgmsg_len);//Gửi nội dung thông điệp. } skConnect.Close(); } -68- 17BUMô tả ứng dụng minh họa: 4.1. 81BMục đích: 4.1.1 51BỨng dụng chat giữa Pocket PC với máy tính để bàn: 4.1.1.1 Ứng dụng này cho phép Pocket PC cùng lúc có thể liên lạc trao đổi thông tin với 82BChức năng: nhiều máy tính để bàn khác nhau thông qua một máy chủ. 101BServer: 4.1.1.2 Dùng một máy tính để bàn làm server. Server sẽ tạo một dịch vụ trên cổng 1111 cho phép các client kết nối vào. Sau khi các client kết nối thành công vào dịch vụ mà Server đang mở các client sẽ được yêu cầu đăng ký nick name khác nhau để có thể liên 102BClient: lạc với nhau. Client bao gồm một bên là Pocket PC còn lại là các máy tính để bàn. Sau khi server đã mở dịch vụ các client có thể kết nối vào dịch đó. Nếu kết nối thành công thì các client được phép đăng ký nick name và có thể trao đổi thông tin được với nhau. 83BMục đích: 4.1.2 52BỨng dụng điều khiển Power Point: 4.1.2.1 Ứng dụng này cho phép chúng ta sử dụng Pocket Pc để điều khiển Power Point ở máy -69- 84BChức năng: chủ. 103BServer: 4.1.2.2 Dùng máy tính làm server. Trên máy tính đang làm server sẽ đồng thời đang chạy trình chiếu Power Point. Server sẽ nhận thông điệp từ Client(Pocket PC). Server chỉ nhận 6 loại thông điệp đó là: lên xuống đầu trang cuối trang số trang bất kỳ thoát. Từ những 104BClient: thông điệp này mà server sẽ điều khiển Power theo những yêu cầu của thông điệp đó. Sau khi server đã mở dịch vụ client(Pocket PC) sẽ kết nối đến server. Nếu kết nối 18BUChi tiết các hàm liên quan đến ứng dụng: thành công client sẽ gửi đến server 6 thông điệp nêu trên để server xử lý. 4.2. Do đặc điểm của chương trình chat giữa Pocket PC và các máy tính để bàn có kết nối mạng là Pocket PC có khả năng cùng lúc có thể liên lạc được với nhiều máy tính để bàn do đó trong ứng dụng này đòi hỏi phải sử dụng kỹ thuật lập trình song song. Trong MFC có hỗ trợ cơ chế đa tuyến ở đây chúng ta chỉ đề cập đến một vài thành phần của cơ chế đa tuyến để hỗ trợ cho ứng dụng minh họa. Đa tuyến: Cơ chế lập trình đa tiểu trình(MultiThread) cho phép ứng dụng có thể có nhiều tác vụ được xử lý song song. Điều này giúp cho chương trình tăng được hiệu quả tính toán và linh hoạt hơn trong xử lý. Một tiểu trình cơ bản phải có hàm xử lý của tiểu trình (ThreadProc) hàm này sẽ chứa nội dung xử lý của tiểu trình. Có thể dung một số hàm khác nhau để tạo tiểu trình chẳng hạn: CreateThread _beginthreadAfxBeginThread....Ở đây ta sẽ khảo sát hàm CreateThread. HANDLE CreateThread ( -70- SEC_ATTRS SecurityAttributes ULONG StackSize SEC_THREAD_START StartFunction PVOID ThreadParameter ULONG CreationFlags PULONG ThreadId ); Quan trọng nhất trong hàm này là tham số StartFunction đây là hàm cài đặt cho thread cần tạo. ThreadParameter là một biến 4 byte được truyền vào hàm MyThread biến pParam nếu không cần truyền tham số ta chỉ cần truyền NULL. Cách kết thúc một tiểu trình. Ngoài việc một luồng tự kết thúc khi hàm dùng để cài đặt luồng kết thúc ta còn có thể yêu cầu luồng kết thúc tức thời. Tuy nhiên việc kết thúc hàm theo kiểu “thô bạo” như vậy sẽ dẫn đến việc không hủy bỏ đúng đắn những tài nguyên đã được cấp như mở file kết nối mạng... Kết thúc luồng hiện hành: dùng hàm ExitThread(dwExitCode) trong đó dwExitCode là mã lỗi trả về thường là bằng 0. Để kết thúc một luồng khác ta phải có handle của luồng đó (hThread) được trả về khi tạo luồng khi đó dùng hàm TerminateThread(hThread dwExitCode) để kết thúc một luồng. Tóm lại để tạo một tiểu trình ta cần thực hiện theo các bước cơ bản sau đây: Viết một hàm xử lý cho tiểu trình DWORD WINAPI ThreadProc( LPVOID Error! Hyperlink reference not valid.) { //...đoạn code xử lý cho tiểu trình return 0; -71- } Khai báo một biến kiểu HANDLE để giữ lại Handle của Thread ví dụ: HANDLE hThread; Gọi hàm CreateThread hThread = CreateThread(NULL 0 (LPTHREAD_START_ROUTINE)ThreadProc NULL 0 NULL); if (hThread == NULL) { //Không tạo được Thread } Khi muốn kết thúc thread ta gọi hàm TerminateThread như sau: TerminateThread(hThread 0);//kết thúc luồng bất kỳ. 19BUMô tả hoạt động của ứng dụng minh họa. Hoặc ExitThread(0);//Kết thúc luồng hiện hành. 4.3. 4.3.1 53BỨng dụng chat giữa Pocket PC với máy tính để bàn: -72- Kết nối server Server Client Tạo
tuyến
Nhận
kết
nối Nếu
kết
nối
thành
công Gửi thông diệp Tạo tuyến nhận
thông điệp Kiểm tra nick Nếu
chưa
tồn
tại Nếu
đã
tồn
tại -Thông điệp đến
client khác.
-Gửi thông điệp
“exit” nếu ngừng
kết nối. - Lưu nick.
-Thông báo thành
công. Gửi nick vừa
nhận cho các client và
ngược lại. - Lưu nick tạm thời.
-Thông báo nick đã tồn
tại gửi “exist” và nick
tạm thời. -“thanhcong”: Gán nick tạm
cho nick vừa nhận.
-“exist”:Nhận nick tạm yêu
cầu tạo nick mới.
-“server exit”:Không thể kết
nối server.
-“nick”:Lưu nick vào danh
sách đưa nick lên ListBox.
-“mess”:hiển thị thông điệp
lên màn hình.
-“exit”:Xóa nick vừa nhận ra
khỏi danh sách xóa ra khỏi
ListBox. Gửi về client Tạo
tuyến
xử lý -“taonick”:chưa tồn tại: Gán nick tạm cho nick vừa
nhận.Gửi ”thanhcong” về client.Nếu tồn tại gửi “exist”
về client.
-“exit”: Xóa nick vừa nhận. Gửi “exit” và nick vừa
nhần về cho các client khác.
-Ngược lại nhận nick client gửi client nhận và thông
điệp. Gửi nick”mess” thông điệp của client gửi cho
client nhận. Tạo dịch vụ Hình 4.1 4.3.2 54BỨng dụng điều khiển Power Point: -73- Server
Tạo dịch vụ Pocket PC
Kết nối server. Nếu
kết nối
thành
công Nhận
kết nối.
Tạo
tuyến
xử lý -Gửi các thông điệp: lên
xuống đầu trang cuối
trang số trang bất kỳ
”exit” đến server. -Nhận các thông điệp biên dịch các thông
điệp thành mã phím tướng ứng gửi đến
Power Point.Nếu thông điệp “exit” đóng
socket đóng tuyến xử lý. Tiến trình
Power Point. 20BUMô tả thuộc tính phương thức chủ yếu của ứng dụng minh họa: Hình 4.2 4.4. 85BServer: 4.4.1 55BỨng dụng chat giữa Pocket PC với máy tính để bàn: 4.4.1.1 105BThành phần dữ liệu chủ yếu: Lớp chủ yếu của Server là lớp CsocketServerDlg. UTên dữ liệu: UChức năng: Socket skListenskAccept[100] Socket lưu thông tin Client. SOCKET hSock[100] Handle của skListenskAccept. HANDLE h[100] Handle của các tiểu trình. Client_Struct Cl[100] Cấu trúc của Client(gồm nickname, số thứ tự) ClistBox m_Danhsach ListBox thể hiện danh sách nickname client. 106BPhương thức chủ yếu: Cbutton m_Taodichvu Biến điều khiển nút Tạo Dịch Vụ. UTên phương thức UChức năng -74- void OnTaodichvu Tạo dịch vụ chat. DWORD INAPI ServiceThread Tạo tuyến chờ đợi kết nối. void ReceiveThread Tạo tuyến xử lý các thông điệp từ client. void OnThoatdichvu Thoát dịch vụ. 86BClient: void OnThoat,void OnClose Thoát chương trình. 4.4.1.2 107BThành phần dữ liệu: Lớp yếu CsocketClientDlg. UTên dữ liệu. UChức năng. CSocket skSend Socket kết nối server. tongso Lưu trữ tổng số client. Client client[100] Lưu trữ thông tin client(nick, số thứ tự). m_Dsctongso Tổng số người được gửi(dịch vụ Conference). CString m_Danhsachchon[100] Danh sách người được chọn(dịch vụ Conference). BOOL m_Nhieunguo Biến xác định dịch vụ là gửi một người hay Conference. ClistBox m_Danhsach Listbox hiển thị nick name các client. Cstring m_ResultString Màn hình hiển thị kết quả. 108BPhương thức: Cstring m_SendString Lưu trữ thông điệp cần gửi. UTên phương thức UChức năng. -75- BOOL OnInitDialog Khởi tạo giá trị mặc định. void OnConnect Kết nối server. DWORD WINAPI Tuyến nhận thông điệp từ server. ReceiveThread DestroyWindow Xử lý sự kiện tắt cửa sổ. OnChon Kích hoạt dịch vụ Conference. OnThoichon Thoát dịch vụ Conference. OnSelchangeDanhsach Xử lý sự kiện chọn trên ListBox. 87BServer: 4.4.2 56BỨng dụng điều khiển Power Point: 109BThành phần dữ liệu: 4.4.2.1 UTên dữ liệu UChức năng. HANDLE h Handle của tuyến tạo dịch vụ nhận thông điệp từ client CsocketskServerskClient,skServerskClient Socket tạo dịch vụ và socket lưu thông tin 110BPhương thức: client. UTên phương thức UChức năng. BOOL OnInitDialog Khởi tạo giá trị ban đầu cho dữ liệu void OnTaodichvu Tạo dịch vụ điều khiển Power Point. -76- DWORD WINAPI Tuyến nhận thông điệp từ client. ReceiveThread(LPVOID lp) 88BClient: HWND findWindowHandle Tìm Handle của các cửa sổ. 111BThành phần dữ liệu: 4.4.2.2 UTên dữ liệu. UChức năng. CSocket skClient Socket để kết nối server. CString ServerAddress Lưu địa chỉ server. 112BPhương thức: Cstring m_So Lưu số slide cần hiển thị. UTên phương thức UChức năng. BOOL DestroyWindow Xử lý sự kiện đóng cửa sổ. BOOL OnInitDialog Khởi tạo giá trị ban đầu cho dữ liệu. void OnKetnoiserver Kết nối server. OnLen Di chuyển lên. OnXuong Di chuyển xuống. OnDautrang Di chuyển lên đầu trang. OnCuoitrang Di chuyển xuông cuối trang. Ongui Gửi số trang bất kỳ. 21BUMô tả màn hình kết quả của ứng dụng OnNgungketnoi Ngừng kết nối. 4.5. -77- 89BServer: 4.5.1 57BỨng dụng chat giữa Pocket PC với máy tính để bàn: 4.5.1.1 Hình 4.3 Màn hình Server chat Nút Tạo Dịch Vụ: Cho phép khởi động dịch vụ chat. Nút Thoát Dịch Vụ: Cho phép dừng dịch vụ chat. Nút Thoát: Thoát khỏi chương trình. Listbox Danh sách: Hiển thị tất cả nick name của các client đã kết nối thành 90BClient: công đến server. 4.5.1.2 Hình 4.4 Màn hình Chat của Client trên máy tính để bàn. Nút kết nối Server: Hiển thị màn hình đăng nhập cho phép nhập vào địa chỉ của Server đang mở dịch vụ. -78- Hình 4.5 Màn hình đăng nhập địa chỉ kết nối server. Nếu kết nối thành công xuất hiện màn hình đăng nhập nick name: Hình 4.6 Màn hình đăng nhập nick name. Cho phép đăng nhâp nick name của client. Nick name này được dùng như là tên gọi để các client có thể giao tiếp trao đổi với nhau. Nếu đăng ký nick name thành công thì trong ListBox “Danh sách” sẽ thể hiện tất cả các nick name của các client đã kết nối đến dịch vụ. Lúc đó chúng ta chỉ cần click chọn một trong những nick name đó để có thể liên lạc. Sau khi đã chọn một nick name ta có thể nhập thông điệp vào trong textbox bên dưới chọn nút Gửi để gửi thông điệp. Khi có thông điệp của client nào đó gửi đến thì bên cạnh nick name của client đó sẽ xuất hiện thêm chữ new bên cạnh. Chúng ta chỉ cần click chọn để xem thông điệp. Mặt khác chúng ta có thể click nút chọn trong nhóm Gửi nhiều người để có thể gửi cùng lúc một thông điệp cho nhiều người. -79- Hình 4.7 Màn hình cho phép chọn gửi nhiều người. ListBox Danh sách liệt kê tất cả những nick name đang kết nối đến server. Ta dùng các nút “>>><<<” để có thể chọn hoặc không chọn các các nick cần gửi. Nút Thôi chọn để ngưng dịch vụ gửi nhiều người. Nút “Tạo Nick name”: Dùng để tạo nick name mới gửi đến server. Nút “Ngừng kết nối”: Dùng để ngừng kết nối đến server. Nút “Thoát”: Dùng để thoát chương trình. 91BServer: 4.5.2 58BỨng dụng điều khiển Power Point: 4.5.2.1 Hình 4.8 Màn hình server điều khiển Power Point. Nút “Tạo dịch vụ”: Dùng để tạo dịch vụ điều khiển Power Point. Nút “Thoát dịch vụ”: Dùng để thoát dịch vụ điều khiển Power Point. Nút “Thoát”: Dùng thoát chương trình. Static Box “Di chuyển”: Dùng để hiển thị những yêu cầu từ Client(Pocket PC). -80- 92BClient: Power Point Client Kết nối Server Ngừng kết nối Điều khiển Power Point Len Xuong Dau trang Cuoi trang Thoat Gui 4.5.2.2 Hình 4.9 Màn hình điều khiển Power Point. Nút Kết nối server: Dùng để kết nối đến server điều khiển Power Point. Sau khi nhấn chọn nút này màn hình đăng nhập địa chỉ server sẽ hiện ra chúng ta sẽ nhập địa chỉ server đang mở dịch vụ điều khiển Power Point. Nếu đăng ký thành công chúng ta có thể sử dụng các nút điều khiển để điều khiển Power Point. Nút Ngừng kết nối: Ngừng kết nối đến server. Nút Len: Gửi yêu cầu di chuyển lên đến server. Nút Xuong: Gửi yêu cầu di chuyển xuống đến server. Nút Dau trang: Gửi yêu cầu di lên đầu trang đến server. Nút Cuoi trang: Gửi yêu cầu di chuyển xuống cuối trang đến server. Một text box dùng để nhập số slide cần di chuyển đến. Nút Gui: Gửi yêu cầu di chuyển đến số slide tương ứng với số được nhập trong text box. Nút Thoát: Thoát chương trình. -81- 22BUNhững kết quả đã đạt được 5.1. - Đã giới thiệu được những kiến thức cơ bản cần thiết để viết một ứng dụng mạng trên máy Pocket PC thông qua socket. - Giới thiệu tương đối đầy đủ những kiến thức lập trình liên quan hỗ trợ cho lập trình mạng như: đa tuyến đồng bộ tiến trình các hàm gửi thông điệp window.... - Sau những kiến thức mới điều có những ví dụ minh họa giúp cho người đọc có thể mau chóng hiểu được những kiến thức mới. - Hai ứng dụng minh họa thể hiện tương đối đầy đủ những kỹ thuật cơ bản trong 23BUĐề xuất hướng phát triển. lập trình mạng đặc biệt trên Pocket PC. 5.2. - Tiếp tục nghiên cứu các tài liệu về lập trình mạng trên máy Pocket PC về những chủ đề như: WinInet sử dụng cổng số và cổng hồng ngoại connection manager..... - Xây dựng cơ sở dữ liệu cho Ứng dụng chat giữa Pocket PC với máy tính để bàn: Xây dựng những chat room cho phép các client kết nối. Từ đó lưu trữ thông điệp gửi đến các client không kết nối đến server. Sau khi client đó kết nối đến server thì server sẽ gửi về những thông điệp offline đó(tương tự như Yahoo chat). Xây dựng thêm chức năng gửi file gửi hình ảnh. - Nâng cao ứng dụng điều khiển Power Point: Điều khiển một Power Point xác định nếu hệ điều hành đang chạy nhiều cửa sổ Power Point. Sử dụng các phím mũi tên của chính Pocket PC để điều khiển Power Point. -82- Tiếng việt: [1] Đặng Văn Đức - Lê Quốc Hưng (1999) Lập trình Window Bằng Visual C++ Nhà Xuất Bản Giáo Dục. [2] Nguyễn Đình Tê Tự Học Lập Trình Visual C++ MFC qua các ví dụ Nhà Xuất Bản Lao Động – Xã Hội. [3] Nguyễn Hồng Sơn Giáo Trình Hệ Thống Mạng Máy Tính CCNA Semester 1 Nhà Xuất Bản Giáo Dục. [4] Võ Thạch Chí Trường (2005) bao_cao_nien_luan_Pocket PC. [5] http://www.fit.hcmuns.edu.vn/~tlhdu/classes/hdhnc/ Tiếng Anh: [1] Addison Wesley Pocket PC Network Programming eBookLiB. [2] MSDN Libarary – April 2005. -83- 5BPhụ lục. UXây dựng Server: Chương trình chat giữa Client và Server. #include "stdafx.h" #include "Server.h" #include "afxsock.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // The one and only application object CWinApp theApp; using namespace std; int _tmain(int argc TCHAR* argv[] TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL) NULL ::GetCommandLine() 0)) { // TODO: change error code to suit your needs cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } else -84- { AfxSocketInit (NULL); CSocket socketListen socketAccept; char sMsg[4096]; int nMsgLen; cout<<"Server dang cho ket noi............."< if(!socketListen.Create (12345) || !socketListen.Listen () || !socketListen.Accept (socketAccept)) { cout<<"Khong tao duoc Socket"; exit(0); } cout<<"Server da nhan duoc ket noi "; do { socketAccept.Receive (&nMsgLensizeof(nMsgLen)); socketAccept.Receive (sMsgnMsgLen); sMsg[nMsgLen] = 0; cout<<"Nhan :"; cout< if(strcmpi(sMsg"exit")==0) break; cout<<"Gui : "; gets(sMsg); nMsgLen = strlen(sMsg); socketAccept.Send (&nMsgLensizeof(nMsgLen)); socketAccept.Send(sMsgnMsgLen); -85- }while(strcmpi(sMsg"exit") != 0); //Dong cac socket socketAccept.Close (); socketListen.Close (); } return nRetCode; UXây dựng Client: } #include "stdafx.h" #include "SocketClient.h" #include "afxsock.h" #include "conio.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // The one and only application object int menu(); CWinApp theApp; using namespace std; int _tmain(int argc TCHAR* argv[] TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL) NULL ::GetCommandLine() 0)) -86- { // TODO: change error code to suit your needs cerr << _T("Fatal Error: MFC initialization failed") << endl; nRetCode = 1; } else { // TODO: code your application's behavior here. AfxSocketInit(NULL);//khoi tao CSocket socketConnect; char sMsg[4096]sServerAddress[] = "127.0.0.1"; int nMsgLen; char header; if (!socketConnect.Create()|| !socketConnect.Connect(sServerAddress1111)) { cout<<"Khong ket noi duoc Server"; exit(0); } cout<<"ket noi server thanh cong "< do { cout<<" Thong diep :"; gets(sMsg); nMsgLen=strlen(sMsg); socketConnect.Send(&nMsgLensizeof(nMsgLen)); socketConnect.Send(sMsgnMsgLen); -87- if(strcmpi(sMsg”exit”)==0) break; socketConnect.Receive(&nMsgLensizeof(nMsgLen)); socketConnect.Receive(sMsgnMsgLen); sMsg[nMsgLen]= 0;//end of string cout< }while(strcmpi(sMsg”exit”)!= 0); //Dong socket ket noi socketConnect.Close(); } return nRetCode; } -88- Tiếng việt: [1] Đặng Văn Đức - Lê Quốc Hưng (1999) Lập trình Window Bằng Visual C++ Nhà Xuất Bản Giáo Dục. [2] Nguyễn Đình Tê Tự Học Lập Trình Visual C++ MFC qua các ví dụ Nhà Xuất Bản Lao Động – Xã Hội. [3] Nguyễn Hồng Sơn Giáo Trình Hệ Thống Mạng Máy Tính CCNA Semester 1 Nhà Xuất Bản Giáo Dục. [4] Võ Thạch Chí Trường (2005) bao_cao_nien_luan_Pocket PC. [5] http://www.fit.hcmuns.edu.vn/~tlhdu/classes/hdhnc/ Tiếng Anh: [1] Addison Wesley Pocket PC Network Programming eBookLiB. [2] MSDN Libarary – April 2005. -89-Chương 4 3BỨng dụng minh họa
4.1.1.2.1
4.1.1.2.2
4.1.2.2.1
4.1.2.2.2
4.4.1.1.1
4.4.1.1.2
4.4.1.2.1
4.4.1.2.2
4.4.2.1.1
4.4.2.1.2
4.4.2.2.1
4.4.2.2.2
Chương 5 4BĐánh giá đề tài và đề xuất hướng phát triển kế
tiếp
Danh mục tài liệu tham khảo.
Danh mục tài liệu tham khảo.