TRƯỜNG CAO ĐẲNG CÔNG NGHỆ THÔNG TIN

HỮU NGHỊ VIỆT-HÀN
KHOA KHOA HỌC MÁY TÍNH

ĐỒ ÁN MÔN HỌC
LẬP TRÌNH MẠNG NÂNG CAO
ĐỀ TÀI

SỬ DỤNG KỸ THUẬT LẬP TRÌNH SOCKET XÂY
DỰNG CHƯƠNG TRÌNH SCAN IP

SVTH

: Nguyễn Đức Trung
Trương Văn Đông
Tô Thị Thu Thủy

Lớp

: CCMM03C

Niên khóa : 2009 – 2012
CBHD

: Ths. Nguyễn Vũ

Đà Nẵng, tháng 3 năm 2012

LỜI MỞ ĐẦU
Hiện nay, mạng máy tính là công nghệ của mọi thời đại. Các ứng dụng mạng đóng vai
trò không thể thiếu để khai thác tiềm năng của mạng máy tính, đặc biệt là mạng Internet.
Do vậy, lập trình mạng là môn học không thể thiếu của sinh viên ngành công nghệ thông
tin nói chung và sinh viên chuyên ngành mạng nói riêng. Mục đích của môn học lập trình
mạng là cung cấp cho sinh viên biết kiến thức mạng liên quan cũng như cơ chế hoạt động
và kiến trúc của các phần mềm mạng. Từ đó, hiểu và biết cách viết các chương trình ứng
dụng trong một hệ thống mạng quy mô nhỏ cũng như mạng Internet.
C# là một ngôn ngữ mềm dẻo và rất phổ biến. Nó sử dụng hệ thống kiểu/đối tượng
trong.NET mà ở đó, các chương trình C# có thể giao tiếp với nhiều ngôn ngữ khác trong
.NET mà không gặp rắc rối nào về kiểu. Dựa trên kiến thức lập trình mạng với C#, cộng
với sự đa dạng của các dịch vụ mạng với nhiều tính năng hỗ trợ cao. Từ ý tưởng xây dựng
một chương trình scan IP có khả năng quét cổng, có khả năng quét các địa chỉ trong phạm
vi bất kỳ, cũng như bất kỳ các cổng. Chương trình ScanIP được xây dựng với một số tính
năng hoàn chỉnh như: xác định địa chỉ MAC, quét cổng v.v…
Mục tiêu của đồ án là tìm hiểu về mạng máy tính và kỹ thuật lập trình socket với ngôn
ngữ lập trình C#, trên cơ sở đó xây dựng một chương trình quét cổng trên mạng nội bộ.
Bao gồm ba chương:
Chương I. Tổng Quan Về Lập Trình Mạng
Chương II. Lập Trình Mạng Với Socket
Chương III. Thiết kế Và Xây Dựng Chương Trình
Trong quá trình xây dựng chương trình do thời gian ngắn và chưa đủ kiến thức, nên
không tránh khỏi sai sót. Kính mong thầy cô cùng các bạn đóng góp ý kiến xây dựng để
nhóm hoàn thiện hơn. Cuối cùng, nhóm em xin chân thành cảm ơn thầy Nguyễn Vũ đã hỗ
trợ và tạo điều kiện giúp chúng em hoàn thành đồ án này.

Đà Nẵng, tháng 3 năm 2012

MỤC LỤC

MỤC LỤC...............................................................................................................................i
DANH MỤC HÌNH ẢNH.......................................................................................................i
CHƯƠNG 1. TỔNG QUAN VỀ LẬP TRÌNH MẠNG.........................................................ii
1.1.GIỚI THIỆU VỀ NGÔN NGỮ C#..............................................................................ii
1.2.KIẾN TRÚC .NET.......................................................................................................ii
1.3.NGÔN NGỮ C#..........................................................................................................iv
1.4.MÔ HÌNH THAM CHIẾU OSI....................................................................................v
1.5.CHỒNG GIAO THỨC TCP/IP.................................................................................viii
1.6.MÔ HÌNH TRUYỀN THÔNG TRONG CẤU TRÚC MẠNG....................................x
1.6.1.Nguyên tắc truyền thông........................................................................................x
1.6.2.Nguyên tắc của phương pháp phân tầng...............................................................xi
1.6.3.Địa chỉ IP – Các địa chỉ IP dành riêng.................................................................xii
1.7.GIAO THỨC ICMP...................................................................................................xii
1.7.1.Giới thiệu ICMP..................................................................................................xiii
1.7.2.Cấu trúc...............................................................................................................xiii
1.7.3.Danh sách các thông điệp điều khiển của giao thức ICMP ................................xiv
CHƯƠNG 2. LẬP TRÌNH MẠNG VỚI SOCKET............................................................xvi
2.1.GIỚI THIỆU VỀ LẬP TRÌNH VỚI SOCKET.........................................................xvi
1.8.SỬ DỤNG RAW SOCKET.....................................................................................xvii
CHƯƠNG 3. THIẾT KẾ VÀ XÂY DỰNG CHƯƠNG TRÌNH......................................xxiv
1.9.PHÂN TÍCH YÊU CẦU.........................................................................................xxiv
1.10.PHÂN TÍCH CÁC CHỨC NĂNG........................................................................xxiv
1.10.1.Phương thức hoạt động của ứng dụng............................................................xxiv
1.10.2.Xây dựng chức năng.......................................................................................xxiv
1.11. XÂY DỰNG CHỨC NĂNG.................................................................................xxv
1.11.1.Xây dựng chức năng gửi gói tin.......................................................................xxv
1.11.2.Xây dựng chức năng nhận gói tin và xử lý......................................................xxv
1.11.3.Xây dựng chức năng quét địa chỉ IP..............................................................xxvii

1.12.GIAO DIỆN VÀ SỬ DỤNG CHƯƠNG TRÌNH................................................xxvii
1.12.1.Giao diện........................................................................................................xxvii
1.12.2.Sử dụng chương trình....................................................................................xxxix
KẾT LUẬN..........................................................................................................................xli
DANH MỤC TÀI LIỆU THAM KHẢO.............................................................................42
NHÂN XÉT CỦA GIẢNG VIÊN HƯỚNG DẪN...............................................................43

DANH MỤC HÌNH ẢNH

Hình 1. 1. Mô tả các thành phần trong .NET Framework.....................................................iii
Hình 1. 2.Mô hình OSI............................................................................................................v
Hình 1.3. Mô hình chồng giao thức TCP/IP..........................................................................ix
Hình 2.1. Giới thiệu về lập trình với socket.........................................................................xvi
Hình 3.1. Giao diện chính của chương trình scanip..........................................................xxvii
Hình 3.2. Chức năng quét tất cả các địa chỉ ip................................................................xxviii
Hình 3.3. Chức năng quét theo lớp..................................................................................xxviii

i

CHƯƠNG 1. TỔNG QUAN VỀ LẬP TRÌNH MẠNG
1.1.

GIỚI THIỆU VỀ NGÔN NGỮ C#
Microsoft .NET không phải là một ngôn ngữ lập trình, đó là một không gian làm việc

tổng hợp bởi bốn bộ ngôn ngữ lập trình: C#, VB.NET, Managed C++, and J# . NET. ở đó
có sự chồng gối lên nhau của các ngôn ngữ, và được định nghĩa trong FCL (Framework
Class Library).
Microsoft .NET bao gồm 2 thành phần chính: Framework và Intergrated Development
Enviroment (IDE). Framework cung cấp những gì cần thiết và căn bản, là khuôn dạng hay
môi trường hỗ trợ các hạ tầng cơ sở theo một quy ước nhất định để công việc được thuận
tiện. IDE cung cấp một môi trường giúp chúng ta triển khai được dễ dàng và nhanh chóng
các ứng dụng trên nền tảng .NET.
Thành phần Framework là quan trọng nhất .NET đây là cốt lõi và tinh hoa của môi
trường, còn IDE chỉ là công cụ để phát triển dựa trên nền tảng đó. Trong .NET toàn bộ các
ngôn ngữ C#, Visual C++ hay Visual Basic .NET đều dùng cùng một IDE.
Microsoft .NET là nền tảng cho việc ứng dụng và thực thi các ứng dụng phân tán thế
hệ kế tiếp. Bao gồm các ứng dụng từ client đến server và các dịch vụ khác. Một số tính
năng của Microsoft .NET cho phép những nhà phát triển sử dụng như sau:
o Một mô hình lập trình cho phép nhà phát triển xây dựng các ứng dụng dịch vụ
web và ứng dụng client với Extensible Markup Language (XML).
o Tập hợp dịch vụ XML Web, như Microsoft .NET My Services cho phép nhà
phát triển đơn giản và tích hợp người dùng kinh nghiệm.
o Cung cấp các server phục vụ bao gồm: Windows 2000, SQL Server và BizTalk
Server, tất cả đều tích hợp, hoạt động và quản lý các dịch XML Web và các ứng dụng
o Các phần mềm client như Windows XP và Windows CE giúp người phát triển
phân phối sâu và thuyết phục người dùng kinh nghiệm thông qua các dòng thiết bị.
o Nhiều công cụ hỗ trợ như Visual Stuido .NET, để phát triển các dịch vụ Web
XML, ứng dụng trên nền Windows hay nền web một cách dễ dàng và hiệu quả.
1.2.

KIẾN TRÚC .NET
ii

.NET Framework là một platform mới giúp làm đơn giản việc phát triển ứng dụng
trong môi trường phân tán của Internet. .NET Framework được thiết kế đầy đủ để đáp ứng
theo quan điểm sau:

Hình 1. 1. Mô tả các thành phần trong .NET Framework
o Để cung cấp một môi trường lập trình hướng đối tượng vững chắc, trong đó mã
nguồn đối tượng được lưu trữ và thực thi một cách cục bộ. Thực thi cục bộ nhưng được
phân tán trên Internet, hoặc thực thi từ xa.
o Để cung cấp một môi trường thực thi mã nguồn mà tối thiểu được việc đóng gói
phần mềm và sự tranh chấp về phiên bản.
o Để cung cấp một môi trường thực thi mã nguồn mà đảm bảo việc thực thi an
toàn mã nguồn, bao gồm cả việc mã nguồn được tạo ra bởi hãng thứ ba hay bất cứ hãng nào
mà tuân thủ theo kiến trúc .NET.Để cung cấp một môi trường thực thi mã nguồn mà loại bỏ
được những lỗi thực hiện các script hay môi trường thông dịch.
o Để làm cho những người phát triển có kinh nghiệm vững chắc có thể nắm vững
nhiều kiểu ứng dụng khác nhau. Như là từ những ứng dụng trên nền Windows đến những
ứng dụng dựa trên web.
o Để xây dựng tất cả các thông tin dựa trên tiêu chuẩn công nghiệp để đảm bảo
rằng mã nguồn trên .NET có thể tích hợp với bất cứ mã nguồn khác.
.NET Framework có hai thành phần chính: Common Language Runtime (CLR) và thư
viện lớp .NET Framework. CLR là nền tảng của .NET Framework. Chúng ta có thể hiểu
iii

như: quản lý bộ nhớ, quản lý tiểu trình, và quản lý từ xa. Ngoài ra nó còn thúc đẩy việc sử
dụng kiểu an toàn và các hình thức khác của việc chính xác mã nguồn, đảm bảo cho việc
thực hiện được bảo mật và mạnh mẽ. Thật vậy, khái niệm quản lý mã nguồn là nguyên lý
nền tảng của runtime. Mã nguồn mà đích tới runtime thì được biết như là mã nguồn được
quản lý (managed code). Trong khi đó mã nguồn mà không có đích tới runtime thì được
biết như mã nguồn không được quản lý (unmanaged code).
Thư viện lớp, một thành phần chính khác của .NET Framework là một tập hợp hướng
đối tượng của các kiểu dữ liệu được dùng lại, nó cho phép chúng ta có thể phát triển những
ứng dụng từ những ứng dụng truyền thống command-line hay những ứng dụng có giao diện
đồ họa (GUI) đến những ứng dụng mới nhất được cung cấp bởi ASP.NET, như là Web
Form và dịch vụ XML Web.
1.3.

NGÔN NGỮ C#
Ngôn ngữ C# khá đơn giản, chỉ khoảng 80 từ khóa và hơn mười mấy 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, 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.
Phần cốt lõi 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à tính
đ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 đề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.

iv

Trong 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 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 (component-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
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ó.
Ngôn ngữ C# hỗ trợ 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. 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.4.

MÔ HÌNH THAM CHIẾU OSI

Hình 1. 2.Mô hình OSI

v

Mô hình tham chiếu OSI (Open Systems Interconnection Reference Model) là một
thiết kế dựa vào nguyên lý tầng cấp, lý giải một cách trừu tượng kỹ thuật kết nối truyền
thông giữa các máy tính và thiết kế giao thức mạng giữa chúng. Mô hình này được phát
triển thành một thành phần trong kế hoạch Kết nối các hệ thống mở dong ISO và IUT-T
khởi xướng.
Mô hình tham chiếu OSI định nghĩa các quy tắc cho các nội dung sau:
o Cách thức các thiết bị giao tiếp và truyền thông được với nhau.
o Các phương pháp để các thiết bị trên mạng khi nào thì được truyền dữ liệu, khi
nào thì không được.
o Các phương pháp để đảm bảo truyền đúng dữ liệu và đúng bên nhận.
o Cách thức vận tải, truyền, sắp xếp và kết nối với nhau.
o Cách thức đảm bảo các thiết bị mạng duy trì tốc độ truyền dữ liệu thích hợp
o Các biểu diễn một bit truyền dẫn
Mô hình tham chiếu OSI được chia thành bảy lớp với các chức năng sau:
o Lớp ứng dụng (Application Layer): là giao diện giữa các chương trình ứng dụng
của người dùng và mạng. Lớp application xử lý truy cập mạng chung, kiểm soát luồng và
phục hồi lỗi. Lớp này không cung cấp các ứng dụng cho lớp nào mà nó cung cấp dịch vụ
cho các ứng dụng như: truyền file, gởi nhận E-mail, Telnet, HTTP, FTP, SMTP …
o Lớp trình diễn (Presentation Layer): lớp này chịu trách nhiệm thương lượng và
xác lập dạng dữ liệu được trao đổi. Nó đả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. 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, đồng thời nó
cũng nén và giải nén dữ liệu.
o Lớp phiên (Session Layer): lớp này có chức năng thiết lập, quản lý, và kết thúc
các phiên thông tin giữa hai thiết bị truyền nhận. Lớp phiên cung cấp các dịch vụ cho lớp
trình bày. Lớp phiên cung cấp sự đồng bộ hóa giữa các tác vụ người dùng bằng cách đặt
những kiểm tra vào luồng dữ liệu. Bằng cách này, nếu mạng không hoạt động thì chỉ có dữ
liệu truyền sau điểm kiểm tra cuối cùng mới phải truyền lại. Lớp này cũng thi hành kiểm
vi

soát hội thoại giữa các quá trình giao tiếp, điều chỉnh bên nào truyền, khi nào, trong bao
lâu.
o Lớp vận chuyển (Transport Layer): lớp vận chuyển phân đoạn dữ liệu từ hệ
thống máy 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 máy nhận đảm
bảo rằng việc bàn giao các thông điệp giữa các thiết bị là đáng tin cậy. Lớp này thiết lập,
duy trì và kết thúc các mạch ảo đảm bảo cung cấp các dịch vụ sau:

Xếp thứ tự các phân đoạn: khi một thông điệp lớn được tách thành

nhiều phân đoạn nhỏ để bàn giao, lớp vận chuyển sẽ sắp xếp thứ tự các phân
đoạn trước khi ráp nối các phân đoạn thành thông điệp ban đầu.

Kiểm soát lỗi: khi có phân đoạn bị thất bại, sai hoặc trùng lặp, lớp

vận chuyển sẽ yêu cầu truyền lại.

Kiểm soát luồng: lớp vận chuyển dùng các tín hiệu báo nhận để

xác nhận. Bên gửi sẽ không truyền đi phân đoạn dữ liệu kế tiếp nếu bên nhận
chưa gửi tín hiệu xác nhận rằng đã nhận được phân đoạn dữ liệu trước đó đầy
đủ.
o

Lớp mạng (Network Layer): lớp này chịu trách nhiệm lập địa chỉ các thông

điệp, diễn dịch địa chỉ và tên logic thành địa chỉ vật lý đồng thời nó cũng chịu trách nhiệm
gởi packet từ mạng nguồn đến mạng đích. Lớp này quyết định đường đi từ máy tính nguồn
đến máy tính đích. Nó quyết định dữ liệu sẽ truyền trên đường nào dựa vào tình trạng, độ
ưu tiên dịch vụ và các yếu tố khác. Nó cũng quản lý lưu lượng trên mạng chẳng hạn như
chuyển đổi gói, định tuyến, và kiểm soát sự tắc nghẽn dữ liệu.
o

Lớp liên kết dữ liệu (Data Link Layer): 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ý. Lớp này liên quan đến: địa chỉ vật lý, mô hình mạng, cơ
chế truy cập đường truyền, thông báo lỗi, thứ tự phân phối frame, điều khiển dòng. Tại lớp
liên kết dữ liệu, các bit đến từ lớp vật lý được chuyển thành các frame dữ liệu bằng cách
dùng một số nghi thức tại lớp này. Lớp liên kết dữ liệu được chia thành hai lớp con:
• Lớp LLC (Logical Link Control): phần trên so với các giao thức truy cập
đường truyền khác, nó cung cấp sự mềm dẻo về giao tiếp. Bởi vì lớp con LLC
hoạt động độc lập với các giao thức truy cập đường truyền, cho nên các giao
vii

thức lớp trên hơn có thể hoạt động mà không phụ thuộc vào loại phương tiện
LAN. Lớp con LLC có thể lệ thuộc vào các lớp thấp hơn trong việc cung cấp
truy nhập đường truyền.
• Lớp MAC (Media Access Control): cung cấp tính thứ tự truy cập vào môi
trường LAN. Khi nhiều trạm cùng truy cập chia sẻ môi trường truyền, để định
danh mỗi trạm, lớp MAC định nghĩa môi trường địa chỉ phần cứng gọi là địa chỉ
MAC – đây là một con số đơn nhất đối với mỗi giao tiếp LAN.
o

Lớp vật lý (Physical Layer): định nghĩa các quy cách về điện, cơ, thủ tục và

đặ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. Bao gồm việc truyền tải tín hiệu trong môi trường từ máy tính này đến máy tính khác.
Lớp này gồm các chi tiết kỹ thuật về các đặc tính điện và cơ như : mức điện áp, định thời
tín hiệu, tốc độ dữ liệu, độ dài truyền tải lớn nhất và các kết nối vật lý của thiết bị mạng. Để
một thiết bị hoạt động chỉ trong lớp vật lý, nó sẽ không có bất kỳ kiến thức nào về dữ liệu
mà nó truyền tải. Một thiết bị lớp vật lý chỉ truyền tải hoặc nhận dữ liệu một cách đơn giản.
1.5.

CHỒNG GIAO THỨC TCP/IP
Bộ giao thức TCP/IP (Internet Protocol Suite) là một bộ các giao thức truyền thông

cài đặt chồng giao thức mà Internet và hầu hết các mạng máy tính thương mại đang chạy
trên đó. Bộ giao thức này được đặt theo hai giao thức chính của nó là TCP và IP. Là 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 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 logic, 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ý.

viii

Hình 1.3. Mô hình chồng giao thức TCP/IP
TCP/IP có cấu trúc tương tự như mô hình OSI, tuy nhiên để đảm bảo tính tương thích
giữa các mạng và sự tin cậy của việc truyền thông tin trên mạng, bộ giao thức TCP/IP được
chia thành 2 phần riêng biệt: giao thức IP sử dụng cho việc kết nối mạng và giao thức TCP
để đảm bảo cho việc truyền dữ liệu một cách tin cậy.
Mô hình tham chiếu TCP/IP được chia thành bốn lớp với các chức năng sau:
o

Lớp ứng dụng (Application Layer): tại mức cao nhất này, người sử dụng thực

hiện các chương trình ứng dụng truy xuất đến các mức dịch vụ hiện hữ trên TCP/IP
Internet. Một ứng dụng tương tác với một trong những protocol ở mức giao vận (transport)
để gửi hoặc nhận dữ liệu. Mỗi chương trình ứng dụng chọn một kiểu giao vận mà nó cần,
có thể là một dãy tuần tự từng thông điệp hoặc một chuỗi các byte liên tục. Chương trình
ứng dụng sẽ gửi dữ liệu đi dưới dạng nào đó mà nó yêu cầu đến lớp giao vận.
o

Lớp giao vận(Transport Layer) : Nhiệm vụ cơ bản của lớp giao vận là cung

cấp phương tiện liên lạc từ một chương trình ứng dụng này đến một chương trình ứng dụng
khác. Việc thông tin liên lạc đó thường được gọi là end-to-end. Mức chuyên chở có thể
điều khiển luồng thông tin. Nó cũng có thể cung cấp sự giao vận có độ tin cậy, bảo đảm dữ
liệu đến nơi mà không có lỗi và theo đúng thứ tự. Để làm được điều đó, lớp giao vận cung
cấp giao thức TCP, trong quá trình trao đổi thông tin nơi nhận sẽ được gửi ngược trở lại
một xác nhận (ACK) và nơi gửi sẽ truyền lại những gói dữ liệu bị mất. Tuy nhiên trong
những môi trường truyền dẫn tốt như cáp quang chẳng hạng thì việc xảy ra lỗi là rất nhỏ.
Lớp giao vận có thể cung cấp một giao thức khác đó là UDP.
ix

o

Lớp Internet (Internet Layer): Nhiệm vụ cơ bản của lớp này là xử lý việc liên

lạc của các thiết bị trên mạng. Nó nhận được một yêu cầu để gửi gói dữ liệu từ lớp trên
cùng với một định danh của máy mà gói dữ liệu phải được gởi đến. Nó đóng segment vào
trong một packet, điền vào phần mào đầu của packet, sau đó sử dụng giao thức định tuyến
để chuyển gói tin đến được đích của nó hoặc trạm kế tiếp. Khi đó tại nơi nhận sẽ kiểm tra
tính hợp lệ của chúng, và sử dụng tiếp các giao thức định tuyến để xử lý gói tin. Đối với
những packet được xác định thuộc cùng mạng cục bộ, phần mềm Internet sẽ cắt bỏ phần
đầu của packet, và chọn một trong các giao thức lớp trung chuyển thích hợp để xử lý
chúng. Cuối cùng, lớp Internet gửi và nhận các thông điệp kiểm soát và xử lý lỗi ICMP.
o

Lớp giao tiếp mạng (Network Access Layer): Lớp thấp nhất của mô hình

TCP/IP chính là lớp giao tiếp mạng, có trách nhiệm nhận các IP datagram và truyền chúng
trên một mạng nhất định. Người ta lại chia lớp này thành hai lớp con là: Lớp vật lý – làm
việc với các thiết bị vật lý, truyền tới dòng bit 0, 1 từ nơi gửi đến nơi nhật. Lớp liên kết dữ
liệu – tại đây dữ liệu được tổ chức thành các khung (frame). Phần đầu khung chứa địa chỉ
và thông tin điều khiển, phần cuối khung dành cho việc phát hiện lỗi.
1.6.

MÔ HÌNH TRUYỀN THÔNG TRONG CẤU TRÚC MẠNG

1.6.1. Nguyên tắc truyền thông
Để một mạng máy tính trở thành môi trường truyền dữ liệu thì nó cần phải có những
yếu tố sau:
o

Các hệ thống được liên kết với nhau theo một cấu trúc kết nối (topology) nào

o

Việc chuyển dữ liệu từ máy tính này đến máy tính khác do mạng thực hiện

đó.
thông qua những quy định thống nhất gọi là giao thức của mạng.
o

Phân chia hoạt động truyền thông của hệ thống thành nhiều lớp theo các

nguyên tắc nhất định.
o

Việc nhận xét các module một cách độc lập với nhau cho phép giảm độ phức

tạp cho việc thiết kế và cài đặt. Phương pháp này được sử dụng rộng rãi trong việc xây
dựng mạng và các chương trình truyền thông và được gọi là phương pháp phân tầng
(layer).
x

1.6.2. Nguyên tắc của phương pháp phân tầng
Mỗi hệ thống thành phần trong mạng được xây dựng như một cấu trúc nhiều tầng và
đều có cấu trúc giống nhau như: số lượng tầng và chức năng của mỗi tầng.
Các tầng nằm chồng lên nhau, dữ liệu chỉ được trao đổi trực tiếp giữa hai tầng kề
nhau từ tầng trên xuống tầng dưới và ngược lại.
Cùng với việc xác định chưc năng của mỗi tầng chúng ta phải xác định mỗi quan hệ
giữa hai tầng kề nhau. Dữ liệu được truyền đi từ tầng cao nhất của hệ thống truyền lần lượt
đến tầng thấp nhất , tiếp đến truyền qua đường nối vật lý dưới dạng các bit tới tầng thấp
nhất của hệ thống nhận, sau đó dữ liệu được truyền ngược lên trên tầng cao nhất của hệ
thống nhận.
Chỉ có hai tầng thấp nhất có liên kết vật lý với nhau còn các tầng trên cùng thứ tự chỉ
có các liên kết logic với nhau. Liên kết logic của một tầng được thể hiện thông qua các tầng
dưới và phải tuân theo những quy định chặt chẽ, các quy định đó được gọi là giao thức của
tầng. Trong kiến trúc phân tầng, một số mô hình được phát triển : mô hình OSI, TCP/IP.
Xét trên phương diện lập trình với máy tính, ta xét mô hình phân tầng thu gọn: Nói
chung trong truyền thông có sự tham gia của các thành phần: Các chương trình ứng dụng,
các chương trình truyền thông, các máy tính và các mạng. Các chương trình ứng dụng là
các chương trình của người sử dụng được thực hiện trên máy tính và có thể tham gia vào
quá trình trao đổi thông tin giữa hai máy tính. Trên một máy tính với hệ điều hành đa
nhiệm (như Windows, UNIX) thường được thực hiện đồng thời nhiều ứng dụng trong đó
có những ứng dụng liên quan đến mạng và các ứng dụng khác. Các máy tính được nối với
mạng và các dữ liệu trao đổi thông qua mạng từ máy tính này đến máy tính khác.
Việc gửi dữ liệu được thực hiện giữa một ứng dụng với một ứng dụng khác trên hai
máy tính khác nhau thông qua mạng được thực hiện như sau: Ứng dụng gửi chuyển dữ liệu
cho chương trình truyền thông trên máy tính của nó, chương trình truyền thông sẽ gửi
chúng tới máy tính nhận. Chương trình truyền thông trên máy nhận sẽ tiếp nhận dữ liệu,
kiểm tra nó trước khi chuyển giao cho ứng dụng đang chờ dữ liệu.
Với mô hình truyền thông đơn giản người ta chia chương trình truyền thông thành ba
tầng không phụ thuộc vào nhau là : tầng ứng dụng, tầng giao vận và tầng tiếp cận mạng.
xi

o

Tầng tiếp cận mạng: Liên quan đến việc trao đổi dữ liệu giữa máy tính và

mạng mà nó được nối vào. Để dữ liệu đến được đích máy tính gửi cần phải chuyển địa chỉ
của máy tính nhận cho mạng và qua đó mạng sẽ chuyển các thông tin tới đích. Ngoài ra
máy gửi có thể sử dụng một số dịch vụ khác nhau mà mạng cung cấp như gửi ưu tiên, tốc
độ cao.
o

Tầng giao vận: Thực hiện quá trình truyền thông end-to-end giữa hai ứng

dụng không liên quan tới mạng và nằm ở trên tầng tiếp cận mạng. Tầng truyền dữ liệu
không quan tâm đến bản chất các ứng dụng đang trao đổi dữ liệu mà quan tâm tới làm sao
cho các dữ liệu trao đổi một cách an toàn. Tầng truyền dữ liệu đảm bảo các dữ liệu đến
được đích và đến theo đúng thức tự mà chúng được xử lý.Trong tầng truyền dữ liệu người
ta phải có những cơ chế nhằm đảm bảo sự chính xác đó và rõ ràng các cơ chế này không
phụ thuộc vào bản chất của tầng ứng dụng và chúng sẽ phục vụ cho tất cả các ứng dụng.
o

Tầng ứng dụng: Sẽ chứa các module phục vụ cho tất cả những ứng dụng của

người dùng. Với các loại ứng dụng khác nhau (truyền file, truyền thư mục) cần các module
khác nhau.
1.6.3. Địa chỉ IP – Các địa chỉ IP dành riêng
Mỗi địa chỉ IP có độ dài 32 bit (đối với IPv4) được tách thành 4 vùng (mỗi vùng 1
byte), có thể được biểu thị dưới dạng thập phân, bát phân, thập lục phân hoặc nhị phân.
Cách viết phổ biến nhất là dùng ký pháp thập phân có dấu chấm để tách giữa các vùng. Địa
chỉ IP là để định danh duy nhất cho một host bất kỳ trên liên mạng.
Khuôn dạng địa chỉ IP: Mỗi host trên mạng TCP/IP được định danh duy nhất bởi một địa
chỉ có khuôn dạng <Network Number, Host Number>. Do tổ chức và độ lớn của các mạng
con của liên mạng có thể khác nhau, người ta chia địa chỉ IP thành 5 lớp ký hiệu A, B, C,
D, E. Các bit đầu tiên của byte đầu tiên được dùng để định danh lớp địa chỉ (0-lớp A; 10
lớp B; 110 lớp C; 1110 lớp D; 11110 lớp E).
Subneting: Trong nhiều trường hợp, một mạng có thể được chia thành nhiều mạng
con, lúc đó có thể đưa thêm các vùng subnetid để định danh các mạng con. Vùng subnetid
được lấy từ vùng hosted, cụ thể đối với 3 lớp A, B, C.
1.7.

GIAO THỨC ICMP
xii

ICMP(Internetwork Control Message Protocol) là một trong những giao thức cốt lõi
của giao thức Internet Suite. Đó là chủ yếu được sử dụng bởi các hệ điều hành của máy tính
nối mạng để gửi thông báo lỗi cho thấy, ví dụ: Một dịch vụ yêu cầu không có hoặc có một
máy chủ hoặc router không thể đạt được. ICMP cũng có thể được sử dụng để chuyển tiếp
tin nhắn truy vấn.
ICMP khác với giao thức vận chuyển như TCP và UDP ở chổ nó không thường được
sử dụng để trao đổi dữ liệu giữa các hệ thống, cũng không phải là thường xuyên làm việc
của người sử dụng các ứng dụng mạng lưới cấp (với ngoại lệ của một số công cụ chuẩn
đoán như Ping và Tracerouter).
ICMP cho giao thức Internet phiên bản ICMPv4. IPv6 có một giao thức tương tự,
ICMPv6.
1.7.1. Giới thiệu ICMP
Internet Control Message Protocol là một phần của giao thức Internet Suite được định
nghĩa trong RFC 792. Thông điệp ICMP thường được tạo ra để đáp ứng với các lỗi trong IP
datagrams (theo quy định tại RFC 1122), hoặc cho hay định tuyến nhằm mục đích chẩn
đoán. ICMP luôn luôn được báo cáo với nguồn địa chỉ IP gốc của gói dữ liệu có nguồn gốc.
Mỗi thông điệp ICMP được đóng gói trực tiếp trong một gói dữ liệu IP duy nhất, và
do đó, giống như UDP, ICMP là giao thức không đáng tin cậy.
Mặc dù thông điệp ICMP được chứa trong tiêu chuẩn IP datagrams, các thông điệp
ICMP thường được xử lý như một trường hợp đặc biệt, phân biệt với cách điều chế IP bình
thường. Trong nhiều trường hợp, việc kiểm tra các nội dung của thông điệp ICMP là rất
cần thiết, nó cung cấp những thông báo lỗi thích hợp cho các ứng dụng tạo ra các gói IP
ban đầu.
Nhiều tiện ích mạng thông dụng dựa trên thông điệp ICMP. Các lệnh tracerouter được
thực hiện bằng cách truyền UDP datagrams với gói tin được đặt thêm thông số IP TTL, và
tìm kiếm ICMP có thời gian sống lớn hơn TTL và “Destination ủneachable” trong quá trình
truyền. Các tiện ích ping được thực hiện bằng cách sử dụng ICMP “Echo Request” và
“Echo Reply”.
1.7.2. Cấu trúc
xiii

Các gói tin bắt đầu sau IP header (20 bytes). Tất cả các gói ICMP sẽ có một header có
kích thước 8 byte và phần biến dữ liệu. 4 byte đầu tiên của header này sẽ được nhất quán.
Các byte đầu tiên dành cho trường Type. Các byte thứ hai là cho trường Code. Các byte thứ
ba và thứ tư là trường Checksum. Nội dung của các byte từ byte thứ 4 của header sẽ khác
nhau dựa trên trường Type và Code.
Thông báo lỗi của ICMP có chứa một phần dữ liệu bao gồm toàn bộ các IP header
cộng với các byte đầu tiên của gói tin mà tạo ra các thông báo lỗi khác nhau. Các gói dữ
liệu ICMP sau đó được gói gọn trong một gói IP mới.
o

Type – ICMP Code theo quy định

o

Code – Kiểu loại hình nhất định.

o

Checksum – Kiểm tra lỗi dữ liệu. Tính từ ICMP header + dữ liệu, với giá trị

0 cho trường này.
Bit

0-7
0
32

8-15
Loại
Message

16-23

24-31
Checksum

1.7.3. Danh sách các thông điệp điều khiển của giao thức ICMP
Type
0 – Echo Reply
1&2
3- Destination Ủneachable

4- Source Quench

Code
0
0
1
2
3
4
5
6
7
8
9
10
11
12
13
0

Description
Có phản hồi lại (sử dụng để ping)
Dành riêng
Điểm đích của mạng không thể truy cập
Host đích không thể truy cập
Giao thức đích không thể truy cập
Cổng đích không thể truy cập
Yêu cầu sự phân mảnh, và đặt cờ DF
Định tuyến nguồn bị lỗi
Không biết mạng đích
Không biết máy đính
Host nguồn bị cô lập
Mạng hành chính bị cấm
Host hành chính bị cấm
Mạng không thể truy cập cho TOS
Máy không thể truy cập cho TOS
Bị cấm truyền thông
Nguồn bị tắt (điều khiển tắc nghẽn)
xiv

5- Redirect Message

0
1
2
3

6
7
8- Echo Request
9- Router Advertisement
10- Router Solicitation
11- Time Exceeded

0
0
0
0
1
12- Parameter Problem: Bad IP 0

Chuyển Datagram cho mạng
Chuyển Datagram cho host
Chuyển Datagram cho TOS và mạng
Chuyển Datagram cho TOS và host
Thay thế địa chỉ host
Dành riêng
Lặp lại yêu cầu
Router quảng bá
Router khám phá/ lựa chọn
TTL hết trong quá trình truyền
Xác nhận phân mảnh hết hạn
Con trỏ chỉ ra lỗi

header
13- Timestamp
14- Timestamp Reply
15- Information Request
16- Information Reply
17- Address Mask Request
18- Address Mask Request
19
20 29
30 – Traceroute
31
32
33
34
35
36
37
38
39

1
2
0
0
0
0
0
0

0

Thiếu lựa chọn cần thiết
Tình trạng chiều dài
Dấu thời gian
Trả lời dấu thời gian
Yêu cầu thông tin
Phản hồi thông tin
Yêu cầu địa chỉ Mask
Trả lời địa chỉ Mask
Dành riêng cho bảo mật
Dành riêng cho thử nghiệm độ bền
Yêu cầu thông tin
Chuyển đổi Datagram bị lỗi
Chuyển host di động
Where – Are – You (bạn đầu cho IPv6)
Here – I – Am (ban đầu cho IPv6)
Yêu cầu sự đăng ký di động
Trả lời sự đăng ký di động
Yêu cầu tên miền
Trả lời tên miền
Thuật toán SKIP Discovery Protocol,

40
41

Simple Key – Quản lý giao thức Internet
Photuris, bảo mật fail
Các giao thức ICMP cho thử nghiệm trên di

42  255

động như Seamoby [RFC4065]
Dành riêng

xv

CHƯƠNG 2. LẬP TRÌNH MẠNG VỚI SOCKET

2.1.

GIỚI THIỆU VỀ LẬP TRÌNH VỚI SOCKET
Application Program
Stream
Socket
Interface

Datagram
Socket
Interface

TCP

Raw Socket
Interface

UDP
IP

Physical & Data Link Layer

Hình 2.1. Giới thiệu về lập trình với socket
Sockets cung cấp một interface để lập trình mạng tại tầng Transport. Một socket là
một end-point của một liên kết giữa hai ứng dụng. Ngày nay, Socket được hỗ trợ trong hầu
hết các hệ điều hành như MS Windows (WinSock), Linux và được sử dụng trong nhiều
ngôn ngữ lập trình khác nhau: như C, C++, Java, Visual Basic, C#, . . .
Windows Socket Application Programming Interface (Winsock API) là một thư viện
các hàm socket. Winsock hỗ trợ các lập trình viên xây dựng các ứng dụng mạng trên nền
TCP/IP.
Là giao diện lập trình ứng dụng (API), giao diện giữa chương trình ứng dụng với lớp
mạng trong hệ thống mạng TCP/IP.Thông qua giao diện này chúng ta có thể lập trình điều
khiển việc truyền thông giữa hai máy sử dụng các giao thức mức thấp làTCP,UDP…
Thiết lập các lập kênh giao tiếp với mỗi đầu kênh được đánh dấu bằng một cổng. Dữ
liệu có thể đi vào và ra khỏi kênh giao tiếp thông qua cổng này.
Cơ chế giao tiếp:
o

Một trong hai quá trình phải công bố số hiệu cổng của socket mà mình sử

dụng để nhận và gởi dữ liệu.
xvi

o

Các quá trình khác có thể giao tiếp với quá trình đã công bố cổng cũng bằng

cách tạo ra một socket.
Các loại socket:

1.8.

o

Socket hướng kết nối (TCP Socket)

o

Socket không hướng kết nối (UDP Socket)

o

Raw Socket

SỬ DỤNG RAW SOCKET
Gói tin ICMP không sử dụng TCP hoặc UDP nên chúng ta không thể sử dụng các lớp

được hỗ trợ như TCPClient hay UDPClient mà phải sử dụng một Raw Socket.
Muốn tạo Raw Socket khi tạo Socket ta phải sử dụng SocketType.Raw, giao thức
ICMP.
Cách tạo Raw Socket như sau:
Socket newsock= new Socket(AddressFamily.InterNetwork, SocketType.Raw,
ProtocolType.Icmp);
Raw Socket Format

o
Value
GGP
ICMP
IDP
IGMP
IP
IPX
ND
PUP
Raw
SPX
SPXLL
Unknown
Unspecified

Description
Gateway – to – Gateway Protocol
Internet Control Message Protocol
IDP Protocol
Internet Group Management Protocol
A raw IP packet
Novell IPX Protocol
Net Disk Protocol
Xerox PARC Universal Protocol (PUP)
A raw IP Packet
Novell SPX Protocol
Novell SPXv2 Protocol
An unknown protocol
An unspecified protocol

Gửi gói dữ liệu Raw:
o

Là giao thức không hướng kết nối, không cần bind socket đến cổng cục bổ để

gửi gói tin hoặc dùng phương thức Conncect() để kết nối nó với host cụ thể ở xa.
xvii

o

Sử dụng phương thức SendTo() của lớp Socket để gửi.

o

Công trong giao thức ICMP không quan trọng.

o

Chú ý: Vì raw socket không format dữ liệu nên mảng byte sẽ truyền nguyên

định dạng đến host ở xa. Do đó ta phải tạo thủ công gói ICMP thành mảng byte rồi mới
gởi. Nếu có lỗi bạn sẽ không có gói ICMP trả về.
Socket newsock= new Socket(AddressFamily.InterNetwork,
SocketType.Raw, ProtocolType.Icmp);
IPEndPoint iep = new IPEndPoint
(IPAdress.Parse(“192.168.1.2”),0);
Sock.SendTo(packet, iep);
Nhận gói dữ liệu Raw
o

Dữ liệu nhận được từ raw socket phức tạp hơn, ta phải dùng phương thức

ReceiveFrom().
o

Raw socket không xác định giao thức tầng trên, dữ liệu trả về phương thức

ReceiveFrom() chứa toàn bộ nội dung gói IP.
o

Chú ý: Vì phương thức ReceiveFrom() cho toàn bộ gói tin IP, ta phải khai

báo kích thước buffer nhận nhiều hơn dữ liệu chứa bên trong ít nhất là 20 bytes.
Tạo lớp ICMP Class
o

Tạo lớp ICMP class để dễ dùng trong các ứng dụng mạng có các gói ICMP.

o

Lớp ICMP thường cần có các biến dữ liệu trong bản sau:
Variable
Type
Code
Checksum
Message

o

Size
1 byte
1 byte
2 bytes
Multibyte

Type
Byte
Byte
Unsigned 16-bit integer
Byte array

Không gán giá trị cho các biến dữ liệu. Ta sẽ gán giá trị cho chúng khi thực

sự khởi tạo gói ICMP.
class ICMP
{
xviii

public byte Type;
public byte Code;
public UInt16 Checksum;
public int MessageSize;
public byte[] Message = new byte[1024];
public ICMP()
{
}
}
Để tạo gói ICMP mới, ta khai báo và gán giá trị:

o

ICMP packet = new ICMP();
packet.Type = 0x08;
packet.Code = 0x00;
packet.Checksum = 0;
o

Đoạn code trên tạo phần đầu của gói ICMP Echo Request.

o

Gói Echo Request định nghĩa các trường trong thành phần thông điệp ICMP

(Idnetifier và Sequence), bạn phải quyết định xây dựng thành phần này như thế nào. Bằng 2
cách:

Tạo lớp khác cho trường Echo Request và lấy mảng byte của

lớp.

Chuyển các trường thông điệp riêng thành mảng byte và đặt

chúng vào thành phần dữ liệu.
o

Nếu bạn định tạo nhiều gói Echo Request, nên tạo lớp Ping định nghĩa các

trường Echo Request riêng biệt.
o

Ngược lại ta làm theo cách sau:
Buffer.BlockCopy(BitConverter.GetBytes((short)1),0, packet.Message, 0, 2);
Buffer.BlockCopy(BitConverter.GetBytes((short)1),0, packet.Message, 2, 2);
byte[] data = Encoding.ASCII.GetBytes("test packet");
Buffer.BlockCopy(data, 0, packet.Message, 4, data.Length);
xix

packet.MessageSize = data.Length + 4;
o

Các trường Identifier và Sequence cho gói Echo Reply lần lượt chuyển thành

mảng byte và đặt đúng vị trí trong thành phần thông điệp.
Xây dựng lại đối tượng ICMP Object
o

Sau khi gởi gói ICMP, thường ta sẽ nhận lại gói ICMP của thiết bị từ xa trả

về. Để lây nội dung của gói đó, bạn nên tạo lớp ICMP khởi dựng khác để lấy mảng byte
ICMP và đặt giá trị vào thành phần dữ liệu phù hợp trong lớp:
public ICMP(byte[] data, int size)
{
Type = data[20];
Code = data[21];
Checksum = BitConverter.ToUInt16(data, 22);
MessageSize = size - 24;
Buffer.BlockCopy(data, 24, Message, 0, MessageSize);
}
o

Lưu ý raw socket trả về toàn bộ gói IP. Như vậy ta phải bỏ qua thông tin IP

header trước khi trích thông tin gói ICMP.
o

Thành phần Type ở vì trí 20 trong mảng byte. Các thành phần dữ liệu riêng

biệt trong gói ICMP được trích theo từng byte vào thành phần ICMP phù hợp.
o

Sau khi tạo đối tượng ICMP mới với dữ liệu gói nhận được, ta có thể xem

được thành phần dữ liệu riêng biệt:
int recv = ReceiveFrom(data, ref ep);
ICMP response = new ICMP(data, recv);
Console.WriteLine("Received ICMP packet:");
Console.WriteLine(" Type {0}", response.Type);
Console.WriteLine(" Code: {0}", response.Code);
Int16 Identifier = BitConverter.ToInt16(response.Message, 0);
Int16 Sequence = BitConverter.ToInt16(response.Message, 2);
Console.WriteLine(" Identifier: {0}", Identifier);
xx

Console.WriteLine(" Sequence: {0}", Sequence);
stringData

=

Encoding.ASCII.GetString(response.Message,

4,

response.MessageSize - 4);
Console.WriteLine(" data: {0}", stringData);
o

Vì 2 bytes đầu tạo trường số nguyên không dấu Identifier vaf 2 bytes thứ hai

là trường số nguyên không dấu Sequence, bạn có thể dùng lớp BitConverter để gán các giá
trị đó.
o

Phần còn lại của thành phần thông điệp được gán cho trường Message của

gói Echo Reply packet.
o

Từ đoạn code này, ta dễ thấy vì sao thành MessageSize được thêm vào lớp

ICMP. Nếu không có nó, sẽ khó xây dựng lại thành phần Message từ gói nhận được.
The ICMP Packet Creator
o

Sau khi đối tượng ICMP mới được tạo ra và các thành phần dữ liệu gói được

xác định, bạn muốn gởi gói đến thiết bị ở xa. Bạn không thể gởi đối tượng ICMP bằng
phương thức SendTo(); cần chuyển nó thành mảng byte.
o

Các dễ nhất để gởi đối tượng phức tạp qua mạng là tạo phương thức chuyển

mỗi thành phần dữ liệu thành mảng byte và nối các mảng byte lớn hơn dùng phương thức
Buffer.BlockCopy():
public byte[] getBytes()
{
byte[] data = new byte[MessageSize + 9];
Buffer.BlockCopy(BitConverter.GetBytes(Type), 0, data, 0, 1);
Buffer.BlockCopy(BitConverter.GetBytes(Code), 0, data, 1, 1);
Buffer.BlockCopy(BitConverter.GetBytes(Checksum), 0, data, 2, 2);
Buffer.BlockCopy(Message, 0, data, 4, MessageSize);
return data;
}
o

Khi tất cả các thành phần dữ liệu được chuyển thành mảng byte có đúng dạng

gói ICMP có thể nó đến thiết bị mạng ở xa:
xxi

IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.2"), 0);
sock.SendTo(packet.getBytes(), iep);
o

Chú ý: Giá trị Identifier và Sequence không được chuyển thành byte trước

khi đưa vào mảng vì thiết bị mạng ở xa sẽ trả về cho bạn gói y hệt.
o

Đây là phần khó nhất khi tạo ra gói ICMP packet. Cách làm là tạo phương

thức tự chứa tính checksum và đưa vào lớp ICMP phụ vụ cho ứng dụng ICMP.
o

Cho vài ví dụ tính checksum, sau đây là ví dụ:
public UInt16 getChecksum()
{
UInt32 chcksm = 0;
byte[] data = getBytes();
int packetsize = MessageSize + 8;
int index = 0;
while ( index < packetsize)
{
chcksm += Convert.ToUInt32(BitConverter.ToUInt16(data, index));
index += 2;
}
chcksm = (chcksm >> 16) + (chcksm & 0xffff);
chcksm += (chcksm >> 16);
return (UInt16)(~chcksm);

o

Đầu tiên gán đầy giá trị tất cả thành phần dữ liệu, đặt thành phần Checksum

thành zero. Sau đó, gọi phương thức getChecksum() để tình checksum của gói ICMP, đặt
kết quả vào thành phần Cheksum của gói:
packet.Checksum = 0;
packet.Checksum = packet.getChecksum();
o

Sau khi tính xong Cheksum gởi gói đi sử udnjg phương thức SendTo().

o

Chú ý: Khi nhận gói ICMP phải lấy giá trị Checksum và so sánh với giá trị đã

tính cho gói. Nếu 2 giá trị không so khớp, đã có lỗi và cần truyền lại gói.
xxii

xxiii

CHƯƠNG 3. THIẾT KẾ VÀ XÂY DỰNG CHƯƠNG TRÌNH

1.9.

PHÂN TÍCH YÊU CẦU
Ứng dụng phải đảm bảo thực hiện được các yêu cầu sau:
o

Gửi gói tin ICMP đến tất cả các máy đến dải địa chỉ trong mạng LAN.

o

Bắt gói tin IP được gửi về và tách ra gói tin ICMP từ gói tin IP để xử lý.

o

Có thể quét theo các lớp địa chỉ Private

1.10. PHÂN TÍCH CÁC CHỨC NĂNG
1.10.1.Phương thức hoạt động của ứng dụng
Ứng dụng hoạt động bằng cách sẽ lần lượt gửi từng gói tin ICMP tới tất cả các máy
trong mạng LAN cần quét. Dãy địa chỉ Ip để gửi các gói tin ICMP sẽ do người dùng nhập
vào hay sẽ chọn lựa việc gửi theo lớp (lớp A, lớp B, lớp C ..). Trong khi gửi gói tin thì ứng
dụng sẽ bắt tói tin phản hồi từ một địa chỉ IP nào đó để tiến hành xử lý. Và dựa vào thông
tin phản hồi đó mà biết được địa chỉ IP đó có tồn tại trong mạng hay không.
Để gửi được gói tin tới tất cả các địa chỉ thì ta dùng 4 vòng lặp for lồng nhau tương
ứng với 4 octet của địa chỉ IPv4.
for (byte i=ipf1;i<=ipt1;i++)
for (byte j=ipf2;j<=ipt2;j++)
for(byte t=ipf3;t<=ipt3;t++)
for (byte z = ipf4; z <= ipt4; z++)
Sau khi phân tích và xác định được địa chỉ IP nào tồn tại trong mạng thì ta sẽ tiến
hành hiển thị ra cho người dùng. Thông tin hiển thị bao gồm số thứ tự của máy trong mạng,
tên máy và địa chỉ IP của máy đó.
1.10.2.Xây dựng chức năng
Từ việc phân tích hoạt động của ứng dụng như trên ta tiến hành xây dựng chức năng
cho ứng dụng. Ứng dụng sẽ bao gồm các chức năng cơ bản:
o

Chức năng gửi gói tin ICMP

o

Chức năng nhận và xử lý gói tin
xxiv

Chức năng quét địa chỉ IP dựa trên 2 chức năng cơ bản trên.

o
1.11.

XÂY DỰNG CHỨC NĂNG

1.11.1.Xây dựng chức năng gửi gói tin
Để gửi một gói tin trong Visual C# thì phải sử dụng một Raw Socket. Muốn tạo Raw
Socket khi tạo ra Socket ta sử dụng SocketType, giao thức ICMP.
Tạo ra Raw Socket như sau:
Socket sock = new Socket(AddressFamily.InterNetwork,
SocketType.Raw, ProtocolType.Icmp);
Gửi gói dữ liệu Raw:
ICMP là giao thức không hướng kết nối.
Sử dụng phương thức SendTo() của lớp Socket để gửi.
Cổng trong giao thức ICMP không quan trọng
IPEndPoint iep = new(IPEndPoint (IPAddress.Parse
(“192.168.1.100”), 0);
Sock.SendTo(packet, iep);
1.11.2.Xây dựng chức năng nhận gói tin và xử lý
Để nhận gói tin từ các máy khác gửi về ta dùng phương thức ReceiveFrom của lớp
Soket. Dữ liệu nhận về là một gói tin IP, vì vậy ta phải tách ra để lấy gói tin ICMP. Raw
Socket không tự động định dạng ICMP cho chúng ta.
Ta định nghĩa lớp ICMP như sau:
Class ICMP
{
public byte Type;
public byte Code;
public Ulnt16 Checksum;
public int Messagesize;
public byte[] Message = new byte[1024];
public ICMP()
{
xxv

}
}
Tạo ra một gói tin ICMP với Type =8, Code = 0 để tiến hành gửi.
ICMP packet = new ICMP();
Packet.Type = 0x08;
Packet.Code = 0x00;
Packet.Checksum = 0;
Để lấy lại gói tin ICMP từ gói IP nhận được ta có phương thức:
Public ICMP(byte[] data, int size)
{
Type = data[20];
Code = data[21];
Checksum = Bitconverter.toUInt16(data, 22);
Messagesize = size – 24;
Buffer.Blockcopy(data, 24, Message, 0, Messagesize);
}
Vì gói tin ICMP bắt đầu từ byte thứ 20 trong gói tin IP nên ta sẽ lấy dữ liệu bắt đầu từ
vị trí byte thứ 20.
Byte thứ 20 chứa thông tin về Type
Byte thứ 21 chứa thông tin về Code
Byte thứ 22 và 23 chứa thông tin về Cheksum
Dữ liệu bắt đầu từ byte thứ 24
Sau khi nhận gói tin ta tiến hành phân tích gói tin ICMP theo các thông điệp điều
khiển:
Type
Code
Indentifier
Sequence
Tùy theo các thông điệp đó mà ta biết được gói tin có được phản hồi lại hay không.
xxvi

1.11.3.Xây dựng chức năng quét địa chỉ IP
Chức năng quét địa chỉ IP là mở rộng của việc gửi, nhận và phân tích gói tin nhận
được từ nhiều máy trong mạng LAN. Ở đây ta sẽ quét một dãy các địa chỉ IP. Để thực hiện
công việc này ta tiến hành một vòng lặp trên 4 octet của địa chỉ IP để lần lượt gửi các gói
tin ICMP đến từng máy và tiến hành phân tích nhận được tương ứng của mỗi máy.
Nếu có sự phản hồi của máy nào thì ta biết máy đó đang tồn tại trong mạng và hiển
thị cho người sử dụng biết.
1.12. GIAO DIỆN VÀ SỬ DỤNG CHƯƠNG TRÌNH
1.12.1.Giao diện
Giao diện chính của chương trình

Hình 3.1. Giao diện chính của chương trình scanip
Chức năng quét địa chỉ của chương trình

xxvii

Hình 3.2. Chức năng quét tất cả các địa chỉ ip

Hình 3.3. Chức năng quét theo lớp
Code chương trình
Lớp ICMP.cs: Xử lý gói tin ICMP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ScanIP
{
xxviii

class ICMP
{
// Định dạng cho việc xây dựng lớp ICMP mặc định
public byte Type;
public byte Code;
public UInt16 Checksum;
public int Messagesize;
public byte[] Message = new byte[1024];
public ICMP()
{
}
// Xây dựng lại đối tượng ICMP để nhận gói tin ICMP từ các thiết bị ở xa
public ICMP(byte[] data, int size)
{
Type = data[20];
Code = data[21];
Checksum = BitConverter.ToUInt16(data, 22);
Messagesize = size - 24;
Buffer.BlockCopy(data, 24, Message, 0, Messagesize);
}
// Tạo gói ICMP để gửi tới các thiết bị ở xa
public byte[] getByte()
{
byte[] data = new byte[Messagesize + 9];
Buffer.BlockCopy(BitConverter.GetBytes(Type),0,data,0,1);
Buffer.BlockCopy(BitConverter.GetBytes(Code),0,data,1,1);
Buffer.BlockCopy(BitConverter.GetBytes(Checksum),0,data,2,2);
Buffer.BlockCopy(Message,0,data,4,Messagesize);
return data;
xxix

}
// Tạo phương thức Checksum
public UInt16 getChecksum()
{
UInt32 chcksm = 0;
byte[] data = getByte();
int packetsize = Messagesize + 8;
int index = 0;
while (index < packetsize)
{
Chcksm +=Convert.ToUInt32(BitConverter.ToUInt16(data,index));
index +=2;
}
chcksm = (chcksm >> 16) + (chcksm & 0xffff);
chcksm += (chcksm >> 16);
return (UInt16)(~chcksm);
}
}
}
Lớp Kiemtra.cs: Kiểm tra thông tin trả về của gói tin ICMP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

xxx

namespace ScanIP
{
class Kiemtra
{
public static bool Check(string st)
{
byte[] data = new byte[1024];
int recv;
Socket host = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
ProtocolType.Icmp);
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(st), 0);
EndPoint ep = (EndPoint)ipe;
// Tạo gói ICMP Request
ICMP packet = new ICMP();
packet.Type = 0x08;
packet.Code = 0x00;
packet.Checksum = 0;
// Gửi nhiều gói ICMP
Buffer.BlockCopy(BitConverter.GetBytes((short)1), 0, packet.Message, 0, 2);
Buffer.BlockCopy(BitConverter.GetBytes((short)1), 0, packet.Message, 2, 2);
data = Encoding.ASCII.GetBytes("test packet");
Buffer.BlockCopy(data, 0, packet.Message, 4, data.Length);
packet.Messagesize = data.Length + 4;
int packetsize = packet.Messagesize + 4;
// Gọi tới phương thức getChecksum và khởi tạo giá trị trường Checksum của gói
tin
UInt16 chcksum = packet.getChecksum();
packet.Checksum = chcksum;

xxxi

host.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout, 100);
host.SendTo(packet.getByte(), packetsize, SocketFlags.None, ipe);
try
{
data = new byte[1024];
recv = host.ReceiveFrom(data, ref ep);
ICMP response = new ICMP(data, recv);
// Lấy các giá trị cần thiết của gói ICMP từ trong gói tin IP
int Indentifier = BitConverter.ToInt16(response.Message, 0);
int Sequence = BitConverter.ToUInt16(response.Message, 2);
System.Console.WriteLine("response from: {0}", ep.ToString());
System.Console.WriteLine("Type {0}", response.Type);
System.Console.WriteLine("Code: {0}", response.Code);
System.Console.WriteLine("Indentifier: {0}", Indentifier);
System.Console.WriteLine("Sequence: {0}", Sequence);
string stringData = Encoding.ASCII.GetString(response.Message, 4,
response.Messagesize - 4);
System.Console.WriteLine("data: {0}", stringData);
host.Close();
if (response.Type == 0 && response.Code == 0 && Indentifier == 1 &&
Sequence == 1)
return true;
else return false;
}
catch (SocketException)
{
System.Console.WriteLine("No response from remote host");
host.Close();
xxxii

return false;
}
}
}
}
Form1.cs: Xử lý sự kiện trên Winform
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Threading;
namespace ScanIP
{
public partial class FrMain : Form
{
int stt;
byte ipf1, ipf2, ipf3, ipf4, ipt1, ipt2, ipt3, ipt4;
public FrMain()
{
InitializeComponent();
stt = 1;
}

xxxiii

delegate void DlgThreadCode();
public void ThreadCode()
{
if (this.prgressBar.InvokeRequired)
{
this.Invoke(new DlgThreadCode(ThreadCode));
}
else
{
for (byte i=ipf1;i<=ipt1;i++)
for (byte j=ipf2;j<=ipt2;j++)
for(byte t=ipf3;t<=ipt3;t++)
for (byte z = ipf4; z <= ipt4; z++)
{
int max = ((ipt1 - ipf1) + (ipt2 - ipf1) + (ipt3 - ipf3) + (ipt4 - ipf4));
prgressBar.Minimum = 0;
prgressBar.Maximum = max;
prgressBar.Step = 1;
prgressBar.PerformStep();
string strip=i.ToString()+"."+j.ToString() + "." + t.ToString() + "." +
z.ToString();
if (Kiemtra.Check(strip))
{
IPHostEntry ipHost = Dns.Resolve(strip);
string hostName = ipHost.HostName;
Add(stt.ToString().Trim(), hostName, strip);
lvKetQua.Refresh();
stt++;
}
xxxiv

}
prgressBar.Value = 0;
lbStatus.Text = "ĐÃ QUÉT XONG";
}
}
private void btnQuet_Click(object sender, EventArgs e)
{
for(int i = 0; i<lvKetQua.Items.Count;i++)
{
lvKetQua.Items[i].Remove();
i--;
}
lbStatus.Text="ĐANG QUÉT ...";
lbStatus.Refresh();
stt =1;
if(rdbAll.Checked==true)
{
ipf1 = Convert.ToByte(tbF1.Text.Trim());
ipf2 = Convert.ToByte(tbF2.Text.Trim());
ipf3 = Convert.ToByte(tbF3.Text.Trim());
ipf4 = Convert.ToByte(tbF4.Text.Trim());
ipt1 = Convert.ToByte(tbT1.Text.Trim());
ipt2 = Convert.ToByte(tbT2.Text.Trim());
ipt3 = Convert.ToByte(tbT3.Text.Trim());
ipt4 = Convert.ToByte(tbT4.Text.Trim());
}
if(rdbLop.Checked == true)
{
xxxv

if(cbbLop.SelectedIndex == 0)
{
ipf1 = 10;
ipf2 = 0;
ipf3 = 0;
ipf4 = 0;
ipt1 = 10;
ipt2 = 255;
ipt3 = 255;
ipt4 = 255;
}
else if(cbbLop.SelectedIndex ==1)
{
ipf1 = 172;
ipf2 = 16;
ipf3 = 0;
ipf4 = 0;
ipt1 = 172;
ipt2 = 31;
ipt3 = 255;
ipt4 = 255;
}
else
{
ipf1 = 192;
ipf2 = 168;
ipf3 = 1;
ipf4 = 0;
ipt1 = 192;
xxxvi

ipt2 = 168;
ipt3 = 1;
ipt4 = 255;
}
}
Thread thread = new Thread(new ThreadStart(ThreadCode));
thread.Start();
}
private void rbtQuetALL_CheckedChanged(object sender, EventArgs e)
{
if (rdbAll.Checked == true)
{
cbbLop.Enabled = false;
tbF1.Enabled = true;
tbF2.Enabled = true;
tbF3.Enabled = true;
tbF4.Enabled = true;
tbT1.Enabled = true;
tbT2.Enabled = true;
tbT3.Enabled = true;
tbT4.Enabled = true;
}
}
private void rbtQuetlop_CheckedChanged(object sender, EventArgs e)
{
if (rdbLop.Checked == true)
{
xxxvii

tbF1.Enabled = false;
tbF2.Enabled = false;
tbF3.Enabled = false;
tbF4.Enabled = false;
tbT1.Enabled = false;
tbT2.Enabled = false;
tbT3.Enabled = false;
tbT4.Enabled = false;
cbbLop.Enabled = true;
}
}
private void FrMain_Load(object sender, EventArgs e)
{
string strhostname = Dns.GetHostName();
IPHostEntry iphost = Dns.Resolve(strhostname);
lbDiachi.Text = iphost.AddressList[0].ToString();
lbHostName.Text = strhostname;
tbF1.Enabled = false;
tbF2.Enabled = false;
tbF3.Enabled = false;
tbF4.Enabled = false;
tbT1.Enabled = false;
tbT2.Enabled = false;
tbT3.Enabled = false;
tbT4.Enabled = false;
cbbLop.Enabled = false;
}
private void Add(String st1, String st2, String st3)
xxxviii

{
ListViewItem item = new ListViewItem(st1);
item.SubItems.Add(st2);
item.SubItems.Add(st3);
lvKetQua.Items.Add(item);
}
private void btnThoat_Click(object sender, EventArgs e)
{
Close();
}
private void btnDung_Click(object sender, EventArgs e)
{
}
}
}
1.12.2.Sử dụng chương trình
o

Địa chỉ IP của bạn: Chương trình sẽ lấy địa chỉ ip của Card mạng và gán

cho phần Địa chỉ IP của bạn.
o

Tên máy của bạn: Chương trình sẽ lấy hostname của máy tính đang chạy

chương trình.
o

Quét tất cả các địa chỉ: Tại đây người sử dụng có thể gán một dải địa chỉ

ip muốn chương trình quét.
o

Quét theo lớp: Tại đây người sử dụng có thể lựa chọn quét ip theo lớp

A,B,C,…
o

Sau khi đã lựa chọn việc quét theo dải địa chỉ ip hoặc quét theo lớp thì

kích vào điều khiển Quét để chạy chương trình.
xxxix

o

Tiếp đó chương trình sẽ thực hiện quét và thông tin quét được sẽ hiển thị

bên listbox.
o

Trong quá trình quét có thể sử dụng điều khiển Dừng để tạm dừng

chương trình.

xl

KẾT LUẬN
Sau khi thực hiện xong đồ án đã giúp nhóm em củng cố lại kiến thức vừa học. Dưới sự
hướng dẫn nhiệt tình và những kiến thức vô cùng quý báu của Thầy Nguyễn Vũ đã giúp đỡ
nhóm em hoàn thiện “Chương trình Scan IP”.
Tuy nhiên do thời gian nghiên cứu ít, tham khảo ở nhiều nguồn tài liệu khác nhau cũng
như kiến thức về lập trình mạng còn hạn hẹp do đó chương trình của nhóm còn nhiều hạn
chế như tốc độ xử lý còn khá chậm, chưa bẫy được hết lỗi trên chương trình và đôi lúc còn
gặp một số trục trặc ngoài ý muốn. Mong Thầy Cô và các bạn có những nhận xét cũng như
góp ý chân thành nhất để chương trình của nhóm có thể được hoàn chỉnh và ứng dụng trong
thực tiễn hơn.

xli

Sử dụng kỹ thuật lập trình Socket xây dựng chương trình Scan IP

DANH MỤC TÀI LIỆU THAM KHẢO
Tiếng việt
[1]

Giáo trình lập trình mạng

[2]

Ebook Bài giảng lập trình mạng với C#

Nguồn từ Internet
[3]

http://www.wikipedia.org

[4]

http://www.tailieu.vn

[5]

http://ebook.edu.vn

Nhóm 7 – Lớp CCMM03C

Trang 42

Sử dụng kỹ thuật lập trình Socket xây dựng chương trình Scan IP

NHÂN XÉT CỦA GIẢNG VIÊN HƯỚNG DẪN
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................
.............................................................................................................................................

Nhóm 7 – Lớp CCMM03C

Trang 43

Sign up to vote on this title
UsefulNot useful