Như vậy có thể thấy TCP cung cấp cho chúng ta một kênh truyền thông điểm điểm phục vụ cho các ứng dụng đòi hỏi giao tiếp tin cậy như HTTP HyperText Tranfer Protocol, FTP File Tranfer Pro
Trang 11
MỤC LỤC
LỜI MỞ ĐẦU 2
CHƯƠNG I : GIỚI THIỆU NGÔN NGỮ LẬP TRÌNH C#, GIAO THỨC TRUYỀN TIN TCP/IP VÀ LẬP TRÌNH SOCKET 3
1.1 Tổng quan về ngôn ngữ lập trình C# 3
1.1.1 Giới thiệu về C# 3
1.1.2 Tại sao lại sử dụng ngôn ngữ C# 4
1.1.3 C# và những ngôn ngữ khác 8
1.2 Giao thức truyền tin TCP/IP 9
1.2.1 Giới thiệu 9
1.2.2 Định nghĩa 10
1.2.3 Một số ưu điểm của TCP/IP 10
1.2.4 Kiến trúc của bộ giao thức TCP/IP 11
1.2.5 Vai trò của TCP 14
1.3 Lập trình Socket 16
1.3.1 Port (Cổng giao tiếp ) 16
1.3.2 Socket 17
CHƯƠNG 2 : PHÂN TÍCH BÀI TOÁN CHƠI CỜ TƯỚNG TRÊN MẠNG INTERNET 32
2.1 Giới thiệu bài toán chơi cờ tướng trên mạng Internet 32
2.2 Mô hình Client/Server 33
2.2.1 Khái niệm mô hình Client/Server 33
2.2.2 Mô hình Client/Server trên Internet 33
2.3 Phân tích bài toán chơi cờ tướng trên mạng Internet 34
2.3.1 Xác định các tác nhân 34
2.3.2 Xác định các UC của hệ thống (các ca sử dụng) 34
2.3.3 Phân tích chi tiết bài toán 36
CHƯƠNG 3: XÂY DỰNG CHƯƠNG TRÌNH CHƠI CỜ TƯỚNG TRÊN MẠNG INTERNET 49
3.1 Giới thiệu về môn cờ tướng 49
3.1.1 Lịch sử hình thành 49
3.1.2 Luật chơi cờ tướng 51
3.2 Bài toán chơi cờ tướng trên mạng Internet 58
3.2.1 Giới thiệu bài toán chơi cờ tướng trên mạng Internet 58
3.2.2 Giải quyết vấn đề truyền dữ liệu trên mạng Internet 59
3.2.3 Giải quyết vấn đề đồ họa khi thiết kế giao diện 62
3.2.4 Giải quyết vấn đề di chuyển quân cờ 62
3.2.5 Một số giao diện thường dùng 63
KẾT LUẬN 66
TÀI LIỆU THAM KHẢO 67
Trang 22
LỜI MỞ ĐẦU
Hiện nay, công nghệ thông tin đã và đang phát triển một cách sâu rộng và toàn diện tới tất cả các lĩnh vực trong đời sống xã hội, cuộc sống con người được cải thiện nhanh chóng và ngày càng phát triển Nhờ việc áp dụng tin học vào nhiều lĩnh vực khác nhau nhất là ‘Công nghệ phần mềm’ đã và đang phát triển mạnh mẽ trên toàn thế giới Nhờ đó giúp con người nâng cao hiệu quả quản lý, tiết kiệm về thời gian và tiền của Chính vì những lợi ích to lớn đó mà con người ngày càng phát triển và mở rộng hơn các ứng dụng của công nghệ thông tin nói chung và công nghệ phần mềm nói riêng vào công việc hàng ngày cũng như đời sống xã hội
Ở nước ta hiện nay Công nghệ phần mềm đang phát triển một cách nhanh chóng, đặc biêt là công nghệ hướng đối tượng và đi kèm với nó là các công nghệ, ngôn ngữ lập trình hướng đối tượng như C++, Java, denphi, và nhất là C#, được
sử dụng rộng rãi và mang lại nhiều thành quả to lớn Tính ưu việt của nó thể hiện
ở chỗ thích hợp với việc phát triển các hệ thống lớn và phức tạp, sản phẩm tạo ra
có thể dễ dàng nâng cấp bảo trì và có tính sử dụng cao
Với ý tưởng sử dụng công nghệ hướng đối tượng kết hợp với ngôn ngữ lập trình C# vào phát triển phần mềm, đồ án tốt nghiệp này trình bày quá trình tìm hiểu xây dựng chương trình chơi cờ tướng trên mạng Internet giúp chúng ta có thể thư giãn, giải trí sau những giờ làm việc căng thẳng, giúp con người làm việc hiệu quả hơn sau những phút giây thư giãn và nhất là giúp mọi người gần nhau hơn, và hiểu nhau hơn Mặc dù đã rất cố gắng vận dụng các kiến thức tổng hợp
để xây dựng chương trình, nhưng với thời gian và kinh nghiệm còn thiếu, nên đồ
án không thể tránh khỏi những thiếu xót Em rất mong được sự giúp đỡ của các thầy cô giáo và các bạn để em có thể hoàn thành tốt hơn đồ án của mình
Em xin chân thành cảm ơn!
Trang 33
CHƯƠNG I : GIỚI THIỆU NGÔN NGỮ LẬP TRÌNH C#, GIAO THỨC
TRUYỀN TIN TCP/IP VÀ LẬP TRÌNH SOCKET 1.1 Tổng quan về ngôn ngữ lập trình C#
1.1.1 Giới thiệu về C#
Ngôn ngữ C# khá đơn giản, chỉ khoảng 80 từ khóa và hơn mười kiểu dữ liệu được xây dựng sẵn Tuy nhiên, ngôn ngữ C# có ý nghĩa cao khi nó thực thi những khái niệm lập trình hiện đại C# bao gồm tất cả những hỗ trợ cho cấu trúc, thành phần component, lập trình hướng đối tượng Những tính chất đó hiện diện trong một ngôn ngữ lập trình hiện đại Và ngôn ngữ C# hội đủ những điều kiện như vậy, hơn nữa nó được xây dựng trên nền tảng của hai ngôn ngữ mạnh nhất là C++ và Java
Ngôn ngữ C# được phát triển bởi đội ngũ kỹ sư của Microsoft, trong đó người dẫn đầu là Anders Hejlsberg và Scott Wiltamuth Cả hai người này điều là những người nổi tiếng, trong đó Anders Hejlsberg được biết đến là tác giả của Turbo Pascal, một ngôn ngữ lập trình PC phổ biến Và ông đứng đầu nhóm thiết
kế Borland Delphi, một trong những thành công đầu tiên của việc xây dựng môi trường phát triển tích hợp (IDE) cho lập trình client/server
Phần cốt lõi hay còn gọi là trái tim của bất cứ ngôn ngữ lập trình hướng đối tượng là sự hỗ trợ của nó cho việc định nghĩa và làm việc với những lớp Những lớp thì định nghĩa những kiểu dữ liệu mới, cho phép người phát triển mở rộng ngôn ngữ để tạo mô hình tốt hơn để giải quyết vấn đề Ngôn ngữ C# chứa những
từ khóa cho việc khai báo những kiểu lớp đối tượng mới và những phương thức hay thuộc tính của lớp, và cho việc thực thi đóng gói, kế thừa, và đa hình, ba thuộc tính cơ bản của bất cứ ngôn ngữ lập trình hướng đối tượng
Trong ngôn ngữ C# mọi thứ liên quan đến khai báo lớp điều được tìm thấy trong phần khai báo của nó Định nghĩa một lớp trong ngôn ngữ C# không đòi hỏi phải chia ra tập tin header và tập tin nguồn giống như trong ngôn ngữ C++ Hơn thế nữa, ngôn ngữ C# hỗ trợ kiểu XML, cho phép chèn các tag XML để phát sinh tự động các document cho lớp
Trang 4Trong ngôn ngữ C#, những cấu trúc cũng được hỗ trợ, nhưng khái niệm về ngữ nghĩa của nó thay đổi khác với C++ Trong C#, một cấu trúc được giới hạn,
là kiểu dữ liệu nhỏ gọn, và khi tạo thể hiện thì nó yêu cầu ít hơn về hệ điều hành
và bộ nhớ so với một lớp Một cấu trúc thì không thể kế thừa từ một lớp hay được kế thừa nhưng một cấu trúc có thể thực thi một giao diện
Ngôn ngữ C# cung cấp những đặc tính hướng thành phần oriented), như là những thuộc tính, những sự kiện Lập trình hướng thành phần được hỗ trợ bởi CLR cho phép lưu trữ metadata với mã nguồn cho một lớp Metadata mô tả cho một lớp, bao gồm những phương thức và những thuộc tính của nó, cũng như những sự bảo mật cần thiết và những thuộc tính khác Mã nguồn chứa đựng những logic cần thiết để thực hiện những chức năng của nó Do vậy, một lớp được biên dịch như là một khối self-contained, nên môi trường hosting biết được cách đọc metadata của một lớp và mã nguồn cần thiết mà không cần những thông tin khác để sử dụng nó
(component-Một lưu ý cuối cùng về ngôn ngữ C# là ngôn ngữ này cũng hỗ trợ việc truy cập bộ nhớ trực tiếp sử dụng kiểu con trỏ của C++ và từ khóa cho dấu ngoặc [] trong toán tử Các mã nguồn này là không an toàn (unsafe)
Và bộ giải phóng bộ nhớ tự động của CLR sẽ không thực hiện việc giải phóng những đối tượng được tham chiếu bằng sử dụng con trỏ cho đến khi chúng được giải phóng
1.1.2 Tại sao lại sử dụng ngôn ngữ C#
Nhiều người tin rằng không cần thiết có một ngôn ngữ lập trình mới Java, C++, Perl, Microsoft Visual Basic, và những ngôn ngữ khác được nghĩ rằng đã cung cấp tất cả những chức năng cần thiết
Trang 5 C# là ngôn ngữ đơn giản
C# là ngôn ngữ hiện đại
C# là ngôn ngữ hướng đối tượng
C# là ngôn ngữ mạnh mẽ và mềm dẻo
C# là ngôn ngữ có ít từ khóa
C# là ngôn ngữ hướng module
C# sẽ trở nên phổ biến
1.1.2.1 C# là ngôn ngữ đơn giản
C# loại bỏ một vài sự phức tạp và rối rắm của những ngôn ngữ như Java và C++, bao gồm việc loại bỏ những macro, những template, đa kế thừa, và lớp cơ
sở ảo (virtual base class)
Chúng là những nguyên nhân gây ra sự nhầm lẫn hay dẫn đến những vấn đề cho các người phát triển C++ Nếu chúng ta là người học ngôn ngữ này đầu tiên thì chắc chắn là ta sẽ không trải qua những thời gian để học nó! Nhưng khi đó ta
sẽ không biết được hiệu quả của ngôn ngữ C# khi loại bỏ những vấn đề trên Ngôn ngữ C# đơn giản vì nó dựa trên nền tảng C và C++ Nếu chúng ta thân thiện với C và C++ hoặc thậm chí là Java, chúng ta sẽ thấy C# khá giống về diện mạo, cú pháp, biểu thức, toán tử và những chức năng khác được lấy trực tiếp từ ngôn ngữ C và C++, nhưng nó đã được cải tiến để làm cho ngôn ngữ đơn giản hơn Một vài trong các sự cải tiến là loại bỏ các dư thừa, hay là thêm vào những
cú pháp thay đổi Ví dụ như, trong C++ có ba toán tử làm việc với các thành viên
là ::, •, và -> Để biết khi nào dùng ba toán tử này cũng phức tạp và dễ nhầm lẫn Trong C#, chúng được thay thế với một toán tử duy nhất gọi là • (dot) Đối với
Trang 61.1.2.2 C# là ngôn ngữ hiện đại
Điều gì làm cho một ngôn ngữ lập trình được gọi là ngôn ngữ hiện đại? Những đặc tính như là xử lý ngoại lệ, thu gom bộ nhớ tự động, những kiểu dữ liệu mở rộng, và bảo mật mã nguồn là những đặc tính được mong đợi trong một ngôn ngữ hiện đại C# chứa tất cả những đặc tính trên Nếu là người mới học lập trình có thể chúng ta sẽ cảm thấy những đặc tính trên phức tạp và khó hiểu Ghi chú: Con trỏ được tích hợp vào ngôn ngữ C++ Chúng cũng là nguyên nhân gây ra những rắc rối của ngôn ngữ này
C# loại bỏ những phức tạp và rắc rối phát sinh bởi con trỏ Trong C#, bộ thu gom bộ nhớ tự động và kiểu dữ liệu an toàn được tích hợp vào ngôn ngữ, sẽ loại
bỏ những vấn đề rắc rối của C++
1.1.2.3 C# là ngôn ngữ hướng đối tượng
Những đặc điểm chính của ngôn ngữ hướng đối tượng (Object-oriented language) là sự đóng gói (encapsulation), sự kế thừa (inheritance), và đa hình (polymorphism) Ngôn Ngữ C# hỗ trợ tất cả những đặc tính trên
1.1.2.4 C# là ngôn ngữ mạnh mẽ và cũng mềm dẻo
Như đã đề cập trước, với ngôn ngữ C# chúng ta chỉ bị giới hạn ở chính bởi bản thân hay là trí tưởng tượng của chúng ta Ngôn ngữ này không đặt những ràng buộc lên những việc có thể làm C# được sử dụng cho nhiều các dự án khác nhau như là tạo ra ứng dụng xử lý văn bản, ứng dụng đồ họa, bản tính, hay thậm chí những trình biên dịch cho các ngôn ngữ khác
1.1.2.5 C# là ngôn ngữ ít từ khóa
C# là ngôn ngữ sử dụng giới hạn những từ khóa Phần lớn các từ khóa được
sử dụng để mô tả thông tin Chúng ta có thể nghĩ rằng một ngôn ngữ có nhiều từ
Trang 77
khóa thì sẽ mạnh hơn Điều này không phải sự thật, ít nhất là trong trường hợp ngôn ngữ C#, chúng ta có thể tìm thấy rằng ngôn ngữ này có thể được sử dụng để làm bất cứ nhiệm vụ nào
1.1.2.6 C# là ngôn ngữ hướng module
Mã nguồn C# có thể được viết trong những phần được gọi là những lớp, những lớp này chứa các phương thức thành viên của nó Những lớp và những phương thức có thể được sử dụng lại trong ứng dụng hay các chương trình khác Bằng cách truyền các mẫu thông tin đến những lớp hay phương thức chúng ta có thể tạo ra những mã nguồn dùng lại có hiệu quả
1.1.2.7 C# sẽ là một ngôn ngữ phổ biến
C# là một trong những ngôn ngữ lập trình mới nhất, nó chưa được biết như là một ngôn ngữ phổ biến Nhưng ngôn ngữ này có một số lý do để trở thành một ngôn ngữ phổ biến Một trong những lý do chính là Microsoft và sự cam kết của NET
Microsoft muốn ngôn ngữ C# trở nên phổ biến Mặc dù một công ty không thể làm một sản phẩm trở nên phổ biến, nhưng nó có thể hỗ trợ Cách đây không lâu, Microsoft đã gặp sự thất bại về hệ điều hành Microsoft Bob Mặc dù Microsoft muốn Bob trở nên phổ biến nhưng thất bại C# thay thế tốt hơn để đem đến thành công so với Bob Thật sự là không biết khi nào mọi người trong công
ty Microsoft mới sử dụng Bob trong công việc hằng ngày của họ Tuy nhiên, với C# thì khác, nó được sử dụng bởi Microsoft Nhiều sản phẩm của công ty này đã chuyển đổi và viết lại bằng C# Bằng cách sử dụng ngôn ngữ này Microsoft đã xác nhận khả năng của C# cần thiết cho những người lập trình
Micorosoft NET là một lý do khác để đem đến sự thành công của ngôn ngữ lập trình C#.Và NET là một sự thay đổi trong cách tạo và thực thi những ứng dụng
Ngoài hai lý do trên ngôn ngữ C# cũng sẽ trở nên phổ biến do những đặc tính của ngôn ngữ này được đề cập trong mục trước như: đơn giản, hướng đối tượng, mạnh mẽ, nhưng cũng rất mềm dẻo…
Trang 88
1.1.3 C# và những ngôn ngữ khác
Chúng ta đã từng nghe đến những ngôn ngữ khác như Visual Basic, C++ và Java Có lẽ chúng ta cũng tự hỏi sự khác nhau giữa ngôn ngữ C# và nhưng ngôn ngữ đó Và cũng tự hỏi tại sao lại chọn ngôn ngữ này để học mà không chọn một trong những ngôn ngữ kia Có rất nhiều lý do và chúng ta hãy xem một số sự so sánh giữa ngôn ngữ C# với những ngôn ngữ khác giúp chúng ta phần nào trả lời được những thắc mắc
Microsoft nói rằng C# mang đến sức mạnh của ngôn ngữ C++ với sự dễ dàng của ngôn ngữ Visual Basic Có thể nó không dễ như Visual Basic, nhưng với phiên bản Visual Basic.NET (Version 7) thì ngang nhau Bởi vì chúng được viết lại từ một nền tảng Chúng ta có thể viết nhiều chương trình với ít mã nguồn hơn nếu dùng C#
Mặc dù C# loại bỏ một vài các đặc tính của C++, nhưng bù lại nó tránh được những lỗi mà thường gặp trong ngôn ngữ C++ Điều này có thể tiết kiệm được hàng giờ hay thậm chí hàng ngày trong việc hoàn tất một chương trình
Một điều quan trọng khác với C++ là mã nguồn C# không đòi hỏi phải có tập tin header Tất cả mã nguồn được viết trong khai báo một lớp
Như đã nói ở bên trên .NET runtime trong C# thực hiện việc thu gom bộ nhớ tự động Do điều này nên việc sử dụng con trỏ trong C# ít quan trọng hơn trong C++ Những con trỏ cũng có thể được sử dụng trong C#, khi đó những đoạn mã nguồn này được đánh dấu là không an toàn (unsafe code)
C# cũng từ bỏ ý tưởng đa kế thừa như trong C++ Và sự khác nhau khác là C# đưa thêm thuộc tính vào trong một lớp giống như trong Visual Basic Và những thành viên của lớp được gọi duy nhất bằng toán tử “•” khác với C++ có nhiều cách gọi trong các tình huống khác nhau
Một ngôn ngữ khác rất mạnh và phổ biến là Java, giống như C++ và C# được phát triển dựa trên C Nếu chúng ta quyết định sẽ học Java sau này, chúng ta sẽ tìm được nhiều cái mà học từ C# có thể được áp dụng
Điểm giống nhau C# và Java là cả hai cùng biên dịch ra mã trung gian: C# biên dịch ra MSIL còn Java biên dịch ra bytecode Sau đó chúng được thực hiện bằng cách thông dịch hoặc biên dịch just-in-time trong từng máy ảo tương ứng
Trang 99
Tuy nhiên, trong ngôn ngữ C# nhiều hỗ trợ được đưa ra để biên dịch mã ngôn ngữ trung gian sang mã máy C# chứa nhiều kiểu dữ liệu cơ bản hơn Java
và cũng cho phép nhiều sự mở rộng với kiểu dữ liệu giá trị Ví dụ, ngôn ngữ C#
hỗ trợ kiểu liệt kệ (enumerator), kiểu này được giới hạn đến một tập hằng được định nghĩa trước, và kiểu dữ liệu cấu trúc đây là kiểu dữ liệu giá trị do người dùng định nghĩa
Tương tự như Java, C# cũng bỏ tính đa kế thừa trong một lớp, tuy nhiên mô hình kế thừa đơn này được mở rộng bởi tính đa kế thừa nhiều giao diện
1.2 Giao thức truyền tin TCP/IP
1.2.1 Giới thiệu
Vào cuối những năm 1960 và đầu 1970, Trung tâm nghiên cứu cấp cao (Advanced Research Projects Agency - ARPA) thuộc bộ quốc phòng Mĩ (Department of Defense - DoD) được giao trách nhiệm phát triển mạng ARPANET Mạng ARPANET bao gồm mạng của những tổ chức quân đội, các trường đại học và các tổ chức nghiên cứu và được dùng để hỗ trợ cho những dự
án nghiên cứu khoa học và quân đội (Ngày nay, ARPA được gọi là DARPA) Năm 1984, DoD chia ARPANET ra thành 2 phần: ARPANET sử dụng cho nghiên cứu khoa học và MILNET sử dụng cho quân đội Đầu những năm 1980, một bộ giao thức mới được đưa ra làm giao thức chuẩn cho mạng ARPANET và các mạng của DoD mang tên DARPA Internet protocol suit, thường được gọi là
bộ giao thức TCP/IP hay còn gọi tắt là TCP/IP
Năm 1987 tổ chức nghiên cứu quốc gia Hoa Kỳ (National Science Foundation - NSF) tài trợ cho việc kết nối 6 trung tâm siêu tính trên toàn liên bang lại với nhau thành một mạng với tên gọi NSFNET Về mặt vật lý, mạng này kết nối 13 điểm làm việc bằng đường điện thoại cao tốc được gọi là NSFNET backbone Khoảng 8 đường backbone đã được xây dựng NSFNET được mở rộng với hàng chục mạng địa phương kết nối vào nó và kết nối vào mạng Internet của DARPA Cả NSFNET và các mạng con của nó đều sử dụng bộ giao thức TCP/IP
Trang 1010
1.2.2 Định nghĩa
TCP (Transmission Control Protocol) là một giao thức hướng kết nối, nó cung cấp một đường truyền dữ liệu tin cậy giữa hai máy tính Tính tin cậy thể hiện ở việc nó đảm bảo dữ liệu được gửi sẽ đến được đích và theo đúng thứ tự như khi nó được gửi
Đặc biệt, TCP/IP cho phép người lập trình thiết lập truyền thông giữa hai chương trình ứng dụng và chuyền dữ liệu qua lại.TCP/IP cung cấp kết nối bình đẳng giữa các ứng dụng kể cả ứng dụng chạy trên cùng một máy
Như nhiều giao thức khác, bộ giao thức TCP/IP có thể được coi là một tập hợp các tầng, mỗi tầng giải quyết một tập các vấn đề có liên quan đến việc truyền
dữ liệu, và cung cấp cho các giao thức tầng cấp trên một dịch vụ được định nghĩa
rõ ràng dựa trên việc sử dụng các dịch vụ của các tầng thấp hơn Về mặt lôgic, các tầng trên gần với người dùng hơn và làm việc với dữ liệu trừu tượng hơn, chúng dựa vào các giao thức tầng cấp dưới để biến đổi dữ liệu thành các dạng mà cuối cùng có thể được truyền đi một cách vật lý
1.2.3 Một số ưu điểm của TCP/IP
1-TCP/IP là giao thức chuẩn phát triển độc lập với phần cứng và hệ điều hành, là giao thức lý tưởng cho việc hợp nhất phần cứng và phần mềm, ngay cả khi truyền thông trên Internet Sự độc lập rành mạch với phần cứng vật lý của mạng cho phép TCP/IP hợp nhất các mạng khác nhau TCP/IP có thể chạy trên mạng Ethernet, mạng Token ring, mạng quay số (Dial-up line), mạng X.25, mạng
ảo và mọi loại môi trường vật lý truyền thông
2- Một sơ đồ địa chỉ dùng chung cho phép mỗi thiết bị TCP/IP có duy nhất một địa chỉ trên mạng ngay cả khi đó là mạng toàn cầu Internet
3- Tiêu chuẩn hoá mức cao của giao thức phù hợp với lợi ích của dịch vụ người dùng
DARPA hỗ trợ việc nghiên cứu kết nối nhiều loại mạng khác nhau lại thành một mạng toàn cầu Internet Ngoài việc sử dụng cho tất cả các máy trên Internet, TCP/IP còn được sử dụng trong mạng nội bộ của một số tổ chức chính phủ hoặc thương mại, những mạng này gọi là Intranet TCP/IP vừa có thể kết nối một số
Trang 1111
lượng lớn các máy tính (150.000 máy trên nước Mĩ, Châu Âu, Châu Á) lại có thể chỉ kết nối hai máy tính trong phòng làm việc
1.2.4 Kiến trúc của bộ giao thức TCP/IP
Giao thức TCP/IP có kiến trúc phân tầng
Application Layer
Presentation Layer Application Layer
Session Layer
Data link Layer
Hình 1.1 : Các lớp tương ứng giữa OSI và TCP/IP
Có nhiều giao thức trong bộ giao thức truyền thông TCP/IP, nhưng hai giao thức quan trọng nhất được lấy tên đặt cho bộ giao thức này là TCP (Transmission Control Protocol) và IP (Internet Protocol)
Bộ giao thức TCP/IP được phân làm 4 tầng
Tầng mạng (Network Layer)
Tầng Internet (Internet Layer)
Tầng giao vận (Transport Layer)
Trang 12Network Ethernet
Header
IP Header
TCP Header Data
Ethernet trailer
Hình 1.2 : Quy trình gửi dữ liệu qua các tầng
1.2.4.1 Tầng mạng (NetworkLayer)
Tầng mạng là tầng thấp nhất của kiến trúc giao thức TCP/IP Các giao thức trong tầng này cung cấp biện pháp cho hệ thống chuyển giao dữ liệu giữa các thiết bị được kết nối trực tiếp Nó mô tả cách sử dụng mạng để truyền một gói thông tin IP Không giống những giao thức của tầng cao hơn là sử dụng dịch vụ của tầng dưới nó và cung cấp dịch vụ cho tầng trên, giao thức của tầng mạng cần phải biết chi tiết của mạng vật lý phía dưới (cấu trúc của gói, địa chỉ, vv ) để định dạng đúng thông tin sẽ được truyền tuân theo những ràng buộc của mạng Tầng mạng của TCP/IP chứa các chức năng tương ứng của 3 tầng thấp nhất của
mô hình tham chiếu OSI (tầng mạng, tầng liên kết dữ liệu, tầng vật lý) Tầng mạng thường không được người dùng để ý tới vì thiết kế của TCP/IP che dấu những chức năng của tầng thấp nhất này và những điều cần biết cho người sử dụng cũng như người lập trình chỉ là những giao thức của các tầng cao hơn (IP, TCP, UDP, vv ) Mỗi khi có công nghệ phần cứng xuất hiện, những giao thức tầng mạng phải được phát triển để TCP/IP có thể sử dụng phần cứng mới (thông thường đó chính là các trình điều khiển của chính nhà cung cấp phần cứng đó) Các chức năng trình diễn trong tầng này bao gồm đóng gói gói thông tin IP thành các "Frame" được truyền dẫn trên mạng và chuyển địa chỉ IP thành địa chỉ vật lý sử dụng bởi mạng máy tính Một trong số các điểm mạnh của TCP/IP là địa chỉ của nó được phối hợp sao cho trên mạng Internet không có một thiết bị
Trang 1313
mạng nào cùng tên Địa chỉ này phải được chuyển đổi thích hợp với địa chỉ mạng vật lý nơi mà dữ liệu được truyền đi
Hai ví dụ RFCs mô tả giao thức sử dụng cho tầng mạng là:
RFC 826: Giao thức chuyển đổi địa chỉ chuyển đổi địa chỉ IP thành địa chỉ Ethernet
RFC 894: Một chuẩn cho việc truyền gói tin IP qua mạng Ethernet mô
tả cách thức đóng gói để truyền thông tin qua mạng Ethernet
Khi cài đặt trong UNIX, giao thức của tầng này được xem như sự phối hợp của chương trình điều khiển thiết bị và các chương trình liên quan Những đơn vị tương ứng với những thiết bị mạng làm nhiệm vụ đóng gói dữ liệu và chuyển giao cho mạng
1.2.4.2 Tầng Internet (Internet Layer)
Tầng Internet cung cấp một hệ thống chuyển giao không kết nối và đôi khi người ta còn gọi là không tin cậy Không kết nối bởi mỗi gói tin được truyền đi trên mạng một cách độc lập, sự kết hợp dữ liệu của các gói tin được cung cấp bởi các dịch vụ lớp trên Mỗi gói tin IP chứa địa chỉ nơi gửi và địa chỉ nơi nhận và dựa vào đó nó có thể được truyền trên mạng tới đích Nhưng chính việc dữ liệu
có thể đi tới đích trên nhiều đường khác nhau tạo nên sự mềm dẻo cho Internet khi một đường bị đứt hay một nút nào đó bị quá tải, các gói tin có thể được truyền đi theo những con đường khác, nếu một gói tin nào có lỗi thì chỉ phải truyền lại gói tin đó thay vào việc phải truyền lại toàn bộ thông báo Không tin cậy bởi vì IP không có cơ chế kiểm tra tính đúng đắn của dữ liệu được truyền nhận, dịch vụ tin tưởng phải được cung cấp bởi các giao thức lớp trên
Vấn đề chủ chốt trên tầng Internet là việc chọn lựa con đường tối ưu để truyền các gói tin từ trạm nguồn tới trạm đích
1.2.4.3 Tầng giao vận (Transport Layer)
Tầng giao thức ngay trên tầng Internet là Tầng giao vận (Host-to-Host Transport Layer hay thường gọi là Transport Layer) Hai giao thức quan trọng nhất của tầng này là Transmission Control Protocol (TCP) và User Datagram
Trang 1414
Protocol (UDP) TCP cung cấp dịch vụ chuyển giao thông tin có kết nối (connection-oriented), nó bao gồm cả việc kiểm tra và sửa lỗi UDP cung cấp dịch vụ kém tin cậy hơn (unreliable) và không thiết lập liên kết trước (connectionless) Cả hai giao thức đều chuyển giao thông tin giữa tầng ứng dụng
và tầng Internet Chương trình ứng dụng có thể lựa chọn dịch vụ nào thích hợp với nó
1.2.4.4 Tầng ứng dụng (Application Layer)
Phần lớn người sử dụng chỉ quan tâm tới các dịch vụ thông tin được cung cấp trên Internet Các ứng dụng có sớm nhất của Internet là Telnet, FTP, SMTP, DNS ngoài ra ngày nay có hàng ngàn ứng dụng khác đang phát triển và ngày một nhiều Sau đây chúng ta tìm hiểu và phân tích một số ứng dụng của Internet
dữ liệu (dưới dạng âm thanh) bằng cách nói và nghe qua điện thoại của bạn Toàn
bộ việc thực hiện kết nối và truyền dữ liệu giữa hai máy điện thoại được thực hiện bởi công ty điện thoại thông qua các trạm và đường dây điện thoại, nhiệm
vụ duy nhất của bạn là quay số để cung cấp cho nhà cung cấp dịch vụ điện thoại biết số điện thoại bạn muốn liên lạc Giống như vậy, trong việc truyền dữ liệu qua mạng thì TCP đóng vai trò như nhà cung cấp dịch vụ điện thoại ở ví dụ trên,
nó làm nhiệm vụ tạo kết nối và truyền dữ liệu giữa hai điểm giao tiếp để đảm bảo
dữ liệu không bị mất và đến đích theo đúng trật tự như khi chúng được gửi Các giao thức TCP/IP có vai trò xác định quá trình liên lạc trong mạng và quan trọng hơn cả là định nghĩa “hình dáng” của một đơn vị dữ liệu và những thông tin chứa trong nó để máy tính đích có thể dịch thông tin một cách chính xác TCP/IP và các giao thức liên quan tạo ra một hệ thống hoàn chỉnh quản lý
Trang 1515
quá trình dữ liệu được xử lý, chuyển và nhận trên một mạng sử dụng TCP/IP Một hệ thống các giao thức liên quan, chẳng hạn như TCP/IP, được gọi là bộ giao thức
Tính tin cậy của đường truyền được thể hiện ở hai đặc điểm sau:
Bộ giao thức TCP/IP cung cấp các thuộc tính đảm bảo mức độ tin cậy của việc vận chuyển dữ liệu trên mạng Những thuộc tính này bao gồm việc kiểm tra lỗi trong quá trình vận chuyển (để xác định dữ liệu đã tới nơi chính là cái đã được gửi đi) và xác nhận việc thông tin đã được nhận Lớp Vận chuyển của TCP/IP xác định các việc kiểm tra lỗi và xác nhận thông qua giao thức TCP Nhưng giao thức ở cấp thấp hơn, Lớp Truy cập Mạng, cũng đóng một vai trò trong toàn bộ quá trình kiểm tra lỗi
Mọi gói tin cần gửi sẽ đến được đích Để làm điều này thì mỗi lần phía gửi gửi xong một gói tin nó sẽ chờ nhận một xác nhận từ bên nhận rằng đã nhận được gói tin Nếu sau một khoảng thời gian mà phía gửi không nhận được thông tin xác nhận phản hồi thì nó sẽ phát lại gói tin Việc phát lại sẽ được tiến hành cho đến khi việc truyền tin thành công, tuy nhiên sau một số lần phát lại max nào
đó mà vẫn chưa thành công thì phía gửi có thể suy ra là không thể truyền tin được và sẽ dừng việc phát tin
Các gói tin sẽ được trình ứng dụng nhận được theo đúng thứ tự như chúng được gửi Bởi các gói tin có thể được dẫn đi trên mạng theo nhiều con đường khác nhau trước khi tới đích nên thứ tự khi tới đích của chúng có thể không giống như khi chúng được phát Do đó để đảm bảo có thể sắp xếp lại các gói tin
ở phía nhận theo đúng thứ tự như khi chúng được gửi, giao thức TCP sẽ gắn vào mỗi gói tin một thông tin cho biết thứ tự của chúng trong cả khối tin chung được phát nhờ vậy bên nhận có thể sắp xếp lại các gói tin theo đúng thứ tự của chúng Thực tế của quá trình định dạng và xử lý dữ liệu bằng TCP/IP được thực hiện bằng bộ lọc của các hãng sản xuất Ví dụ, Microsoft TCP/IP là một phần mềm cho phép Windows NT xử lý các dữ liệu được format theo TCP/IP và vì thế có thể hoà vào mạng TCP/IP
Trang 1616
Mục đích của các chuẩn TCP/IP là nhằm đảm bảo tính tương thích của tất cả
bộ lọc TCP/IP thuộc bất kỳ phiên bản nào hoặc của bất kỳ hãng sản xuất nào Như vậy có thể thấy TCP cung cấp cho chúng ta một kênh truyền thông điểm điểm phục vụ cho các ứng dụng đòi hỏi giao tiếp tin cậy như HTTP (HyperText Tranfer Protocol), FTP (File Tranfer Protocol), Telnet… Các ứng dụng này đòi hỏi một kênh giao tiếp tin cậy bởi thứ tự của dữ liệu được gửi và nhận là yếu tố quyết định đến sự thành công hay thất bại của chúng Hãy lấy ví dụng khi HTTP được sử dụng để đọc thông tin từ một điạ chỉ URL, dữ liệu phải được nhận theo đúng thứ tự mà chúng được gửi nếu không thứ mà bạn nhận được có thể là một trang HTML với nội dung lộn xộn hoặc một file zip bị lỗi và không thể giải nén…
1.3 Lập trình Socket
1.3.1 Port (Cổng giao tiếp )
Định nghĩa - Cổng là một cơ chế cho phép dữ liệu được truyền đến đúng ứng dụng đang chạy trên máy tính
Chúng ta biết rằng mỗi máy tính chỉ có một kết nối vật lý với mạng, tất cả các dữ liệu cần truyền cho máy tính khác sẽ được mang đi bởi kết nối này Tuy nhiên chúng ta cũng lại thấy rằng trên mỗi máy tính không chỉ có một mà có thể
có nhiều ứng dụng (chương trình) cùng chạy và cùng có nhu cầu giao tiếp qua mạng do đó dữ liệu máy tính nhận được thông qua kết nối với mạng cần phải được chuyển đến đúng ứng dụng cần nó vì vậy máy tính cần phải biết dữ liệu mà
nó nhận được được phía gửi hi vọng chuyển đến ứng dung nào Việc này được thực hiện thông qua việc sử dụng các cổng:
• Mỗi ứng dụng chạy trên máy tính sẽ được gắn với một cổng logic, đó là một số 16 bit Các cổng có giá trị từ 0 đến 65535, trong đó các cổng từ 0 tới 1023
bị hạn chế, chúng chủ yếu được sử dụng cho các dịch vụ phổ biến như HTTP, FTP…, các cổng còn lại được sử dụng cho các ứng dụng của người dùng
• Dữ liệu truyền qua mạng Internet chứa trong nó thông tin để xác định định danh và cổng trên máy tính mà nó cần đến Định danh của mỗi máy tính được xác định bằng một địa chia IP có chiều dài 32 bit
Trang 17Tiếp đó cùng với sự phát triển của các ứng dụng mạng, Socket được hỗ trợ trong nhiều ngôn ngữ lập trình và chạy trên nhiều nền tảng hệ điều hành khác nhau Ví dụ như WinSock dùng cho các ứng dụng của Microsoft, Socket++ dùng cho các lập trình viên sử dụng Unix…
Một câu hỏi đặt ra là tại sao chúng ta lại sử dụng Socket trong truyền thông giữa các máy tính Để trả lời câu hỏi này chúng ta phải quay lại thời điểm trước khi Socket ra đời
Trong thời kì này trên hệ thống Unix việc vào/ra dữ liệu được thực hiện theo
mô hình 3 bước Open-Read/Write-Close Để thực hiện việc vào ra dữ liệu trước hết chương trình phải tạo ra một kết nối với tài nguyên mà nó muốn giao tiếp (tài nguyên này có thể là bàn phím, bộ nhớ trong, file ), sau khi kết nối đã được thực hiện, chương trình có thể trao đổi dữ liệu thông qua các thao tác Read - đưa
dữ liệu từ tài nguyên đã kết nối vào chương trình để xử lý hoặc Write - đưa dữ liệu đã xử lý từ chương trình ra tài nguyên Một ví dụ điển hình cho kiểu vào/ra này là thao tác với file dữ liệu mà chúng ta khá quen thuộc trong các ngôn ngữ lập trình: Khi người lập trình muốn thao tác với một file dữ liệu họ tiến hành như sau:
1- Mở file cần sử dụng với các quyền thích hợp trên đó
2- Thực hiện việc đọc dữ liệu từ file để xử lý hay đưa dữ liệu đã xử lý để ghi vào file
3- Đóng file sau khi đã sử dụng xong
Trang 1818
Khi việc trao đổi dữ liệu giữa các chương trình và kết nối mạng được đưa vào hệ thống Unix người ta mong muốn việc trao đổi dữ liệu giữa các chương trình cũng sẽ được thực hiện theo mô hình 3 bước của vào/ra dữ liệu nhằm tránh cho người lập trình những khó khăn khi giao tiếp với các tầng bên dưới tầng ứng dụng Để làm được điều đó, Socket được sử dụng Khi hai chương trình muốn giao tiếp với nhau, mỗi chương trình sẽ tạo ra một Socket, chúng đóng vai trò là các điểm cuối trong một kết nối và thực hiện việc trao đổi thông tin giữa hai chương trình Đối với người lập trình, Socket được xem như một tài nguyên hệ thống mà chương trình cần giao tiếp nên chương trình có thể thực hiện giao tiếp với Socket theo mô hình 3 bước giống như việc vào/ra dữ liệu Như vậy sự ra đời của socket gắn liền với nhu cầu truyền thông máy tính Sau đây chúng ta sẽ đưa
Trang 191.3.2.3 Nguyên lý hoạt động
Trong phần trên chúng ta đã thấy khi hai ứng dụng muốn trao đổi dữ liệu qua mạng chúng sẽ tạo ra ở mỗi phía một socket và trao đổi dữ liệu bằng cách đọc và ghi từ socket Để hiểu rõ cách thức socket trao đổi dữ liệu chúng ta hãy xem xét nguyên lý hoạt động của chúng
Trước hết chúng ta hãy xem làm thế nào các socket có thể xác định đựợc nhau Khi một chương trình tạo ra một socket, một định danh dạng số sẽ được gán cho socket, định danh này chính là cổng mà chúng ta đã thảo luận trong phần
cơ sở về mạng ở chương 1 phần 1 Việc gán số cổng này cho socket có thể được thực hiện bởi chương trình hoặc bởi hệ điều hành tùy theo cách socket được sử dụng như thế nào Trong mỗi gói tin mà socket gửi đi có chứa hai thông tin để xác định đích đến của gói tin:
1- Một địa chỉ mạng để xác định hệ thống sẽ nhận gói tin
Trang 2020
2- Một số định danh cổng để nói cho hệ thống đích biết socket nào trên nó sẽ nhận dữ liệu
Nhờ hai thông tin này mà gói tin có thể đến được đúng máy tính chứa socket
mà nó cần đến (nhờ địa chỉ mạng) và được phân phối đến đúng socket đích (nhờ địa chỉ cổng của socket đích) Bởi dưới góc độ lập trình các socket thường làm việc theo cặp, một socket đóng vai trò làm client còn các socket khác đóng vai trò như một server Socket phía server xác định một cổng cho giao tiếp mạng, sau
đó chờ nghe dữ liệu mà client gửi tới nó bằng client socket Do đó các cổng cho server socket phải được biết bởi các chương trình client Ví dụ server FTP sử dụng một socket để nghe tại cổng 21 do đó nếu một chương trình client muốn giao tiếp với server FTP nó cần phải kết nối đến socket đang nghe tại cổng 21 Như vậy cổng của socket phía server được xác định bởi chương trình, ngược lại cổng cho client socket được xác định bởi hệ điều hành Khi một socket phía client gửi một gói tin tới socket phía server thì trong gói tin đã có chứa thông tin
về địa chỉ của hệ thống client và cổng của socket phía client nên server hoàn toàn
có thể gửi thông tin phản hồi cho client
Chúng ta có thể khái quát quá trình trao đổi dữ liệu trong mạng Lan thông qua các socket như sau:
1 Chương trình phía Server tạo ra một socket, socket này được chương trình gắn với một cổng trên server Sau khi đựợc tạo ra socket này (mà từ nay ta sẽ gọi
là socket phía server) sẽ chờ nghe yêu cầu từ phía client
2 Khi chương trình phía Client cần kết nối với một Server, nó cũng tạo ra một socket, socket này cũng được hệ điều hành gắn với một cổng Chương trình Client sẽ cung cấp cho Socket của nó (mà từ nay ta sẽ gọi là Socket phía Client) điạ chỉ mạng và cổng của Socket phía Server và yêu cầu thực hiện kết nối (nếu chương trình định sử dụng giao thức hướng kết nối) hoặc truyền dữ liệu (nếu chương trình sử dụng giao thức không hướng kết nối)
3 Chương trình phía Server và chương trình phía Client trao đổi dữ liệu với nhau bằng cách đọc từ Socket hoặc ghi vào Socket của minh Các socket ở hai phía nhận dữ liệu từ ứng dụng và đóng gói để gửi đi hoặc nhận các dữ liệu được
Trang 2121
gửi đến và chuyển cho chương trình ứng dụng bởi socket ở cả hai phía đều biết được địa chỉ mạng và điạ chỉ cổng của nhau
Ở bước thứ hai chúng ta thấy chương trình ứng dụng phải lựa chọn giao thức
mà nó định sử dụng để trao đổi dữ liệu Tùy theo việc chúng ta sử dụng giao thức nào (TCP hay UDP) mà cách thức xử lý trước yêu cầu của client có thể khác Sau đây chúng ta sẽ xem xét chi tiết các thức trao đổi dữ liệu của Socket ứng với từng loại giao thức
Các hàm Socket:
socket(): tạo socket truyền dữ liệu
bind(): định danh cho socket vừa tạo (gán port cho socket)
listen(): chở kết nối
accept(): chấp nhận kết nối từ client
connect(): kết nối với server
send(), recv() : gửi, nhận dữ liệu với stream socket
sendto(), recvfrom(): gửi,nhập dữ liệu với datagram socket
………
Một số hàm hỗ trợ khác:
inet_addr(): chuyển từ địa chỉ IP dạng số thập phân có chấm sang địa chỉ Internet
inet_ntoa(): ngược lại với hàm inet_addr();
gethostname(): cho tên máy hiện thời
1.3.2.4 Socket hỗ trợ TCP
a Ở phía Server: Khi một ứng dụng trên server hoạt động nó sẽ tạo ra một socket và đăng ký với server một cổng ứng dụng và chờ đợi yêu cầu kết nối từ phía client qua cổng này
Hình 1.4 : Client gửi yêu cầu đến Server
Trang 2222
b Ở phía client: Nó biết địa chỉ của máy trên đó server đang chạy và cổng và server đang chờ nghe yêu cầu Do đó khi muốn kết nối đến Server, nó cũng tạo ra một socket chứa địa chỉ máy client và cổng của ứng dụng trên máy client đồng thời client sẽ cung cấp cho socket của nó địa chỉ và cổng của Server mà nó cần kết nối và yêu cầu Socket thực hiện kết nối Khi Server nhận được yêu cầu kết nối từ Client, nếu nó chấp nhận thì server sẽ sinh ra một socket mới được gắn với một cổng khác với cổng mà nó đang nghe yêu cầu Sở dĩ server làm như vậy bởi
nó cần cổng cũ để tiếp tục nghe yêu cầu từ phía client trong khi vẫn cần một kết nối với client
Hình 1.5: Server chấp nhận yêu cầu và tạo một socket phục vụ client
Sau đó chương trình ứng dụng phía Server sẽ gửi thông báo chấp nhận kết nối cho Client cùng thông tin về địa chỉ cổng mới của socket mà nó dành cho Client
c Quay lại phía client, nếu kết nối được chấp nhận nghĩa là socket của nó đã được tạo ra thành công và nó có thể sử dụng socket để giao tiếp với server bằng cách viết và ghi tới socket theo cách giao tiếp với một tài nguyên trên máy tính thông thường
1.3.2.5 Lập trình socket với C#
Bạn cần gửi dữ liệu giữa hai máy tính trên một network bằng kết nối TCP/IP Khi đó một máy tính phải đóng vai trò là máy chủ (server) lắng nghe bằng lớp System.Net.Sockets.TcpListener Mỗi khi một kết nối được thiết lập, cả hai máy tính đều có thể giao tiếp bằng lớp System.Net.Sockets.TcpListener
TCP là một giao thức đáng tin cậy dựa trên kết nối, cho phép hai máy tính giao tiếp thông qua một network Để tạo một kết nối TCP, một máy tính phải đóng vai trò là server và bắt đầu lắng nghe trên một endpoint cụ thể (endpoint được định nghĩa là một địa chỉ IP, cho biết máy tính và số port) Một máy tính
Trang 2323
khác phải đóng vai trò là client và gửi một yêu cầu kết nối đến endpoint mà máy tính thứ nhất đang lắng nghe trên đó Một khi kết nối được thiết lập, hai máy tính
có thể trao đổi các thông điệp với nhau Giao tiếp giữa hai máy tính chỉ đơn giản
là quá trình đọc/ghi từ một System.Net.Sockets.NetworkStream
Mặc dù một kết nối TCP luôn cần có một server và một client, nhưng không
lý do gì một ứng dụng không thể là cả hai Ví dụ, trong một ứng dụng peer, một tiểu trình được sử dụng lắng nghe các yêu cầu đến (đóng vai trò là một server) trong khi một tiểu trình khác được sử dụng để khởi tạo các kết nối đi (đóng vai trò là một client) Trong ví dụ đi kèm mục này, client và server là các ứng dụng riêng rẽ và được đặt trong các thư mục con riêng
peer-to-Một khi kết nối TCP được thiết lập, hai máy tính có thể gửi bất kỳ kiểu dữ liệu nào bằng cách ghi dữ liệu đó ra NetworkStream Tuy nhiên, ý tưởng hay là bắt đầu thiết kế một ứng dụng mạng bằng cách định nghĩa giao thức mức ứng dụng mà client và server sẽ sử dụng để giao tiếp Giao thức này chứa các hằng
mô tả các lệnh được phép, bảo đảm mã lệnh của ứng dụng không chứa các chuỗi giao tiếp được viết cứng
namespace SharedComponent
{
public class ServerMessages
{
public const string AcknowledgeOK = "OK";
public const string AcknowledgeCancel = "Cancel";
public const string Disconnect = "Bye";
}
public class ClientMessages
{
public const string RequestConnect = "Hello";
public const string Disconnect = "Bye";
}
}
Trang 2424
Trong ví dụ này, bảng từ vựng được định nghĩa sẵn chỉ là cơ bản Bạn có thể thêm nhiều hằng hơn nữa tùy thuộc vào kiểu ứng dụng Ví dụ, trong một ứng dụng truyền file, client có thể gửi một thông điệp để yêu cầu một file Sau đó, server có thể đáp lại bằng một acknowledgment (ACK) và trả về các chi tiết của file (kích thước file chẳng hạn) Những hằng này sẽ được biên dịch thành một Class Library Assembly riêng, và cả client và server đều phải tham chiếu đến assembly này
Ứng dụng server cần xác định địa chỉ IP của client sau khi nó chấp nhận một kết nối Sử dụng phương thức AcceptSocket của lớp TcpListener để lấy lớp mức thấp là System.Net.Sockets.Socket thay vì là TcpClient Sử dụng thuộc tính Socket.RemoteEndPoint để lấy địa chỉ IP của client
Lớp TcpClient không cho phép bạn thu lấy socket nằm dưới hay bất cứ thông tin nào về port và địa chỉ IP của client Lớp này có cung cấp thuộc tính Socket, nhưng thuộc tính này là được-bảo-vệ (protected) và do đó không thể truy xuất được từ các lớp phi dẫn xuất Để truy xuất socket nằm dưới, bạn có hai tùy chọn: Tạo một lớp tùy biến dẫn xuất từ TcpClient Lớp này có thể truy xuất thuộc tính được bảo vệ Socket và trưng nó ra thông qua một thuộc tính mới Sau đó, bạn phải sử dụng lớp tùy biến này thay cho TcpClient Bỏ qua lớp TcpClient bằng cách sử dụng phương thức TcpListener.AcceptSocket Bạn vẫn có thể sử dụng các lớp mức-cao là BinaryReader và BinaryWriter để đọc/ghi dữ liệu, nhưng bạn cần phải tạo NetworkStream trước (sử dụng socket)
Dưới đây là phiên bản sửa đổi của server trong :
public class TcpServerTest {
private static void Main() {
// Tạo listener trên port 8000
Trang 2525
TcpListener listener =new TcpListener(IPAddress.Parse("127.0.0.1"), 8000); Console.WriteLine("About to initialize port.");
listener.Start();
Console.WriteLine("Listening for a connection ");
try { // Đợi yêu cầu kết nối, và trả về một Socket
Socket socket = listener.AcceptSocket();
Console.WriteLine("Connection accepted.");
// Tạo network stream
NetworkStream stream = new NetworkStream(socket); // Tạo BinaryWriter để ghi ra stream
BinaryWriter w = new BinaryWriter(stream);
// Tạo BinaryReader để đọc từ stream
BinaryReader r = new BinaryReader(stream);
if (r.ReadString() == ClientMessages.RequestConnect) {
w.Write(ServerMessages.AcknowledgeOK);
Console.WriteLine("Connection completed.");
// Lấy địa chỉ IP của client
Console.WriteLine("The client is from IP address: " + (IPEndPoint)socket.RemoteEndPoint).Address.ToString();
Console.Write("The client uses local port: " + ((IPEndPoint)socket.RemoteEndPoint).Port.ToString()); while (r.ReadString() != ClientMessages.Disconnect){} Console.WriteLine();
Console.WriteLine("Disconnect request received."); w.Write(ServerMessages.Disconnect);
} else {
Trang 2626
Console.WriteLine("Could not complete connection.");
} // Đóng socket
}
}
Bạn muốn tạo một TCP-server có thể cùng lúc xử lý nhiều TCP-client
Sử dụng phương thức AcceptTcpClient của lớp TcpListener Mỗi khi có một client mới kết nối đến, khởi chạy một tiểu trình mới để xử lý yêu cầu và gọi TcpListener.AcceptTcpClient lần nữa
Một endpoint TCP (địa chỉ IP và port) có thể phục vụ nhiều kết nối Thực ra,
hệ điều hành đảm đương phần lớn công việc giùm bạn Những gì bạn cần làm là tạo một đối tượng thợ (worker object) trên server để xử lý mỗi kết nối trong một tiểu trình riêng Xét lớp TCP-client và TCP-server đa được trình bày trong mục 11.8 Bạn có thể dễ dàng chuyển server này thành một server hỗ-trợ-đa-tiểu-trình
để thực hiện nhiều kết nối cùng một lúc Trước hết, tạo một lớp để tương tác với một client, kế tiếp, thay đổi mã lệnh của server sao cho nó lặp liên tục, tạo ra các thể hiện ClientHandler mới khi cần và chạy chúng trong các tiểu trình mới Dưới đây là mã lệnh đa được sửa đổi:
public class TcpServerTest {
private static void Main() {
TcpListener listener =
Trang 2727
new TcpListener(IPAddress.Parse("127.0.0.1"), 8000); Console.WriteLine("Server: About to initialize port."); listener.Start();
Console.WriteLine("Server: Listening for a connection "); int clientNum = 0;
while (true) { try { // Đợi yêu cầu kết nối, và trả về một TcpClient TcpClient client = listener.AcceptTcpClient(); Console.WriteLine("Server: Connection accepted."); // Tạo một đối tượng mới để xử lý kết nối này clientNum++;
ClientHandler handler = new ClientHandler(client, "Client " + clientNum.ToString());
// Khởi động đối tượng này làm việc trong // một tiểu trình khác
Thread handlerThread = new Thread(new ThreadStart(handler.Start));
}
Dưới đây là transcript phía server của một phiên làm việc với hai client:
Trang 2828
Server: About to initialize port
Server: Listening for a connection
Server: Connection accepted
Client 1: Connection completed
Server: Connection accepted
Client 2: Connection completed
Client 2: Disconnect request received
Client 2: Client connection closed
Client 1: Disconnect request received
Client 1: Client connection closed
Bạn có thể thêm mã lệnh vào server để nó theo vết các đối tượng thợ hiện hành trong một tập hợp Làm như thế sẽ cho phép server hủy bỏ các tác vụ này nếu nó cần phải đóng và chỉ được phép một số tối đa client cùng một lúc
Bạn cần ghi dữ liệu ra network-stream từng khối một, mà không phải block phần mã lệnh còn lại Kỹ thuật này có thể được sử dụng nếu bạn muốn “stream” một file lớn trên mạng
Tạo một lớp riêng để xử lý kỹ thuật streaming bất đồng bộ Bạn có thể bắt đầu “stream” một khối dữ liệu bằng phương thức NetworkStream.BeginWrite và cung cấp một phương thức callback Khi callback được kích hoạt thì gửi khối kế tiếp
Lớp NetworkStream hỗ trợ việc sử dụng bất đồng bộ thông qua phương thức BeginRead và BeginWrite Sử dụng các phương thức này, bạn có thể gửi hay nhận một khối dữ liệu trên một trong các tiểu trình do thread-pool của bộ thực thi NET cung cấp, mà không block mã lệnh của bạn Mục này trình bày kỹ thuật ghi bất đồng bộ.Khi gửi dữ liệu một cách bất đồng bộ, bạn phải gửi dữ liệu nhị phân thô (một mảng byte) Và bạn cần chọn kích thước mỗi lần gửi hay nhận Ví dụ dưới đây viết lại server sao cho mỗi lớp ClientHandler gửi một lượng lớn dữ liệu được đọc từ một file Dữ liệu này được gửi một cách bất đồng bộ, nghĩa là ClientHandler có thể tiếp tục thực hiện các tác vụ khác (trong ví dụ này, nó chỉ việc lấy các thông điệp được gửi từ client)
Trang 2929
Một thuận lợi của cách tiếp cận này là toàn bộ nội dung của file chẳng bao giờ nằm trong bộ nhớ một lượt Thay vào đó, nó được thu lấy ngay trước khi một khối mới được gửi Một thuận lợi khác nữa là server có thể hủy bỏ thao tác vào bất cứ lúc nào Ví dụ, nếu client chỉ đọc đến khối dữ liệu thứ ba thì ngắt kết nối, server sẽ thiết lập một biến thành viên luận lý có tên là fileStop để báo cho callback không gửi dữ liệu nữa
Dưới đây là lớp ClientHandler đa được sửa đổi (lớp TcpServerTest không cần thay đổi gì):
public ClientHandler(TcpClient client, string ID) {
this.buffer = new byte[bufferSize];
this.client = client;
this.ID = ID;
}
public void Start() {
// Thu lấy network stream
networkStream = client.GetStream();
// Tạo các đối tượng dùng để gửi và nhận text
BinaryWriter w = new BinaryWriter(networkStream);
BinaryReader r = new BinaryReader(networkStream);
fileStream = new FileStream("test.bin", FileMode.Open);
Trang 30private void StreamData(IAsyncResult asyncResult) {
// Hủy bỏ nếu client ngừng kết nối
// Lấy khối kế tiếp từ file
int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
// Nếu không đọc được byte nào, stream đa đến cuối file
if (bytesRead > 0) {
Trang 3131
Console.WriteLine("Streaming new block.");
// Ghi khối kế tiếp ra network stream
networkStream.BeginWrite(buffer, 0, buffer.Length,
new AsyncCallback(StreamData), null);
}
Trang 3232
CHƯƠNG 2 : PHÂN TÍCH BÀI TOÁN CHƠI CỜ TƯỚNG TRÊN
MẠNG INTERNET 2.1 Giới thiệu bài toán chơi cờ tướng trên mạng Internet
Bài toán chơi cờ tướng trên mạng Internet được xây dựng trên mô hình Client / Server được ứng dụng trên 3 máy Client / Server / Client, cho phép người chơi có thể chơi cờ và chat với nhau qua mạng Internet
Hình 2.1 : Mô hình Client / Server
Server : server hoạt động tạo ra một socket với một cổng ứng dụng và chờ đợi yêu cầu kết nối từ phía client qua cổng này, khi có yêu cầu kết nối thì Server chấp nhận yêu cầu và tạo một socket phục vụ client, sau đó chương trình ứng dụng phía Server sẽ gửi thông báo chấp nhận kết nối cho Client cùng thông tin về địa chỉ cổng mới của socket mà nó dành cho Client
Client: Nó biết địa chỉ IP của Server đang chạy và cổng mà Server đang chờ nghe yêu cầu Do đó Client cũng tạo ra một socket chứa địa chỉ máy client và cổng ứng dụng trên máy client, đồng thời client cung cấp cho socket của nó địa chỉ IP và cổng của Server mà nó cần kết nối và yêu cầu Socket thực hiện kết nối Khi Server nhận được yêu cầu kết nối từ Client, nếu nó chấp nhận thì server sẽ sinh ra một socket mới được gắn với một cổng khác với cổng mà nó đang nghe yêu cầu Sở dĩ server làm như vậy bởi nó cần cổng cũ để tiếp tục nghe yêu cầu từ phía client trong khi vẫn cần một kết nối với client Và nếu kết nối được chấp nhận nghĩa là socket của nó đã được tạo thành công và nó có thể sử dụng socket
để giao tiếp với server bằng cách viết và ghi tới socket theo cách giao tiếp với
một tài nguyên trên máy tính thông thường
Trang 3333
2.2 Mô hình Client/Server
2.2.1 Khái niệm mô hình Client/Server
Khái niệm về thành phần Client : Phần mềm chịu tránh nhiệm thu nhận yêu
cầu của người sử dụng, xử lý sơ bộ và chuyển cho Server dưới một dạng thích hợp Nó cũng làm nhiệm vụ nhận kết quả từ Server gửi đến và hiển thị thông tin
cho người sử dụng
Khái niệm về thành phần Server : Nhận các yêu cầu từ Client, xử lý chúng
bằng nhiều cách như đọc tệp, tìm kiếm cơ sở dữ liệu rồi gửi trả lại kết quả cho Client
Khái niệm Client/Server : Là hai phần mềm có thể được thực hiện trên cùng
một máy hoặc trên hai máy với các hệ điều hành khác nhau.Việc xử lý thông tin thực hiện trên Server.Client đóng vai trò giao tiếp với người sử dụng và thực hiện
trao đổi dữ liệu với Server nếu cần.Việc kết nối giữa Client và Server tuân theo
các giao thức trao đổi thông tin nhất định
2.2.2 Mô hình Client/Server trên Internet
Internet là môi trường với các ứng dụng tính toán phân tán được phát triển trên đó Mô hình thông tin được sử dụng này là Client/Server, trong đó việc xử lý thông tin của các ứng dụng được phân tán trên hai hay nhiều máy Do vậy không
có gì ngạc nhiên khi mô hình thông tin được sử dụng trên ứng dụng Internet gần với mô hình tính toán Client/Server Do vậy Internet là quá khứ và tương lai của của mô hình Client/Server
Mô hình này thật đơn giản.Trước tiên Client kết nối đến Server sau đó Client
và Server chiếm lấy đàm thoại trong đó Client gửi yêu cầu đến Server và Server trả lời cho Client Đàm thoại kết thúc khi Client huỷ bỏ kết nối đến Server Hầu hết các ứng dụng trên Client/Server đều sử dụng các kí tự ASCII, các lệnh và cách trả lời dựa trên dạng text Một số ứng dụng trên Client/Server sử dụng các lệnh và trả lời dưới dạng nhị phân Các lệnh và cách trả lời được gửi dưới dạng nhị phân để gom dữ liệu gửi giữa hai máy tính
Hầu hết các ứng dụng Client/Server đều sử dụng giao thức TCP/IP Các giao thức này cung cấp cho mô hình thông tin mức sử dụng Socket Các Socket cung