Lập trình mạng trên máy Pocket PC

pdf 90 trang vanle 2290
Bạn đang xem 20 trang mẫu của tài liệu "Lập trình mạng trên máy Pocket PC", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdflap_trinh_mang_tren_may_pocket_pc.pdf

Nội dung text: Lập trình mạng trên máy Pocket PC

  1. Simpo PDF Merge and Split Unregistered Version - 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 .
  2. Simpo PDF Merge and Split Unregistered Version - Lời cảm ơn Sau gần sáu tháng làm việ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 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.
  3. Simpo PDF Merge and Split Unregistered Version - 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.
  4. Simpo PDF Merge and Split Unregistered Version - Mục lục Chương 1 Giới thiệu về đề tài 6 1.1. Cơ sở của đề tài : 6 1.2. Mục tiêu của đề tài : 6 1.3. Phạm vi của đề tài : 6 1.4. Cấu trúc của luận văn : 7 Chương 2 Khảo sát những vấn đề kỹ thuật liên quan .Error! Bookmark not defined. 2.1. Máy tính Pocket PC : Error! Bookmark not defined. 2.1.1 Định nghĩa : Error! Bookmark not defined. 2.1.2 Một vài khái niệm về phần cứng Pocket PC :Error! Bookmark not defined. 2.2. Pocket PC Emulator ( 2003 ) : Error! Bookmark not defined. 2.2.1 Định nghĩa Emulator: Error! Bookmark not defined. 2.2.2 Sử dụng Emulator : Error! Bookmark not defined. 2.2.3 Các yêu cầu cho Emulator: Error! Bookmark not defined. 2.2.4 Định cấu hình Emulator: Error! Bookmark not defined. 2.2.5 Tắt Emulator: Error! Bookmark not defined. 2.2.6 Những hạn chế của Emulator: Error! Bookmark not defined. 2.3. Sơ lược về mạng : Error! Bookmark not defined. 2.3.1 Nguồn , đích và các gói dữ liệu : Error! Bookmark not defined. 2.3.2 Môi trường truyền dẫn : Error! Bookmark not defined. 2.3.3 Giao thức : Error! Bookmark not defined. 2.3.4 Mô hình tham chiếu OSI : Error! Bookmark not defined. 2.3.5 Sự đóng gói dữ liệu : Error! Bookmark not defined. 2.4. Lập trình mạng : Error! Bookmark not defined. 2.4.1 Liên lạc trên Internet : Error! Bookmark not defined. 2.4.2 Dịch vụ từ phía máy chủ và khái niệm cổng (PORT) :Error! Bookmark not defined. 2.4.3 Giao tiếp trên mạng theo mô hình khách/chủ ( client/server ) và khái niệm Socket : Error! Bookmark not defined. 2.4.4 Lập trình mạng thông qua Socket : Error! Bookmark not defined. Chương 3 Lập trình mạng trên môi trường Pocket PCError! Bookmark not defined. 3.1. Cài đặt các phần mềm cần thiết: Error! Bookmark not defined. 3.1.1 Cài đặt eMbedded Visual C++ 4.0 Error! Bookmark not defined. 3.1.2 Cài đặt eVC4SP3. Error! Bookmark not defined. 3.1.3 Cài đặt Pocket PC 2003 SDK Error! Bookmark not defined. 3.1.4 Cài đặt Emulator: Error! Bookmark not defined. 3.1.5 Cài đặt LoopBack Adapter Error! Bookmark not defined. 3.1.6 Cấu hình mạng: Error! Bookmark not defined. 3.2. Các bước xây dựng một ứng dụng mạng trên máy Pocket PCError! Bookmark not defined. 3.2.1 Xây dựng dịch vụ trên Server : Error! Bookmark not defined. 3.2.2 Xây dựng ứng dụng trên Client : Error! Bookmark not defined.
  5. Simpo PDF Merge and Split Unregistered Version - 3.3. Chi tiết các hàm sử dụng trong từng bước Error! Bookmark not defined. 3.3.1 Sử dụng API: Error! Bookmark not defined. 3.3.2 Sử dụng MFC: Error! Bookmark not defined. Chương 4 Ứng dụng minh họa Error! Bookmark not defined. 4.1. Mô tả ứng dụng minh họa: Error! Bookmark not defined. 4.1.1 Ứng dụng chat giữa các Pocket PC với nhau hoặc Pocket PC với máy tính để bàn: Error! Bookmark not defined. 4.1.2 Ứng dụng điều khiển Power Point: Error! Bookmark not defined. 4.2. Chi tiết các hàm liên quan đến ứng dụng: Error! Bookmark not defined. 4.3. Mô tả hoạt động của ứng dụng minh họa Error! Bookmark not defined. 4.3.1 Ứng dụng chat giữa các Pocket PC hoặc Pocket PC với máy tính để bàn: Error! Bookmark not defined. 4.3.2 Ứng dụng điều khiển Power Point: Error! Bookmark not defined. 4.4. Mô tả thuộc tính, phương thức chủ yếu của ứng dụng minh họa:Error! Bookmark not defined. 4.4.1 Ứng dụng chat giữa các Pocket PC hoặc Pocket PC với máy tính để bàn: Error! Bookmark not defined. 4.4.2 Ứng dụng điều khiển Power Point: Error! Bookmark not defined. 4.5. Mô tả màn hình kết quả của ứng dụng Error! Bookmark not defined. 4.5.1 Ứng dụng chat giữa các Pocket PC hoặc Pocket PC với máy tính để bàn: Error! Bookmark not defined. 4.5.2 Ứng dụng điều khiển Power Point: Error! Bookmark not defined. Chương 5 Đánh giá đề tài và đề xuất hướng phát triển kế tiếpError! Bookmark not defined. 5.1. Những kết quả đã đạt được Error! Bookmark not defined. 5.2. Đề xuất hướng phát triển Error! Bookmark not defined. Danh mục tài liệu tham khảo. Error! Bookmark not defined. Phụ lục. Error! Bookmark not defined.
  6. Simpo PDF Merge and Split Unregistered Version - Giới thiệu về đề tài. Cơ sở của đề tài : 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ề môi trường lập trình mạng trên Pocket PC. Mục tiêu của đề tài :  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 các Pocket PC với nhau hoặc giữa Pocket PC và máy tính để bàn; chương trình điều khiển Power Point bằng Pocket PC). Phạm vi của đề tài : 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:
  7. Simpo PDF Merge and Split Unregistered Version -  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.  Xây dựng ứng dụng minh họa. Cấu trúc của luận văn : Luận văn này có cấu trúc như sau:  Chương 1 Giới thiệu về đề tài. 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.
  8. Simpo PDF Merge and Split Unregistered Version - Chương 2 Khảo sát những vấn đề kỹ thuật liên quan Máy tính Pocket PC : Đị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.
  9. Simpo PDF Merge and Split Unregistered Version - Một vài khái niệm về phần cứng Pocket PC : Màn hình xúc cảm : 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 bit/pixel (bits per pixel). Bút và bàn phím : 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).
  10. Simpo PDF Merge and Split Unregistered Version - 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à 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ã Morse và cài đặt nó ở nhà. In ấn : In ấn hiện nay không được hỗ trên Pocket PC. Nguồn điện: 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ự phòng để tránh mất dữ liệu nếu pin chính hết năng lượng. CPU: Pocket PC sử dụng họ vi xử lí ARM. Bộ xử lí ARM cung cấp sự kết hợp xuất sắc giữa độ thực thi cao và tiêu hao năng lượng ít. Bộ nhớ: 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 đó.
  11. Simpo PDF Merge and Split Unregistered Version - 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ệ đ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 nén và chuyển nên các file nén thực thi chậm. Cổng nối tiếp cài đặt sẵn: 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ữ liệu thông qua một modem kết nối đến cradle. Cổng giao tiếp hồng ngoại: 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 máy desktop. Pocket PC Emulator ( 2003 ) : Đị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. Sử 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.
  12. Simpo PDF Merge and Split Unregistered Version - Các yêu cầu cho Emulator: 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. Đị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 cài đặt như thế nào sang chương 3 chúng ta sẽ tìm hiểu. Phần này mô tả cách định cấu hình cho emulator trước khi sử dụng lần đầu. Định cấu hình Platform Manager: 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.  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
  13. Simpo PDF Merge and Split Unregistered Version - 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).  Á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. Định cấu hình Pocket PC Connection Manager: 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: Đị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.
  14. Simpo PDF Merge and Split Unregistered Version -  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.
  15. Simpo PDF Merge and Split Unregistered Version -  Bảo đảm Chắc 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. Lưu ý: eMbedded Visual Basic không còn được hỗ trợ nữa. Di chuyển các file đến và đi khỏi Emulator: 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. Tắ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
  16. Simpo PDF Merge and Split Unregistered Version - 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 sau. 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.
  17. Simpo PDF Merge and Split Unregistered Version - Nhữ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 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 của máy tính phát triển chạy emulator. Sơ lược về mạng : 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 .
  18. Simpo PDF Merge and Split Unregistered Version - Nguồ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 đí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 tìn 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. Mô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.
  19. Simpo PDF Merge and Split Unregistered Version - Giao 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. 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. Mô 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 dế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ụ
  20. Simpo PDF Merge and Split Unregistered Version - 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à 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
  21. Simpo PDF Merge and Split Unregistered Version - 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 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. Sự đó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ữ
  22. Simpo PDF Merge and Split Unregistered Version - liệu đến một 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 goi 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.
  23. Simpo PDF Merge and Split Unregistered Version - Lập trình mạng : Liên lạc trên Internet : Họ giao thức TCP/IP : 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ố đều 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 www.microsoft.com 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 tập tin này.
  24. Simpo PDF Merge and Split Unregistered Version - 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 tê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à www.microsoft.com. Đâ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 www.microsoft.com thành địa chỉ IP tương ứng. Quá trình truy tìm địa chỉ IP diễn ra như sau: 1-Trình duyệt yêu cầu hệ điều hành trên máy khách chuyễn chuỗi www.microsoft.com thành địa chỉ IP. 2–Máy khách truy tìm xem tên www.microsoft.com có được ánh xạ trong tập tin HOSTS hay LMHOST hay không . Nếu có máy khách sẽ đổi tên www.microsoft.com thành địa chỉ IP gửi về cho trình duyệt . Nếu không máy khách tìm 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 www.microsoft.com , máy DNS sẽ gửi địa chỉ IP về cho máy khách.
  25. Simpo PDF Merge and Split Unregistered Version - 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 - 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 . Cách chuyển dữ liệu trên mạng , giao thức TCP và UDP : 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à 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à
  26. Simpo PDF Merge and Split Unregistered Version - 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 báo giờ , tỉ giá hay các dịch vụ gửi nhắn tin .
  27. Simpo PDF Merge and Split Unregistered Version - Kết nối với Internet : 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 (như 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. Dị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 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
  28. Simpo PDF Merge and Split Unregistered Version - 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. Giao 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ề 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. Lậ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ơ
  29. Simpo PDF Merge and Split Unregistered Version - 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ụ.
  30. Simpo PDF Merge and Split Unregistered Version - Lập trình mạng trên môi trường Pocket PC Cài đặt các phần mềm cần thiết: Các file cài đặt nằm trong thư mục soft. Cà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. Hình 3.2
  31. Simpo PDF Merge and Split Unregistered Version -  Đ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. Hình 3.5  Ta chọn Continue để bắt đầu quá trình cài đặt.
  32. Simpo PDF Merge and Split Unregistered Version - 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 Cài đặt eVC4SP3.  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.
  33. Simpo PDF Merge and Split Unregistered Version - 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  Chọn Finish để kết thúc quá trình cài đặt.
  34. Simpo PDF Merge and Split Unregistered Version - Hình 3.12 Cà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.13  Chọn I accept the terms in the License Agreement chọn Next. Hình 3.14  Chọn next.
  35. Simpo PDF Merge and Split Unregistered Version - Hình 3.15  Chọn bản Custom hoặc Complete chọn next. Hình 3.16  Chọn Change để chọn thư mục cài đặt chọn Next> Hình 3.17  Chọn Install để bắt đầu quá trình cài đặt.
  36. Simpo PDF Merge and Split Unregistered Version - Hình 3.18  Chọn Finish để hoàn thành cài đặt. Cà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. Hình 3.19  Chọn I agree chọn Next. Hình 3.20
  37. Simpo PDF Merge and Split Unregistered Version -  Chọn thư mục cài đặt chọn next. Hình 3.21  Chọn next. Hình 3.22  Chọn close để kết thúc. Hình 3.23
  38. Simpo PDF Merge and Split Unregistered Version - Cài đặt LoopBack Adapter. Định nghĩa: Loopback Adapter là một phần mềm có chức năng như card mạng. Nó là một thành phần của Windows XP Professional. Cách cài đặt: Sau đây là cách thiết lập Loopback Adapter:  Vào Control Panel chọn Add Hardware.  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.24  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.25
  39. Simpo PDF Merge and Split Unregistered Version -  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.26  Trong danh sách Common hardware types chọn Network adapters sau đó chọn Next. Hình 3.27  Trong danh sách Manufacturer chọn Microsoft chọn Microsoft Loopback Adapter trong danh sách Network Adapter sau đó chọn Next.
  40. Simpo PDF Merge and Split Unregistered Version - Hình 3.28  Tiếp tục chọn Next. Hình 3.29  Chọn Finish hoàn thành cài đặt Add Hardware Wizard. Cấu hình mạng:  Vào Control Panel mở Network Connections chọn Create a new connection.  Chọn next.
  41. Simpo PDF Merge and Split Unregistered Version - Hình 3.30  Chọn connect to the internet; chọn next Hình 3.31  Chọn set up my connection manually. Chọn next. Hình 3.32  Chọn connect using a dial-up modem chọn next. Hình 3.33  Chọn next.
  42. Simpo PDF Merge and Split Unregistered Version - Hình 3.34  Chọn next. Hình 3.35  Chọn next. Hình 3.36  Chọn finish để hoàn thành.
  43. Simpo PDF Merge and Split Unregistered Version - Hình 3.37 Các bước xây dựng một ứng dụng mạng trên máy Pocket PC (sử dụng lớp CSocket): Hình 3.38 Mô hình lập trình mạng giữa Client và Server(Dùng API)
  44. Simpo PDF Merge and Split Unregistered Version - Create() Create() Listen() Connect() Accept() Send() and Send() and Receive() Receive() Messages Messages Server Client Hình 3.39 Mô hình lập trình mạng giữa Client và Server(Dùng MFC) Xâ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 .  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 .
  45. Simpo PDF Merge and Split Unregistered Version - 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() . Xâ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 . B4 : Đóng socket bằng hàm Close(); Chi tiết các hàm sử dụng trong từng bước Sử dụng API: Client: Để 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 winsock.lib . Khởi tạo và làm sạch winsock .
  46. Simpo PDF Merge and Split Unregistered Version - Đ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(1,1). 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á 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.
  47. Simpo PDF Merge and Split Unregistered Version - 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 tiêu đề winsock.h. Luồng Socket : 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 với nhau mà không có dữ liệu bị mất hay bị sao lại (dupliacate). Tạo socket : 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 socke. 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 đị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ị
  48. Simpo PDF Merge and Split Unregistered Version - đó 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; }
  49. Simpo PDF Merge and Split Unregistered Version - Kết nối đến Server ( từ Client ) : 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; sinServer.sin_port = htons(80);
  50. Simpo PDF Merge and Split Unregistered Version - 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 closesocket(s); Gửi và nhận dữ liệu : 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.
  51. Simpo PDF Merge and Split Unregistered Version - Để 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; // See how many bytes are left. If we still need to send, loop nBytesLeft -= nBytesSent;
  52. Simpo PDF Merge and Split Unregistered Version - nBytesIndex += nBytesSent; } Ví dụ: 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.40 // Initialize Winsock WSADATA wsaData; memset(&wsaData, 0, sizeof(WSADATA)); if(WSAStartup(MAKEWORD(1,1), &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; }
  53. Simpo PDF Merge and Split Unregistered Version - // 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 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);
  54. Simpo PDF Merge and Split Unregistered Version - 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"))) fBreak = TRUE; // Clear the buffers memset(tchResponseBuffer, 0, 1024); memset(cResponseBuffer, 0, 1024); } closesocket(s); WSACleanup();
  55. Simpo PDF Merge and Split Unregistered Version - Server: Nhận một kết nối vào ( Server ) : 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 (Client 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 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
  56. Simpo PDF Merge and Split Unregistered Version - 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 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
  57. Simpo PDF Merge and Split Unregistered Version - 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 khi socket ban đầu tiếp tục lắng nghe nhiều kết nối khác. Ví dụ: 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; memset(&wsaData, 0, sizeof(WSADATA)); if(WSAStartup(MAKEWORD(1,1), &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
  58. Simpo PDF Merge and Split Unregistered Version - 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; } // 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();
  59. Simpo PDF Merge and Split Unregistered Version - 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 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
  60. Simpo PDF Merge and Split Unregistered Version - nBytesLeft -= nBytesSent; nBytesIndex += nBytesSent; } // Close the sockets closesocket(sIncomingSocket); closesocket(s); WSACleanup();
  61. Simpo PDF Merge and Split Unregistered Version - Đóng Socket : 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 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. Sử dụng MFC: Giới thiệu về lớp CSocket: Hình 3.41 Sơ đồ kế thừa của lớp CSocket.
  62. Simpo PDF Merge and Split Unregistered Version - 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 CSocket hỗ trợ cho việc lập trình mạng. Client: Để 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 vào đầu tập tin có sử dụng lớp Csocket. 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 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 lpszHostAddress, UINT nHostPort). 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ụ: “ftp.microsoft.com” 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
  63. Simpo PDF Merge and Split Unregistered Version - 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”<<endl; exit(0); } else cout<<”kết nối thành công”; 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* lpBuf, int nBuffeLen, int nFlags = 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(const void* lpBuf, int nBuffeLen, int nFlags = 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;
  64. Simpo PDF Merge and Split Unregistered Version - While(1) { cout<<”Nhap thong diep: “; gets(msg); 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(msg,msg_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(msg,msg_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”<<endl; exit(0); } else cout<<”kết nối thành công”; Char msg[1000]; Int msg_len; While(1) { cout<<”Nhap thong diep: “;
  65. Simpo PDF Merge and Split Unregistered Version - gets(msg); 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(msg,msg_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(msg,msg_len);//Nhận nội dung thông điệp. skConnect[msg_len] = 0;//Kết thúc chuỗi. } skConnect.Close(); Server: 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 nSocketPort = 0,int nSocketType = SOCK_STREAM,LPCTSTR *lptstr = 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. *lptstr: 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();
  66. Simpo PDF Merge and Split Unregistered Version - 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 đị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 backlog = 5 ); backlog: 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 0; ngược lại sẽ cho giá trị là 0 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& rConnectedSocket, SOCKADDR* lpSockAdd = NULL, int* lpSockAddr = 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 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.
  67. Simpo PDF Merge and Split Unregistered Version - 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 skConnect.Receive(&msg_len, sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msg,msg_len);//Nhận nội dung thông điệp.
  68. Simpo PDF Merge and Split Unregistered Version - 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(msg,msg_len);//Gửi nội dung thông điệp. } skConnect.Close(); }
  69. Simpo PDF Merge and Split Unregistered Version - Chương 4 Ứng dụng minh họa Mô tả ứng dụng minh họa: Ứng dụng chat giữa các Pocket PC với nhau hoặc Pocket PC với máy tính để bàn: Mục đích: Ứng dụng này cho phép các Pocket PC cùng lúc có thể liên lạc trao đổi thông tin với nhau hoặc Pocket PC liên lạc với nhiều máy tính để bàn khác nhau thông qua một máy chủ. Chức năng: Server: 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 lạc với nhau. Client: Client bao gồm các Pocket PC hoặc 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.
  70. Simpo PDF Merge and Split Unregistered Version - Ứng dụng điều khiển Power Point: Mục đích: Ứng dụng này cho phép chúng ta sử dụng Pocket Pc để điều khiển Power Point ở máy chủ. Chức năng: Server: 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 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 đó. Client: Sau khi server đã mở dịch vụ, client(Pocket PC) sẽ kết nối đến server. Nếu kết nối thành công, client sẽ gửi đến server 6 thông điệp nêu trên để server xử lý. Chi tiết các hàm liên quan đến ứng dụng: 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ý.
  71. Simpo PDF Merge and Split Unregistered Version - 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, _beginthread,AfxBeginThread Ở đây ta sẽ khảo sát hàm CreateThread. HANDLE CreateThread ( 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(
  72. Simpo PDF Merge and Split Unregistered Version - LPVOID lp) { // đoạn code xử lý cho tiểu trình return 0; }  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ỳ. Hoặc ExitThread(0);//Kết thúc luồng hiện hành. Mô tả hoạt động của ứng dụng minh họa. Ứng dụng chat giữa các Pocket PC hoặc Pocket PC với máy tính để bàn:
  73. Simpo PDF Merge and Split Unregistered Version - Server Client Tạo dịch vụ Kết nối server Tạo Nếu tuyến kết Nhận nối kết thành nối Gửi thông công Tạo tuyến nhận dip thông điệp Kiểm tra nick Nếu Nếu -Thông điệp đến -“thanhcong”: Gán nick tạm chưa đã client khác. cho nick vừa nhận. tồn tồn -Gửi thông điệp -“exist”:Nhận nick tạm, yêu tại tại “exit” nếu ngừng cầu tạo nick mới. kết nối. -“server exit”:Không thể kết nối server. - Lưu nick. - Lưu nick tạm thời. -“nick”:Lưu nick vào danh -Thông báo thành -Thông báo nick đã tồn sách, đưa nick lên ListBox. công. Gửi nick vừa tại, gửi “exist” và nick -“mess”:hiển thị thông điệp nhận cho các client và tạm thời. lên màn hình. ngược lại. -“exit”:Xóa nick vừa nhận ra khỏi danh sách, xóa ra khỏi ListBox. Tạo tuyến Gửi về client 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. Hình 4.1
  74. Simpo PDF Merge and Split Unregistered Version - Ứng dụng điều khiển Power Point: Server Pocket PC Tạo dịch vụ Kết nối server. Tiến trình Nhận Nếu kết nối. kết nối Power Point. Tạo thành tuyến công xử lý -Gửi các thông điệp: lên, -Nhận các thông điệp, biên dịch các xuống, đầu trang, cuối thông điệp thành mã phím tướng ứng, gửi trang, số trang bất kỳ đến Power Point.Nếu thông điệp “exit” ,”exit” đến server. đóng socket, đóng tuyến xử lý. Hình 4.2 Mô tả thuộc tính, phương thức chủ yếu của ứng dụng minh họa: Ứng dụng chat giữa các Pocket PC hoặc Pocket PC với máy tính để bàn: Server: Lớp chủ yếu của Server là lớp CsocketServerDlg. Thành phần dữ liệu chủ yếu: Tên dữ liệu: Chứ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. Cbutton m_Taodichvu Biến điều khiển nút Tạo Dịch Vụ. Phương thức chủ yếu:
  75. Simpo PDF Merge and Split Unregistered Version - Tên phương thức Chức năng 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ụ. void OnThoat,void OnClose Thoát chương trình. Client: Lớp yếu CsocketClientDlg. Thành phần dữ liệu: Tên dữ liệu. Chứ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 Danh sách người được chọn(dịch vụ m_Danhsachchon[100] 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ả. Cstring m_SendString Lưu trữ thông điệp cần gửi. Phương thức:
  76. Simpo PDF Merge and Split Unregistered Version - Tên phương thức Chức năng. 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. Ứng dụng điều khiển Power Point: Server: Thành phần dữ liệu: Tên dữ liệu Chứ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 client. Phương thức: Tên phương thức Chứ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. DWORD WINAPI Tuyến nhận thông điệp từ client. ReceiveThread(LPVOID lp) HWND findWindowHandle Tìm Handle của các cửa sổ.
  77. Simpo PDF Merge and Split Unregistered Version - Client: Thành phần dữ liệu: Tên dữ liệu. Chức năng. CSocket skClient Socket để kết nối server. CString ServerAddress Lưu địa chỉ server. Cstring m_So Lưu số slide cần hiển thị. Phương thức: Tên phương thức Chức năng. BOOL Xử lý sự kiện đóng cửa sổ. DestroyWindow 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ỳ. OnNgungketnoi Ngừng kết nối.
  78. Simpo PDF Merge and Split Unregistered Version - Mô tả màn hình kết quả của ứng dụng Ứng dụng chat giữa các Pocket PC hoặc Pocket PC với máy tính để bàn: Server: 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 công đến server.  Client: 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ụ. Hình 4.5 Màn hình đăng nhập địa chỉ kết nối server.
  79. Simpo PDF Merge and Split Unregistered Version -  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. 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.
  80. Simpo PDF Merge and Split Unregistered Version -  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.
  81. Simpo PDF Merge and Split Unregistered Version - Ứng dụng điều khiển Power Point: Server: 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). Client: Power Point Kết nối Server Ngừng kết ni Điều khiển Power Point Len Xuong Dau trang Cuoi trang Thoat Gui Hình 4.9 Màn hình điều khiển Power Point.
  82. Simpo PDF Merge and Split Unregistered Version -  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. -1-
  83. Simpo PDF Merge and Split Unregistered Version - Đánh giá đề tài và đề xuất hướng phát triển kế tiếp Những kết quả đã đạt được - Đã 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 lập trình mạng, đặc biệt trên Pocket PC. Đề xuất hướng phát triển . - 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 các Pocket PC hoặc 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: -2-
  84. Simpo PDF Merge and Split Unregistered Version -  Đ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 của mũi tên của chính Pocket PC để điều khiển Power Point. -3-
  85. Simpo PDF Merge and Split Unregistered Version - Danh mục tài liệu tham khảo. 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] Tiếng Anh: [1] Addison Wesley, Pocket PC Network Programming eBookLiB. [2] MSDN Libarary – April 2005. -4-
  86. Simpo PDF Merge and Split Unregistered Version - Phụ lục. Chương trình chat tuần tự giữa Client và Server. Xây dựng 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 -5-
  87. Simpo PDF Merge and Split Unregistered Version - { AfxSocketInit (NULL); CSocket socketListen , socketAccept ; char sMsg[4096]; int nMsgLen ; cout<<"Server dang cho ket noi "<<endl; 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 (&nMsgLen,sizeof(nMsgLen)); socketAccept.Receive (sMsg,nMsgLen); sMsg[nMsgLen] = 0 ; cout<<"Nhan :"; cout<<sMsg<<endl; if(strcmpi(sMsg,"exit")==0) break; cout<<"Gui : "; gets(sMsg); nMsgLen = strlen(sMsg); socketAccept.Send (&nMsgLen,sizeof(nMsgLen)); socketAccept.Send(sMsg,nMsgLen); -6-
  88. Simpo PDF Merge and Split Unregistered Version - }while(strcmpi(sMsg,"exit") != 0); //Dong cac socket socketAccept.Close (); socketListen.Close (); } return nRetCode; } Xâ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)) -7-
  89. Simpo PDF Merge and Split Unregistered Version - { // 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(sServerAddress,1111)) { cout<<"Khong ket noi duoc Server"; exit(0); } cout<<"ket noi server thanh cong "<<endl; do { cout<<" Thong diep :"; gets(sMsg); nMsgLen=strlen(sMsg); socketConnect.Send(&nMsgLen,sizeof(nMsgLen)); socketConnect.Send(sMsg,nMsgLen); -8-
  90. Simpo PDF Merge and Split Unregistered Version - if(strcmpi(sMsg,”exit”)==0) break; socketConnect.Receive(&nMsgLen,sizeof(nMsgLen)); socketConnect.Receive(sMsg,nMsgLen); sMsg[nMsgLen]= 0;//end of string cout<<sMsg<<endl; }while(strcmpi(sMsg,”exit”)!= 0); //Dong socket ket noi socketConnect.Close(); } return nRetCode; } -9-