1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu học tập Kỹ thuật mô phỏng: Phần 2

102 7 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 102
Dung lượng 2,15 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

(NB) Tài liệu học tập Kỹ thuật mô phỏng: Phần 2 cung cấp cho sinh viên những kiến thức về: Liên kết giữa các nút mạng bằng đối tượng simpleLink, đối tượng mô phỏng gói tin Packet, Các toán tử dùng để tạo gói tin được biểu diễn bằng đối tượng Agent, đối tượng Application dùng để mô phỏng các yêu cầu truyền dữ liệu của người sử dụng. Mời các bạn cùng tham khảo.

Trang 1

7.1 Giới thiệu về đối tượng SimpleLink

NS2 mô hình hóa một kênh truyền bằng các sử dụng các Lớp được dẫn xuất từ Lớp Link của OTcl Trong số các Lớp này, Lớp SimpleLink là lớp đơn giản nhất có thể được sử dụng để kết nối giữa hai nút

head_: Điểm truy cập của đối tượng SỉmpleLink

queue_: Là một đối tượng Queue, nó thực hiện mô hình hóa bộ đệm gói tin của một router thực (xem Mục 7.3)

link_: Là đối tượng DelayLỉnk, thực hiện mô hình hóa thời gian truvền gói tin

và thời gian trễ của kênh truyền (xem Mục 7.2)

ttl_: Là một đối tượng kiểm tra thời gian sống (time to live) của lớp

TTLChecker Khi một gói tin tới, đối tượng này thực hiện việc giảm giá trị TTL của

gói tin Sau đó nó kiểm tra nếu giá trị TTL của gói tin vẫn là giá trị dương, gói tin sẽ

Trang 2

Các đối tượng lưu vết

Các đối tượng này sẽ được chèn vào chỉ khi biến thành viên $traceAHFile_ được

định nghĩa Các đối tượng này bao gồm:

enqT_: Lưu vết các gói tin đi vào hàng đợi queue_ deqT_: Lưu vết các gói tin đi ra

từ hàng đợi queue_ drpT_: Lưu vết các gói tin bị hủy từ hàng đợi queue_

rcvT_: Lưu vết các gói tin đi ra khỏi kênh truyền hoặc được các nút tiếp theo nhận

7.1.1 Các thủ tục instproc để cấu hình đối tượng SimpleLink

Trong miền OTcl, một đối tượng SỉmpleLỉnk được tạo ra bằng cách sử dụng thủ tục instproc simplex-lỉnkL"} và duplex-lỉnkr -} của lớp Simulator với cú pháp như sau:

Trong đó $ns là đối tượng Simulator và $nl, $n2 là các đối tượng Node Thủ tục instproc

simplex-Tink{”-} ở trên tạo một đối tượng SimpleLink kết nối 1 chiều giữa nút $nl với

nút $n2 (Chưong trình 7.1) Tốc độ và thời gian trễ của kênh truyền được đưa vào tham

số <bandwỉdth> (tính theo đon vị bps) và <delay> (tính theo đon vị giây) Khác với router thực, NS2 tích hợp hàng đợi trong đối tượng SimpleLỉnk chứ không phải trong đối tượng Node Kiểu của hàng đợi trong kênh truyền được chỉ định bởi tham số

<queue_type>

Trang 3

- 133 -

Chương trình 7.1 đưa ra chi tiết của thủ tục Simulator-simplex- link{"} Dòng 6 tạo một đối tượng của lớp Queue/qtype Dòng 12 khởi tạo một đối tượng SimpleLink kết nối giữa nút n1 và n2 Nó thiết lập độ trễ, băng thông và đối tượng Queue của kênh truyền tương ứng là bw, delay và q Đối tượng Simulator lưu đối tượng SimpleLink được tạo ra vào mảng liên kết link_($sid:$did) của nó với sid là ID định danh của nút nguồn và did là ID định danh của nút đích (xem Chương 4)

Thủ tục duplex-link "-} tạo ra hai đối tượng SimpleLink Một đối tượng kết nối

từ nút $n1 tới nút $n2 và một đối tượng kết nối từ nút $n2 tới nút $n1 Bạn đọc có thể xem chi tiết của thủ tục này trong file ~ns/tcl/lib/ns-lib.tcl

7.1.2 Khỏi tạo của Lớp SimpleLink

Chương trình 7.2 đưa ra chi tiết của thủ tục init{ —} của lớp SỉmpleLỉnk để khởi tạo và kết nối các đối tượng theo Hình 7.1 Trong chương trình này các dòng 3, 5, 11, 12

và 18 tạo ra các biến thành viên drophead_, head_ queue_ link_ và ttl_ là các đối tượng của các lớp OTcl tương ứng là Connector Connector, Queue, DelayLink và TtlChecker Chú ý rằng băng thông và độ trễ của biến link_ được cấu hình trong dòng 13-14

Ngoài việc tạo ra các đối tượng trên, thủ tục khởi tạo này còn kết nối các đối

tượng được tạo ra như Hình 7.1 Được dẫn xuất từ lớp Connector, mỗi một đối tượng

Trang 4

- 134 -

được tạo ra sử dụng lệnh target và drop-target để thiết lập đối tượng nhận gói và đối

tượng hủy gói (xem Chương 5) Dòng 9 thiết lập đối tượng nhận của head_ là q Dòng 15

thiết lập đối tượng nhận của queue_ là link_ Dòng 16 thiết lập đối tượng nhận của link_

là điểm truy cập của nút kế tiếp Dòng 19 và 21 chèn biến ttl_ vào giữa lỉnk_ và điểm truy cập của nút kế tiếp Dòng 17 thiết lập điểm hủy gói tin của queue_ là dropheacL Cuối cùng, dòng 4 thiết lập đích của drophead_ là tác tử rỗng của đối tượng Simulator

7.2 Mô hình truyền gói tin

 Cơ chế truyền gói tín

NS2 mô hình hóa cơ chế truyền gói tin bằng cách sử dụng lớp C++ LinkDelay (xem Chương trinh 7.3) Lớp C++ này được liên kết với lớp DelayLink của OTcl Lớp DelayLink được sử dụng để khởi tạo biến thành viên SimpleLink::Link_ Đây là biến

dùng để mô hình hóa tiến trinh truyền gói tin

Một tiến trình truyền gói tin bao gồm thời gian truyền gói tin và thời gian trễ của kênh truyền Khi một đối tượng LinkDelay nhận một gói tin, nó đưa vào dòng thời gian

mô phỏng hai sự kiện:

Trang 5

- 135 -

 Sự kiện truyền gói tin đi từ đối tượng truyền: Thời gian truyền gói tin

được định nghĩa bằng (kích thước gói tin / băng thông) Đây là thời gian cần thiết để

truyền một gói tin qua một kênh truyền Sau một chu kỳ của thời gian truyền gói tin, gói

tin hoàn toàn đi ra khỏi thiết bị truyền và thiết bị truyền được phép tiếp tục truyền gói tin

tiếp theo Nhờ vào sự kiện nhận gói tin một đối tượng LinkDelay sẽ đợi một chu kỳ thời

gian truyền gói tin và báo cho đối tượng gửi biết rằng nó đã sẵn sàng để nhận một gói tin

tiếp theo

 Sự kiện nhận gói tin về tại đối tượng nhận: Thời gian trễ khi truyền

gói tin được định nghĩa bằng thời gian cần thiết để truyền một bit từ điểm bắt đầu tới

điểm kết thúc trên một kênh truyền Như vậy, toàn bộ gói tin cần một khoảng thời gian

bằng ―thời gian truyền + thời gian trễ‖ để đi tới đích Do đó, đối tượng LinkDelay sẽ lập

lịch cho sự kiện nhận gói tin tại nút nhận sau khoảng thời gian trên

 Lớp LinkDelay trong C++

Chương trình 7.3 đưa ra khai báo của Lớp C++ LinkDelay Lớp này có bốn biến

chính Biến bandwidth_ (dòng 15) lưu băng thông của kênh truyền Biến delay_ (dòng

16) lưu thời gian trễ khi truyền Dòng 4 và 5 liên kết hai biến này với các biến có cùng

tên trong OTcl Lớp LỉnkDelay lưu mọi gói tin sẽ được truyền trong bộ đệm itq_ của nó

(dòng 17) Biến itq_ là một con trỏ trỏ tới đối tượng PacketQueue (xem Mục 7.3.1)

Cuối cùng, biến ỉntr_là một đối tượng Event giả biểu diễn sự kiện gói tin rời khỏi nút

truyền Sự kiện này đươc lập lịch bằng cách sử dụng biến ỉntr_ mà không cần đến cơ chế

thực thi sự kiện (xem Mục 4.3.6)

Các hàm chính của Lớp LinkDelay là hàm recv(p,h), hàm send(p,h), hàm

handle(e) và hàm txttime(p) Hàm txttỉme(p) tính thời gian truyền của gói tin *p (dòng

10-12 trong Chương trình 7.3) Hàm send(p,h) gửi gói tin *p tới đối tượng nhận (dòng

12 trong Chương trinh 7.3) Hàm handle(e) được gọi khi bộ lập lịch thực thi sự kiện

tương ứng với đối tượng LinkDelay (xem Chương 4) Hàm recv(p.h) lập lịch cho các sự

kiện gói tin rời khỏi nút truyền và gói tin tới nút nhận từ hai đối số đầu vào là gói tin *p

và thẻ quản lý *h

Trang 6

- 136 -

Sự kiện gói tin rời khỏi nút truyền: Vì một gói tin cần ‗thời gian truyền‖ (biến txt

trong dòng 3) tại đối tượng truyền nên hàm recv(p,h) sẽ lập lịch cho sự kiện gói tin rời khỏi nút truyền tại thời điểm txt giây sau khi đối tượng LỉnkDelay nhận được gói tin Để thực hiện việc này, dòng 10 gọi hàm scheđule(h,Sántr,txt) của lớp Scỉieđuler với đối số thứ nhất là thẻ quản lý, đối số thứ hai là sự kiện giả và đối số thứ ba là thời gian trễ Sau khoảng thời gian txt giây, bộ lập lịch thực thi sự kiện này bằng cách gọi hàm handle(e) liên kết với thẻ quản lý *h để báo cho đối tượng gửi biết sự kiện một gói tin đã rời đi Trong hầu hết mọi trường hợp, đối tượng gửi đáp ứng lại bằng cách truyền một gói tin

tiếp theo nếu có (xem Mục 7.3.3 về cơ chế gọi ngược)

Sự kiện gói tin đến: Lớp LinkDelay cũng thực hiện việc truyền gói tin tới đối tượng nhận (*target) Dòng 8 thực hiện việc lập lịch cho một sự kiện lấy từ gói tin đầu vào *p với thời gian trễ txt+đelay_ giây Trong đó, txt là thời gian truyền và đelay_ là thời gian trễ trên kênh truyền Ở đây, *target_ được truyền từ hàm schedule( - ) dưới dạng một con trỏ Handler Sau khoảng thời gian “txt+delay_” giây, hàm h.handle(p) sẽ gọi hàm recv(p) (xem Chương trình 4.2) và gói tin *p sẽ được truyền tới đối tượng

*target_ sau khoảng thời gian txt+delay_ giây

Sự khác biệt chính giữa việc lập lịch cho sự kiện gói tin rời đi từ nguồn và gói tin đến đích là như sau: Trong khi một nút chỉ có thể giữ một gói tin thì một kênh truyền có thể chứa nhiều hơn một gói tin Vì thế, một đối tượng Link chỉ có thể lập lịch cho một sự kiện gói tin rời đi từ nguồn (sử dụng biến intr_) và nhiều hơn một sự kiện gói tin đến đích (sử dụng *p để biểu diễn một gói tin) Bất kỳ lúc nào đối tượng LinkDelay nhận được một gói tin, nó sẽ lập lịch cho sự kiện gói tin rời đi từ nguồn bằng cách sử dụng biến sự kiện giả ỉntr_ Nếu biến intr_ không thực thi được, bộ lập lịch sẽ gây ra lỗi trong thời gian chạy bởi vì nó cố đưa một gói tin vào đầu bộ đệm mà bộ đệm này lại đang bị chiếm giữ

bởi gói tin khác Ngược lại, đối với sự kiện gói tin đến đích, đối tượng LinkDelay lập

lịch cho sự kiện gói tin tới nút đích cho mọi gói tin nó nhận được (xem dòng 8 trong Chương trình 7.4) Do đó, một liên kết có thể lập lịch cho một sự kiện gói tin đến đích trong khi sự kiện gói tin tới đích trước đó vẫn chưa được thực thi Đây là trường hợp rất phổ biến đối với các kênh truyền có thời gian trễ lớn có thể chứa nhiều gói tin đồng thời

7.3 Quản lý vùng đệm

Một thành phần chính khác của đối tượng SimpleLink là lớp Queue Lớp Queue

mô hình hoá cơ chế bộ đệm trong router Nó lưu gói tin nhận được trong bộ đệm, chuyển tiếp lần lượt từng gói tin ở đầu bộ đệm tới đối tượng nhận

Trang 7

- 137 -

Như ta thấy trong Chưong trình 7.5, lớp Queue là lớp dẫn xuất từ Lớp Connector

và nó được sử dụng để kết nối giữa hai đối tượng NsObject Nó khai báo đối tượng *pq_ của Lớp PacketQueue (dòng 20) dừng làm bộ đệm gói tin Kích thước bộ đệm chứa trong biến qlim_ (dòng 16) Các biến blockecL (dòng 17), unblock_on_resume_ (dòng 18) và qh_ (dòng 19) có liên quan tới cơ chế gọi ngược được trinh bày trong Mục 7.3.3

Có một số hàm quan trọng sau trong Lớp Queue: Hàm enque(p) và deque() (dòng 3-4) thực hiện các công việc tương ứng là đưa gói tin vào và lấy gói tin ra từ đối tượng

*pq_ của Lớp PầcketQueue Các hàm này đều là các hàm ảo nguyên thuỷ và chúng cần được xây dựng lại trong các Lớp dẫn xuất từ Lớp Queue/Hàm recv(p,h) (dòng 5) thừa kế

từ Lớp NsObject là hàm thực hiện việc nhận gói tin Hàm blocked) (dòng 7) là hàm kiểm tra trạng thái kho á của đối tượng Queue Các hàm resume() (dòng 6), unblock() (dòng 8)

và block() (dòng 9) được sử dụng trong cơ chế gọi ngược sẽ được đề cập chi tiết trong Mục 7.3.3 Cuối cùng, hàm lỉmito và lengthO thực hiện các công việc tương ứng là lấy giá trị kích cỡ tối đa và kích cỡ hiện tại của bộ đệm

 Lớp PacketQueue

Được khai báo trong Chương trình 7.6, lớp PacketQueue mô hình hoá các hoạt

động cấp thấp của bộ đệm bao gồm lưu trữ, đưa gói vào hàng đợi và xuất gói ra khỏi hàng đợi

Trang 8

8 Biến tail_ (dòng 12): là một con trỏ trỏ vào phần tử cuối danh sách liên kết

9 Biến len_ (dòng 13); chứa số lượng gói tin trong bộ đệm

10 Hàm enque(p) (dòng 5): đưa gói tin *p vào cuối bộ đệm

11 Hàm deque() (dòng 6): trả về phần tử con trỏ đầu bộ đệm trong trường hợp

bộ đệm không rỗng Ngược lại nó sẽ trả về giá trị NULL

12 Hàm remove(p) (dòng 7): tìm kiếm gói tin *p và xoá nó khỏi bộ đệm nếu tìm thấy

 Lớp QueueHandler

Lớp QueueHandler là Lớp dẫn xuất từ Lớp Handler (dòng 1 trong Chương trình

7.7) Nó có mối quan hệ chặt chẽ với bộ lập lịch sự kiện Lớp này định nghĩa hành động mặc định của mình trong hàm handle(e) Các hành động mặc định này sẽ được thực thi khi sự kiện liên kết với nó được thực thi

Trang 9

- 139 -

Trong các dòng từ 8 tới 11 của Chương trình 7.7, hành động mặc định của i đối

tượng QueueHandler là thực hiện lệnh resume của đối tượng queue_ (lớp Queue) liên kết với nó Ta sẽ thảo luận chi tiết về hàm resume trong Mục 7.3.3 Trong phần này ta chỉ tập trung vào nội dung cách tạo ra kết nối giữa các đối tượng QueueHandler và đối tượng Queue

Để liên kết một đối tượng Queue với một đối tượng QueueHandler, Lớp Queue khai báo biến thành viên qh_ (dòng 19 trong Chưong trình 7.5) và Lớp QueueHandler khai báo biến thành viên queue_ (dòng 12 trong Chương trình 7.7) Hai biến này được khởi tạo khi một đối tượng Queue được tạo ra (dòng 12 trong.Chương trình 7.7) Sau đó, hàm khởi tạo của qh_ thiết lập biến thành viên queue_ để chia sẻ chung địa chỉ của đối tượng đầu vào Queue (đối tượng queue_(q) trong dòng 3 của Chương trình 7.7) Vỉ vậy kết nối hai chiều giữa đối tượng Queue và QueueHandler đã được tạo ra Kể từ điểm này, các đối tượng Queue và QueueHandler tham chiếu tới nhau bằng các biến qh_ và queue_

 Cơ chế khoá hàng đợi và cơ chế gọi ngược

Cơ chế khoá hàng đợi

NS2 sử dụng khái niệm ―khoá hàng đợi‖ để chỉ trạng thái hàng đợi đang truyền gói tin Mặc định, một hàng đợi có thể truyền một gói tin tại một thời điểm Nó không cho phép (khoá) truyền các gói tin khác cho tới khi hoàn thành việc truyền gói tin hiện tại Một hàng được gọi là đang bị khoá (blocked_=l) khi nó đang truyền gói tin và nó có trạng thái mở khoá (blocked_=0) khi nó không truyền gói tin

Hình 7.2 Sơ đồ trạng thái của cơ chế khoá hàng đợi Hình 7.2 cho thấy sơ đồ trạng thái của cơ chế khoá hàng đợi Khi hàng đợi ở trạng thái ―không khoá‖, nó cho phép truyền gói tin đi bằng cách thực hiệr lệnh ―target_-

>recv(p,&qh_)‖ Sau đó nó chuyển sang trạng thái ―khoá‖ ( đây hàng đợi sẽ phải đợi cho

đến khi nào việc truyền gói tin ra ngoài hoàj thành Khi đó hàm resumeO sẽ được gọi Sau điểm này, hàng đợi chuyển sanj trạng thái ―không khoá‖ và tiến trình trên lại được lặp lại

Cơ chế gọi ngược

Như đã đề cập trong Chương 5, một nút trong NS2 truyền các gói tin tc Nút nhận bằng cách thực thi hàm recv(p,h) với *p là gói tin truyền đi và *h là Thẻ quản lý Cơ chế gọi ngược là tiến trình ở đó đối tượng nhận gọi ngược cho đối tượng gửi để thực hiện một mục đích nào đó Trong tiến trình khóa hàng đợi cơ chế gọi ngược được sử dụng để mở

Trang 10

Xét hàm recv(p,h) của Lớp Queue trong Chương trình 7.8 Khi đối tượng I Queue nhận được gói tin *p, thay vì việc truyền ngay lập tức gói tin này tới đối I tượng nhận của

nó, đối tượng Queue thực hiện việc đưa gói tin vào bộ đệm I (dòng 3) Nhắc lại rằng, một đối tượng Queue chỉ cho phép truyền một gói tin chỉ khi nó không ở trạng thái khóa (dòng 4) Trong trường hợp này, dòng 5 sẽ lấy về gói tin từ đầu bộ đệm Nếu gói tin này hợp lệ (dòng 6), dòng 7 sẽ thiết lập trạng thái của đối tượng Queue là ―khóa‖ và dòng 8

sẽ chuyển tiếp gói tin này ; tới đối tượng nhận kế tiếp của đối tượng Queue (chứa trong biến target_) Đối tượng Queue truyền con trỏ QueueHandler qh_ của nó (thay vì con trỏ Thẻ quản lý đi tới nó) tới đối tượng nhận kế tiếp Con trỏ QueueHandler này đóng vai trò như một điểm tham chiếu cho cơ chế gọi ngược mở khóa hàng đợi

Trang 11

Hàm recv(p) của Lớp LinkDelay cũng được lập lịch cho sự kiện gói tin rời đi Vì

con trỏ Handler đầu vào là một con trỏ QueueHandler, sự kiện gói tin rời đi được liên kết với đối tượng qh_ kiểu QueueHandler Tại thời điểm thực thi, bộ lập lịch gọi hàm handle(p) của đối tượng QueueHandler qh_

Trong Chương trình 7.7, hàm này sau đó sẽ gọi đến hàm resume() để mở khóa cho đối tượng Queue liên kết với nó Như vậy có thể thấy đối tượng LinkDelay lập lịch

cho một sự kiện mà sự kiện này sẽ gọi ngược cho đối tượng Queue đã gọi nó để mở khóa hàng đợi

Chương trình 7.9 là mã nguồn của hàm resume() Đầu tiên hàm này lấy gói tin ở đầu bộ đệm (dòng 3) Nếu bộ đệm không rỗng (dòng 4) thì dòng 5 sẽ gửi gói tin tới đối tượng nhận kế tiếp của hàng đợi mà không cần quan tâm tới trạng thái của hàng đợi là khóa hay mở Trong trường hợp này, biến blocked_ vẫn không có sự thay đổi Nếu đối

Trang 12

- 142 -

tượng Queue đang ở trạng thái ―khóa‖, nó sẽ vẫn ở trạng thái khóa sau khi truyền gói tin Điều này là phù hợp với sơ đồ trạng thái trong Hình 7.2 Nếu hàng đợi rỗi (bộ đệm rỗng), biến blocked sẽ được ' thiết lập giá trị bằng 0 nếu cờ unblock_on_resume_ có giá trị bằng 0 và biến blocked_ sẽ được thiết lập giá trị bằng 1 trong trường hợp cờ , unblock_on_resume_ có giá tri bằng 1

 Lớp DropTail

Lớp DropTail là một Lớp con của Lớp Queue Nó được liên kết với Lớp Queue/DropTail của OTcl với mã nguồn được đưa ra trong Chương trình 7.10 Hàm khởi tạo của Lớp DropTaỉl tạo một con trỏ q_ (dòng 13) trỏ tới một đối tượng PacketQueue và thiết lập biến pq_thừa kế từ Lớp Queue bằng giá trị biến q_ (dòng 5) Trong quá trình thực hiện các hàm, Lớp DropTail tham chiếu tới bộ đệm của nó bằng

biến con trỏ q_ thay cho biến con trỏ pq_ của Lớp cha Nó cũng cho phép việc hủy gói tin

tại đầu bộ đệm nếu cờ drop_front_ (dòng 14) được thiết lập giá trị bằng 1 Lớp DropTail không xây dựng lại hàm recv(p,h) từ lớp cha Do đó, nó nhận gói tin qua hàm tecvíp.h) của Lớp Queue

Trong Chương trình 7.11, hàm enque(p) đầu tiên sẽ kiểm tra gói tin đến có ; làm tràn bộ đệm hay không (dòng 3) Nếu có, hoặc là nó sẽ hủy gỏi tin đang I đứng đầu hàng đợi (dòng 5-7) hoặc là nó sẽ hủy gói tin ở cuối hàng đợi (dòng ! 9) ở đây, hàm drop(p) (dòng 7 và 9) là hàm thành viên của Lớp Connector ; (xem Chương trình 5.4) Nếu bộ đệm còn đủ chỗ, dòng 10 sẽ đưa gói tin (p) vào I cuối bộ đệm (q_)

Trang 13

- 143 -

7.4 Một ví dụ mạng Two-Node

Ta đã giới thiệu về hai thành phần cơ bản của NS2 là nút và kênh truyền Trên cơ

sở của hai thành phần này, bây giờ ta sẽ tạo một mạng gồm hai nút với kênh truyền một chiều và cơ chế chuyển gói tin trong mạng như Hình 7.4

Hình 7.4 Một mạng hai nút với kênh truyền một chiều và các hàm của lớp

Simulator

 Khỏi tạo mạng

Mạng trong Hình 7.4 bao gồm một nút bắt đầu (n1), một nút kết thúc (n2) một

kênh SimpleLink kết nối giữa nl và n2, một tác tử nguồn lớp giao vận(udp) và một tác tử

nhận lớp giao vận(null) Mạng này được tạo ra bởi đoạn mã Tcl sau:

Ở đây, lệnh $ns node tạo ra một đối tượng Node Cơ chế bên trong của tiến trình

khởi tạo đối tượng này đã được trình bày trong Mục 6.6 Lệnh $ns simplex-link $nl $n2

<bw><đelay> DropTail tạo một đối tượng SimpleLink kết nối một chiều giữa nút nl và nút n2 Băng thông và độ trễ của kênh tương ứng sẽ là <bw> bps và <delay> giây Bộ đệm của kênh kiểu DropTail Như đã trinh bày trong Mục 6.6.3, lệnh $ns attach-agent $nl

$udp thiết lập đích của tác tử udp là đỉểm truy cập của nút n1 Lệnh $n2 attach-agent $n2

$null cài đặt tác tử null vào bộ phân kênh của nút n2

 Cơ chế luồng gói tin

Trang 14

- 144 -

Các bước để vận chuyển gói tin ―*p‖ từ tác tử udp tới tác tử null bao gồm:

- Tác tử udp gửi gói tin *p tới điểm truy cập của nút nl

- Gói tin *p được gửi tới bộ phân loại đứng đầu classifỉer_ (là đối tượng của

Lớp DestHastClassifier) của nút nl

- Đối tượng classifỉer_ lớp DestHashClassỉfier kiểm tra header của gói tin *p

Trong trường hợp này, đích của gói tin là nút n2 Do đó, bộ phân loại này sẽ chuyển tiếp

gói tin tới đối tượng SimpleLink đứng đầu chuỗi liên kết

- Đối tượng SimpleLink chuyển tiếp gói tin tới đối tượng Queue

- Đối tượng Queue đưa gói tin vào hàng đợi Nếu hàng đợi ở trạng thái không

khóa, nó sẽ chuyển tiếp gói tin đầu hàng đợi tới đối tượng LinkDelay kêt nối với nó và

thiết lập trạng thái của hàng đợi là trạng thái khóa

- Khi nhận được gói tin, đối tượng LinkDelay lập lịch hai sự kiện

- Sự kiện gói tin rời đi chỉ ra rằng việc truyền gói tin đã hoàn thành Sự kiện này

sẽ mở khóa cho hàng đợi Queue liên kết với đối tượng LỉnkDelay

- Sự kiện gói tin đi đến chỉ ra rằng gói tin đi đến đối tượng TTLChecker kết nối với đối tượng LinkDelay

- Đối tượng TTLChecker nhận gói tin và giảm giá trị của trường TTL I

Trong phần header của gói tin Sau khi giảm giá trị trường TTL, nếu trường I này

có giá trị bằng không thì gói tin sẽ bị đối tượng này hủy bỏ Ngược lại, đối tượng này chuyển tiếp gói tin tới điểm truy cập của nút n2 Nút n2 chuyển tiếp gói tin tới bộ phân loại đứng đầu classỉfỉer_ Vì ; nút n2 chính là đích của gói tin nên gói tin sẽ được chuyển tiếp tới bộ phân kênh dmux_i

Bộ phân kênh dmux_ chuyển tiếp gói tin tới tác tử null được cài đặt trong nó

Trang 15

Trong hầu hết mọi trường hợp, NS2 trích thông tin từ phần dữ liệu và lưu thông tin này vào phần header Ý tưởng này làm giảm bớt sự cần thiết phải xử lý thông tin trong phần dữ liệu trong thời gian chạy Ví dụ, thay vì việc phải đếm số lượng bit trong gói tin, NS2 lưu giá trị kích cỡ gói tin trong biến hdr_cmn::size_ (xem Mục 8.3.5) và truy cập vào biến này tại thời gian chạy

Nội dung của chương này tập trung vào vấn đề mô hình hóa gói tin trong NS2 Mục 8.1 đưa ra một cách nhìn tổng quan về mô hình hóa gói tin trong NS2 Mục 8.2 thảo luận về tiến trình cấp phát và thu hồi bộ nhớ dành cho gói tin Mục 8.3 và 8.4 đưa ra nội dung chi tiết về tổ chức phần header và phần dữ liệu của gói tin Các hướng dẫn về cách tùy biến các gói tin được đưa ra trong Mục 8.5

8.1 Tổng quan về nguyên tắc tạo gói tin

Kiến trúc gói tin

Kiến trúc của một mô hình gói tin trong NS2 được biểu diễn bởi Hình 8.1 Trong hình vẽ này ta thấy một mô hình gói tin bao gồm bốn thành phần chính: gói tin thực, lớp Packet, header theo giao thức và bộ quản lý header Ý nghĩa của các thành phần này như sau:

Gói tin thực: Một gói tin thực được xem như là một phần của bộ nhớ lưu trữ phần header và phần dữ liệu của gói tin NS2 không truy cập trực tiếp tới phần header hoặc phần dữ liệu mà nó sử dụng con trỏ bỉts_ và đata_ để truy cập tương ứng vào phần header

và phần dữ liệu của gói tin Chi tiết về phần header và phần dữ liệu có trong Mục 8.3 và 8.4 của chương này

Lớp Packet: Được khai báo trong Chương trình 8.1, Lớp Packet là một lớp C++ chính được dùng để biểu diễn các gói tin Nó chứa các biến và các hàm thành viên sau:

Trang 16

- 146 -

Hình 8.1 Mô hình gói tin trong NS2

Các biến thành viên của lớp Packet

bits_: Chuỗi chứa phần header của gói tin

data_: Con trỏ trỏ tới một đối tượng AppData chứa phần dữ liệu của gói tin fflag_: Được thiết lập là true nếu gói tin hiện tại đang được các đối tượng khác tham chiếu tới và là false trong trường hợp ngược lại

tree_: Con trỏ trỏ tới phần tử đầu danh sách gói tin tự do ref_count_: số lượng đối tượng đang tham chiếu tới gói tin next_: Con trỏ trỏ tới gói tin tiếp theo trong danh sách liên kết các gói tin Mr_len_: Kích thước phần header của gói tin

Các hàm thành viên của lớp Packet

- refcopy(): Tăng số lượng đối tượng tham chiếu vào gói tin lên một đơn vị

- alloc(): Tạo một gói tin mới và trạ về một con trỏ trỏ tới gói tin đã được tạo

- alloc(n); Tạo một gói tin mới có ―n‖ byte phần dữ liệu và trả về một con trỏ trỏ tới gói tin đã được tạo

Trang 17

Header theo giao thức (Protocol Specifỉc Header)

Từ Hình 8.1, ta thấy phần header của gói tin chứa một số header theo giao thức Mỗi header theo giao thức sử dụng một vùng liên tục trong header của gói tin để lưu các thuộc tính của gói tin Thông thường với hầu hết các đối tượng TclObject, có ba lớp liên quan với mỗi header theo giao thức đó là một lớp C++, một lớp OTcl và một lớp ánh xạ

-Lớp C++ (ví dụ như hdr_cmn hoặc hdr_ip): cung cấp một cấu trúc để lưu trữ các thuộc tính của gói tin

-Lớp OTcl (ví dụ như PacketHeader/Common hoặc PacketHeader/IP); đóng vai trò như một giao tiếp tới miền OTcl NS2 sử dụng lớp này để cấu hình header của gói tin từ miền OTcl

-Lớp ánh xạ (ví dụ như CommonHeaderClass hoặc IPHeaderClass); liên kết

lớp C++ với lớp OTcl

Bộ quản lý header (Packet Header Manager)

Duy tri một danh sách các giao thức đang hoạt động và cấu hình mọi header theo giao thức đang hoạt động đề thiết lập header của gói tin Nó có một biến hdrlen_ dùng để

Trang 18

- 148 -

lưu kích thước của phần header của gói tin chứa các header theo giao thức Biến hdrlen_ được liên kết với biến hdrlen_ của Lớp Packet Mọi sự thay đổi của một biến sẽ được tự động cập nhật sang biến liên kết

Sự kiện nhận gói tin

Được dẫn xuất từ Lớp Event (dòng 1 trong Chương trình 8.1), Lớp Packet có thể

được đưa vào dòng thời gian mô phỏng (xem chi tiết trong Chương 4) Trong Mục 4.2, ta

đã biết rằng một đối tượng Event là một đối tượng được tạo ra bởi người dùng từ mã Tcl Chương này sẽ thảo luận chi tiết về một Lớp khác dẫn xuất từ Lớp Event Đó là Lớp Packet

Như đã nói đến trong Mục 5.2.2, NS2 mô hình hóa sự kiện làm trễ quá trình truyền gói tin bằng cách đưa một sự kiện tương ứng vào dòng thời gian mô phỏng với

một khoảng thời gian trễ xác định trước Được dẫn xuất từ Lớp Event, lớp Packet có thể

được đưa vào dòng thời gian mô phỏng để biểu diễn việc nhận một gói tin bị trễ Ví dụ, câu lệnh sau (xem dòng 8 trong Chương trinh 7.4) lập lịch một sự kiện nhận gói tin để

đối tượng *target_ kiểu NsObject nhận gói tin *p tại thời điểm txt+delay_ giây trong tương lai: s.schedule(target_, p, txt + delay_)

Hàm schedule(-) của lớp Scheduler được định nghĩa trong Chương trinh 4.7 có đối số đầu vào thứ hai là một con trỏ Event Con trỏ Packet có thể được ép kiểu thành con trỏ Event trước khi đưa vào làm tham số thứ hai của hàm trên

Tại thời điểm thực thi sự kiện, bộ lập lịch sẽ thực thi sự kiện được lập lịch (*p) và gọi hàm target―>handle(p) đề thực thi hàm ―target->recv(p)‖ để chuyển tiếp gói tin *p tới con trỏ đối tượng *target_ lớp NsObject

- Danh sách lỉên kết gói tin

Là một trong bốn thành phần chính của gói tin trong NS2, một đối tượng Packet chứa một con trỏ next_ (dòng 11 trong Chưong trinh 8.1) để trợ giúp cho việc hình thành một danh sách các đối tượng Packet (ví dụ như Packet List trong Hình 8.2)

Hình 8.2 Danh sách liên kết các gói tin và danh sách gói tin tự do

Trang 19

- 149 -

Chương trình 8.2 đưa ra mã thực hiện của các hàm enque(p) và deque(p) cửa lớp PacketQueue Hàm enque(p) (dòng 3-13) thêm một đối tượng *p kiểu Packet vào cuối hàng đợi Nếu hàng đợi PacketQueue rỗng, NS2 sẽ thiết lập các con trỏ head_, tail_ và p trỏ tới cùng một điểm (dòng 5) Ngược lại, dòng 7-8 thiết lập con trỏ p trỏ vào gói tin ở cuối hàng đợi PacketQueue và dịch chuyển con trỏ tail_ trỏ vào cùng vị trí với con trỏ p

Vì con trỏ tail_ là con trỏ cuối cùng của hàng đợi PacketQueue nên dòng 10 thiết lập con trỏ tail_- >next_ bằng 0 (trỏ đến NULL)

Hàm deque (dòng 14-21) lấy về một con trỏ trỏ tới gói tin đầu bộ đệm Nếu không

có gói tin nào trong bộ đệm, hàm deque() sẽ trả lại con trỏ NULL (dòng 15) Nếu bộ đệm không rỗng, dòng 17 sẽ dịch chuyển con trỏ head_ tới gói tin tiếp theo, dòng 19 sẽ trả về con trỏ gói tin p đã được thiết lập là con trỏ head_ trong dòng 16

Danh sách gói tin tự do

Không như hầu hết các đối tượng NS2 khác, đối tượng Packet mỗi khi được tạo ra

sẽ không bị hủy cho đến khi kết thúc mô phỏng NS2 sẽ lưu giữ các đối tượng Packet không còn sử dụng trong một danh sách gói tin tự do (xem Hình 8.2) Khi NS2 cần một gói tin mới, đầu tiên nó sẽ kiểm tra xem danh sách gói tin tự do có rỗng hay không Nếu không rỗng, nó sẽ lấy một đối tượng Packet từ danh sách này Nếu danh sách này rỗng,

nó sẽ tạo một đối tượng Packet mới Ta sẽ thảo luận chi tiết về quá trình cấp phát và thu hồi bộ nhớ cho đối tượng Packet trong Mục 8.2

Có hai biến có mối quan hệ rất chặt chẽ với tiến trinh cấp phát và thu hồi bộ nhớ là biến fflag_ và free_ Ngưởi ta sử dụng biến fflag_ (dòng 6 trong Chương trinh 8.1) của một đối tượng Packet để xác định xem đối tượng này có đang được sử dụng hay không Nếu biến fflag_ có giá tộ true thì hiện tại nó đang được sử dụng và ngược lại biến này sẽ

có giá trị false Con trỏ tĩnh free_ (dòng 8 trong Chương trình 8.1) được mọi đối tượng

Trang 20

- 150 -

Packet sử dụng chung là một con trỏ trỏ vào gói tin đầu tiên của danh sách gói tin tự do Mỗi một gói tin trong danh sách gói tin tự do sử dụng biến next_ của mình để trợ giúp

cho quá trình thiết lập danh sách liên kết các đối tượng gói tin tự do Mặc dù NS2 không

trả về bộ nhớ được cấp phát cho một đối tượng Packet cho hệ thống, nó vẫn thực hiện

việc trả về bộ nhớ được phần header và phần dữ liệu của gói tin sử dụng (biến bits_ và data_) cho hệ thống (xem Mục 8.2.2) Vì yêu cầu lưu trữ một đối tượng gói tin trong bộ nhớ là tổng họp của phần header và phần dữ liệu cho nên việc duy trì danh sách gói tin tự

do sẽ tiết kiệm được nhiều không gian bộ nhớ

8.2 Sắp xếp và phân bổ gói tin

Không giống như hầu hết các đối tượng NS2 khác, một đối tượng Packet được NS2 cấp phát và thu hồi bộ nhớ bằng cách sử dụng các hàm tĩnh tương ứng là alloc() và free() Nếu có thể, hàm alloc() sẽ lấy một đối tượng Packet từ danh sách các gói tin tự

do Chỉ khi nào danh sách này rỗng, nó mới tạo ra một đối tượng Packet mới bằng cách

sử dụng hàm new Hàm free(p) thu hồi bộ nhớ đã cấp phát cho một đối tượng Packet

bằng cách trả về vị trí bộ nhớ đã được cấp phát cho phần header và phần dữ liệu của đối tượng này cho hệ thống và lưu trữ con trỏ p trỏ tới gói tin không được sử dụng vào danh sách gói tin tự do để có thể sử dụng lại sau đó Chi tiết của tiến trình cấp phát và thu hồi

bộ nhở cho đối tượng Packet được trình bày ở hai mục tiếp theo là 8.2.1 và 8.2.2

8.1.1 Cấp phát gói tin Chương trình 8.3 đưa ra chi tiết của hàm alloc() thuộc lớp Packet Hàm alloc() trả

về một con trỏ trỏ tới một đối tượng Packet được cấp phát cho đối tượng gọi hàm Nó

bao gồm hai phần: cấp phát gói tin trong các dòng 3-15 và khởi tạo gói tin trong các dòng 16-24

Xét tiến trình cấp phát gói tin trong các dòng 3-15 Dòng 3 khai báo p là con trỏ trỏ tới đối tượng Packet và thiết lập con trỏ p trỏ tới gói tin đầu tiên trong danh sách gói

tin tự do Nếu danh sách này rỗng (p=0), NS2 sẽ tạo một đối tượng Packet mới (dòng 11),

và cấp phát không gian nhớ có kích thước ―ỉiđrlen^‘ byte cho phần header của gói tin trong dòng 12 Biến hdrlen_ không được cấu hình trong quá trình khởi tạo đối tượng

Packet Thay vào đó, nó được thiết lập trong Pha cấu hình mạng (xem Mục 8.3.8) và

được hàm alloc() sử dụng để tạo header của gói tin

Hàm alloc() không cấp phát bộ nhớ cho phần dữ liệu của gói tin Nếu cần thì NS2

sẽ tạo phần này bằng hàm allocdata(n) (dòng 8-14 trong Chương trình 8.4)

Trang 21

- 151 -

Nếu danh sách gói tin tự do không rỗng, hàm allocí) sẽ thực thi các dòng 5-9 trong Chưcmg trình 8.3 (được thể hiện trong Hình 8.3) Trong trường hợp này, đầu tiên hàm alloc() cần chắc chắn rằng không có đối tượng nào khác đang sử dụng đối tượng gói tin p bằng cách kiểm tra xem biến fflag_ có giá trị false hay không (dòng 5) Sau đó, nó dịch chuyển con trỏ free_ tới vị trí mới theo dòng 6 Các dòng 8-9 khởi tạo giá tri bằng 0 cho

hai biến là uỉđ_ và tỉme_ của lớp Event Dòng 23 di chuyển gói tin này ra khỏi danh sách gói tin tự do bằng cách thiết lập giá tri p->next bằng 0

Hình 8.3 Sơ đồ tiến trình cấp phát gói tin khi danh sách gói tin tự do không rỗng

Các đường đứt nét hiểu diễn các hành động của hàm alloc

Trang 22

- 152 -

Sau khi tiến trình cấp phát gói tin hoàn tất, các dòng 16-24 khởi tạo đối tượng

Packet đã được cấp phát Dòng 16 gọi hàm init(p) để khởi tạo header của gói tin *p Từ dòng 5 trong Chương trình 8.1, lời gọi hàm init(p) thực thi lệnh “bzero(p-

>bits_,hdrlen_)” để thiết lập giá trị của bits_ bằng 0 Dòng 19 thiết lập biến giá trị biến

ff lag_ là true để chỉ ra rằng gói tin *p hiện đang được sử dụng Dòng 23 thiết lập con trỏ p->next bằng 0 Dòng 17, 18 và 20 khởi tạo một header gói thông dụng Ta sẽ thảo luận

chi tiết hơn về vấn đề khởi tạo này trong Mục 8.3.2

Ngoài hàm alloc(), còn một số hàm khác có liên quan bao gồm hàm alloc(n), hàm a!locdata(n) và hàm copy() (xem Chương trinh 8.4) Hàm alloc(n) cấp phát một gói tin

(dòng 3) và gọi hàm allocdata(n) (dòng 5) Hàm alloc(n) thực hiện việc tạo phần dữ liệu

của gói với kích cỡ ―n‖ byte bằng cách gọi hàm new PacketData(n) trong dòng 11 Ta sẽ

đi vào chi tiết nội dung này trong Mục 8.4,,

Hàm copy() trả về một bản sao của đối tượng Packet hiện tại Sự khác biệt duy nhất giữa đối tượng gói tin hiện tại và bản sao của nó là giá trị của trường ID định danh (uid_) Hàm này rất hữu dụng khi ta cần tạo ra một đối tượng gói tin tương tự hoặc khác biệt đối chút so với một đối tượng gói tin đã có Đầu tiên hàm copy() này sẽ cấp phát một con trỏ gói tin p trong dòng 17 Sau đó, nó sao chép toàn bộ phần header và phần dữ liệu của gói tin hiện tại tới gói tin *p trong các dòng tương ứng là dòng 18 và dòng 20

Mặc dù tên của hàm là refcopy() (dòng 16 trong Chương trình 8.1) nhưng hàm refcopy() thực sự không tạo ra một bản sao của một đối tượng Packet Thay vào đó, nó trả về một con trỏ trỏ tới đối tượng Packet hiện tại Chẳng hạn như ta giả sử rằng p là một con trỏ Packet thì lệnh x=p và x=p->refcopy() đều chung một kết quả là lưu trữ p trong

biến X Tuy nhiên hàm refcopy() lại cập nhật số lượng các đối tượng sử dụng chung một

đối tượng Packet thông qua biến ref_count_ (dòng 9 trong Chương trình 8.1) Biến này ban đầu được khởi tạo bằng 0 trong hàm khởi tạo của lớp Packet (dòng 13 trong Chương trình 8.1) Mỗi khi hàm ref_copy() được gọi một lần, nó sẽ tăng giá trị của biến ref_count lên một đơn vị để chỉ ra rằng có một đối tượng mới bắt đầu sử dụng đối tượng

packet hiện tại Tương tự như vậy, hàm này sẽ giảm giá trị biến ref_count đi một đơn vị mỗi khi hàm free(p) (xem Mục 8.2.2) được gọi để chỉ ra rằng có một đối tượng ngừng sử dụng đối tượng Packet hiện tại

Trang 23

- 153 -

8.1.2 Thu hồi gói tin

Khi NS2 không cần sử dụng một gói tin *p nữa, nó sẽ thu hồi gói tin bằng cách sử

dụng hàm free(p) Bằng tiến trình thu hồi, NS2 sẽ trả lại cho hệ thống không gian nhớ đã được sử dụng để lưu phần header và phần dữ liệu của gói tin, thiết lập con trỏ data_ với giá trị bằng 0 và lưu đối tượng Packet vào trong danh sách gói tin tự do Chú ý rằng mặc

dù giá trị của biến bits_ không được thiết lập bằng 0 nhưng không gian nhớ đã được cấp phát để lưu trữ biến này không còn truy cập được qua biến này nữa

Chi tiết của hàm free(Packet*) được đưa ra trong Chương trình 8.5

Trước khi trả về một đối tượng Packet cho danh sách gói tin tự do, ta cần phải đảm bảo rằng:

Gói tin vằng: về một đối tượng Packet cho danh sách gói tin tự do, ta cần phảiông được thiết lập bằng 0 nhưnKhông có đng: về một đối tượng ->fflag_ = 1 trong dòng 3) vì khôngGói tin không xu một đối tượng ->fflag_ = 1 trong dòng 3) vì không thể thu hồi một gói tin đã được thu hồi.ng khônằm trên dòng thời gian mô phỏng sẽ gây ra sự kiện sai trịnh tự và lỗi trong thời gian chạy Dòng 5 kiểm tra để khẳng định rằng định danh ID của sự kiện tưong ứng với đối tượng gói tin p có giá trị âm để đảm bảo gói tin không nằm trên dòng thời gian mô phỏng

Con trỏ phần dữ liệu đata_ của gói tin phải khác NULL (p->data_ * 0 trong dòng

6) khi trả về cho hệ thống bộ nhớ do phần dữ liệu của gói chiếm giữ

Trang 24

- 154 -

NS2 cho phép nhiều hon một đối tượng mô phỏng chia sẻ cùng một đối tượng Packet Để thu hồi một gói tin, NS2 phải đảm bảo rằng hiện tại không có bất cứ một đối tượng nào đang sử dụng gói tin hiện tại Nếu biến ref_count_ > 0 (có nghĩa là có một đối tượng đang gọi hàm free(p) trong khi có các đối tượng khác đang sử dụng gói tin *p), hàm free(p) sẽ chỉ thực hiện việc giảm giá trị biến ref_count_ đi một đơn vị để chỉ ra rằng

có một đối tượng ngừng sử dụng gói tin *p (dòng 15) Ngược lại nếu biến ref_count_ = 0 thì các dòng 13- 15 sẽ xóa phần header và phần dữ liệu của gói tin và lưu đối tượng Packet vào danh sách gói tin tự do

Nếu cả bốn điều kiện trên đều thỏa mãn, hàm free(p) sẽ thực hiện các dòng lệnh

6-13 trong Chương trình 8.5 Sơ đồ ngữ cảnh của phần này được minh họa trong Hình 8.4 Dòng 7 trả về cho hệ thống bộ nhớ được phần dữ liệu của gói tin sử dụng Dòng 8 thiết lập con trỏ data_ bằng 0 Dòng 10 trả về cho hệ thống bộ nhớ được phần header của gói tin sử dụng bằng cách gọi hàm inỉt(p) (xem dòng 5 của Chương trình 8.1) Hàm free(p) không cần thiết lập biến bỉts_ bằng 0 vì mọi truy cập vào biến bỉts_ sau lệnh hàm free này đều gây ra lỗi trong thời gian chạy (lỗi runtime) Dòng 11 và 12 đưa gói tin này vào đầu danh sách gói tin tự do Cuối cùng, dòng 13 thiết lập biến fflag_ là fal.se để quy định rằng gói tin này hiện không còn được sử dụng

Trang 25

- 155 -

Hình 8.4 Tiến trình trả một gói tin về danh sách gói tin tự do Các đường đứt nét biểu diễn các hành động do hàm free của ỉởp Packet thực hiện

8.2 Tiêu đề gói tin

Header là một phần của gói tin Nó chứa các thuộc tính của gói tin chẳng hạn như

ID định danh, địa chỉ IP, Header của gói tin được lưu trong biến bỉts_ của lớp Packet (xem dòng 3 ừong Chương trình 8.1) Biến bits_ được khai báo kiểu chuỗi và không có cấu trúc để lưu các thuộc tính Do đó, NS2 đưa ra kiến trúc hai mức của biến bits_ như trong Hình 8.5

Mức 1 chia phần header của gói tin thành các header theo giao thức Vị trí của mỗi header theo giao thức trong biến bỉts_ được xác định bằng biến offset_ Cấp độ thứ hai biểu diễn cấu trúc của từng header theo giao thức đê lưu các thuộc tính của gói tin ở cấp

độ này, các thuộc tính của gói tin được lưu trữ dưới dạng các thành phần của kiểu cấu trúc dữ liệu struct trong C++

Trong thực tế, một gói tin chỉ chứa các header theo giao thức có liên quan Tuy nhiên, một gói tin NS2 mặc định chứa mọi header theo giao thức trong phần header của gói tin mà không cần quan tâm tới loại gói tin Kích thước bộ nhớ phần header của mọi

gói tin là giống nhau và được lưu trong biến hdrlen_ Biến này không có quan hệ với

kích cỡ gói tin trong mô phỏng Yí dụ, các gói tin TCP và UDP có kích cỡ khác nhau nên

các giá trị lưu trong các biến hdr_cmn::size_ tương ứng của các gói này là khác nhau Tuy nhiên các giá trị lưu trong biến Packet::hdrlen_ đối với cả gói tin TCP và UDP là như nhau

Trang 26

- 156 -

Hình 8.5 Kiến trúc của header gói tin Trong các phần tiếp theo, đầu tiên ta sẽ thảo luận về header của gói tin ở Mức 1 trong Mục 8.3.1 Các Mục 8.3.2 và 8.3.3 đưa ra các ví dụ về các header theo giao thức là header gói thông dụng và header gói IP Mục 8.3.4 thảo luận về một trong những thuộc tính chính của gói tin là loại gói tin Mục 8.3.5 giải thích chỉ tiết về header theo giao thức bao gồm ở cả hai mức Mục 8.3.6 minh họa cách truy cập vào các thuộc tính được lưu trữ trong phần header của gói tin Mục 8.3.7 thảo luận về một trong các thành phần chính của header gói tin là bộ quản lý header Cuối cùng Mục 8.3.8 sẽ đưa ra tiến trình khởi tạo header của gói tin

8.2.1 Truy cập header gói tin ở Mức 1

Trong Mức 1, NS2 đưa mọi header của mọi giao thức có liên quan (chẳng hạn như header gói thông dụng, header gói IP, header gói TCP, ) vào header của gói tin (Hình 8.5) về bản chất, NS2 phân bố các header theo giao thức một cách liên tục Vị trí của mỗi header theo giao thức được xác định bằng một khoảng dịch chuyển cố định so với vị trí đầu của header toàn bộ gói tin Khoảng cách từ vị trí bắt đầu của header toàn bộ gói tin tới vị trí bắt đầu của header theo giao thức trong gói tin được lưu trong biến offets_ của mỗi header theo giao thức Ví dụ: nếu hdr_cmn, hdr_ip và hdr_tcp tương ứng là header gói thông dụng, header gói IP và header gói TCP trì vị trí tưcmg đối của các header này tính từ vị trí bắt đầu của header toàn bộ gói tin tương ứng sẽ là hdr_cmn"offset_, hdr_ip"offset_ và Mr_tcp‖offset ,

Trang 27

- 157 -

8.2.2 Header gói tin thông dụng

Header gói tin thông dụng (common packet header) chứa các thuộc tính thông dụng cho mọi loại gói tin Nó được triển khai bằng kiểu dữ liệu cấu trúc struct của C++ cấu trúc này có tên là hdr_cmn Chương trình 8.6 dưới đây hiền thị một phần khai báo của cấu trúc hdr_cmn:

sỉze_: Kích thước gói tin được sử dụng trong mô phỏng

uỉd_: Giá trị ID định danh gói tin

đir_t: chiều truyền gói tin b -1 (chiều xuôi), 1 (chiều ngược) và 0 (chưa sử dụng)

offset_: Khoảng dịch chuyển tương đối từ vị trí bắt đầu của header gói tin tới

vị trí bắt đầu lưu trữ phần header gói tin thông dụng

Hầu như mọi hàm của lớp hdr_cmn đóng vai trò như là các giao tiếp để truy cập vào các biến thành viên của nó Hàm access(p) trong các dòng 8-10 là một hàm quan trọng nhất của hdr_cmn Nó được sử dụng để truy cập một header4heo giao thức của đối tượng đầu vào *p kiểu Packet Ta sẽ thảo luận chi tiết về cơ chế truy cập này trong Mục 8.3.6

8.2.3 Header gói IP

Header gói IP được biểu diễn bằng cấu trúc dữ liệu C++ kiểu struct có tên là hdr_ip Chương trình 8.7 đưa ra một phần của khai báo cấu trúc hdr_ip

Trang 28

- 158 -

cấu trúc hdrip chứa 5 biến thành viên chính liên quan tới thông tin gói tin IP bao gồm:

src_: Địa chỉ nút nguồn của gói tin

dst_: Địa chỉ nút đích của gói tin

ttl_: Giá trị thời gian sống (TTL) của gói tin

fid_: ID định danh luồng dữ liệu của gói tin

prio_: Cấp độ ưu tiên của gói tin

Biến src_ và dst_ trong IP header đều là các biến có kiểu dữ liệu có cấu trúc ns_addr_t Do đó, src_.addr lưu địa chỉ nút nguồn và src_.port lưu cổng của tác tử gửi gói tin Tương tự như vậy, gói tin sẽ được gửi tới một tác tử nhận được gắn vào cồng dst_.port của nút có địa chỉ dst_.addr_

Dòng 7-11 trong Chương trình 8.7 khai báo biến offset_, hàm offset(off) và hàm access(p) là các thành phần cơ bản để truy cập vào phần IP header của một gói tin Ta sẽ thảo luận về cơ chế truy cập gói tin trong Mục 8.3.6 Các dòng 12-20 trong Chương trình 8.7 là các hàm trả về giá trị của các biến

8.2.4 Loại gói tin

Trang 29

- 159 -

Mặc dù được lưu trong header gói thông dụng nhưng trường loại gói tin là trường lưu thông tin về loại của toàn bộ gói tin chứ không phải loại của header theo giao thức Mỗi gói tin chỉ có một loại tương ứng trong khi nó có thể chứa nhiều header theo giao thức khác nhau Ví dụ một gói tin được đóng gói bằng cả giao thức TCP và IP nhưng loại gói tin là gói dữ liệu âm thanh hoặc gói TCP chứ không thể đồng thời là cả hai loại này

NS2 lưu thông tin về loại gói tin trong biến thành viên pty^e_ của header gói thông dụng Biến ptype_ này có kiểu enum packet_t được định nghĩa trong Chương trinh 8.9 Các phần tử của một enum là các số nguyên được ánh xạ thành các chuỗi Trong

Hình 8.9, chuỗi PT_TCP (dòng 2) và PT_UDP (dòng 3) được ánh xạ tưong ứng với các

số nguyên 0 và 1 Do enum packet.t có khai báo chuỗi PT_NTYPE (biểu diễn loại góị tin không xác định) trong phần tử cuối cùng nên giá trị của PT_NTYPE là Np-1 với Np là

số phần tử của packet_t NS2 cung cấp 60 loại gói tin đã được định nghĩa sẵn Điều này

có nghĩa là giá trị mặc định của PT_NTYPE là 59

Trong các dòng 11-30 của Chương trình 8.9, lớp p_info ánh xạ mỗi phần tử của packet_t tới một chuỗi mô tả Nó có một biến mảng liên kết tĩnh tên là name_ (dòng 28) Chỉ số của mảng name_ là loại gói tin và giá trị của mỗi phần tử của mảng này là chuỗi

Trang 30

Ví dụ 8.1 Lớp Agent có nhiệm vụ tạo và hủy các gói tin tầng Mạng (xem Chương

11) Đây là lớp cơ sở của các module giao thức TCP và UDP tầng Chuyển vận Lớp

Agent cung cấp một hàm có tên là allocpkto để cấp phát một gói tin

Để in thông tin về loại của mọi gói tin được cấp phát ra màn hình, ta sửa đồi hàm allocpkto của Lớp Agent trong file ~ns/common/agent.cc thành như sau:

Từ dòng 5 tới dòng 11 là đoạn mã thêm vào mã gốc Dòng 6 thực hiện việc thiết lập biến ―ch‖ tham chiếu tới header gói thông dụng của gói tin Dòng 7 sử dụng hàm ptype() để lưu thông tin trong header gói thông dụng vào biến pt kiểu enum packet_t Chú ý rằng, biến packet_info là biến public của Lớp p_info Khi biến pt được đưa vào làm đối số đầu vào của hàm packet_info.name(pt), hàm này sẽ trả lại giá trị là chuỗi mô

tả tương ứng với kiểu của gói tin p (dòng 8) Sau khi biên dịch lại đoạn mã trên, trình mô phỏng sẽ hiển thị các chuỗi mô tả loại của mọi gói tin được cấp phát lên trên màn hình

Ví dụ, khi ta chạy mã mô phỏng Tcl trong Chương trình 2.1 và 2.2 thuộc Chương 2, kết quả sau sễ hiển thị lên trên màn hình:

Trang 31

- 161 -

8.2.5 .Header theo giao thức

Một header theo giao thức chỉ lưu các thuộc tính của gói tỉn liên quan tới giao thức tương ứng Ví dụ, header gói thông dụng lưu các thuộc tính cơ bản như ID định danh gói, kích thước gói, Header gói IP lưu các thuộc tính gói tin IP chẳng hạn như địa chỉ IP nguồn, địa chỉ IP đích và các số hiệu cổng Trong NS2 có 48 loại header theo giao thức khác nhau

Mỗi Header theo giao thức được mô hình hoá bằng ba lớp sau:

Lớp Header theo giao thức trong C++

Trong C++, NS2 sử dụng một cấu trúc dữ liệu kiểu struct để biểu diễn một header theo giao thức Nó lưu trữ các thuộc tính của gói tin và giá trị độ dịch tương dối của nó trong kiểu dữ liệu struct Nó cũng cung cấp hàm access(p) để trả về một tham chiếu tới header theo giao thức của gói tin *p Được dùng để biểu diễn một header theo giao thức,

mỗi loại dữ liệu struct được đật tên theo định dạng hdr_<xxx> với <xxx> là một chuỗi

bất kỳ biểu diễn loại giao thức mà header theo giao thức biểu diễn Ví dụ, tên của lớp C++ cho header gói thông dụng là hdr_cmn

Trong miền C++, các header theo giao thức được khai báo và không cần khởi tạo

do NS2 sử dụng kiểu dữ liệu struct (thay cho một lớp) để biểu diễn header theo giao thức

và không yêu cầu khởi tạo header theo giao thức Từ đây trở về sau ta thống nhất dùng thuật ngữ struct và class thay thế cho nhau

Lớp Header theo giao thức trong OTcl

Với mỗi Lớp C++ dùng để biểu diễn header theo giao thức, NS2 định nghĩa một lớp liên kết tương ứng trong miền OTcl Mỗi Lớp OTcl đóng vai trò như một giao tiếp từ

miền OTcl Nó được đật tên theo định dạng PacketHeader/<XXX> trong đó <xxx> là

một chuỗi bất kỳ biểu diễn tên của header theo giao thức Ví dụ, lớp OTcl dành cho

header gói thông dụng có tên là PacketHeader/Common

Lớp ánh xạ Header theo giao thức

Lớp ánh xạ có nhiệm vụ liên kết một lớp OTcl và một lớp C-H- lại với nhau Mọi lớp header theo giao thức được dẫn xuất từ lớp PacketHeaderClass là Lớp con của lớp TclClass Lớp ánh xạ được đặt tên theo định dạnơ <XXX>HeaderClass trong đó <xxx>

là một chuỗi bất kỳ biểu diễn một header theo giao thức Ví dụ tên của lớp ánh xạ dành cho header gói thông dụng là CommonHeaderClass

Chương trình 8.10 đưa ra khai báo của Lớp PacketHeaderClass Lớp này có hai biến chính là hdrlen_ trong dòng 8 và offset_ trong dòng 9 Biến hdrlen_ biểu diễn độ dài phần header theo giao thức Đây là thông tin hệ thống cần để lưu trữ một Lớp header theo giao thức trong C++ Biến offset_ chỉ ra vị trí của header theo giao thức trong header chung của gói tin

Trang 32

- 162 -

Hàm khởi tạo của Lớp PacketHeaderClass trong dòng 3 và 4 có hai đối số đầu vào Đối số thứ nhất là classname chứa tên của Lớp OTcl tương ứng chẳng hạn như PacketHeader/Common Đối số thứ hai là độ dài của phần header theo giao thức trong C++ Trong các dòng 3-4, hàm khởi tạo của Chương trình 8.10 đưa đối số classname vào hàm khởi tạo của lớp TclClass, lưu giá trị của đối số hdrlen vào biến hdrlen_ và thiết lập giá trị biến offset_ bằng 0

Một header theo giao thức được triển khai bằng cách sử dụng kiểu dữ liêu struct

do đó không có hàm thừa kế command(-) từ lớp TclObject NS2 dùng đến các phương thức OTcl được định nghĩa trong lớp ánh xạ để lấy các hành động C++ trong miền OTcl

Ta sẽ thấy ví dụ về việc sử dụng phương thức offset trong Mục 8.3.8 khi thảo luận về cơ chế khởi tạo gói tin

Xét ví dụ một header gói tin thông dụng, trong đó hdr_cmn là lớp C++, PacketHeader/Common là lớp OTcl và CommonPacketHeaderClass là lớp ánh xạ tương ứng (xem Bảng 8.1) Chương trình 8.12 cho thấy khai báo của lớp

Trang 33

- 163 -

CommonPacketHeaderClass Đây là một lớp con của lớp TclClass Biến lớp ánh xạ class_cmnhdr được khởi tạo ngay tại thời điểm khai báo lớp Trong chương trình trên, dòng 3 gọi hàm khởi tạo của lớp cha (lớp PacketHeaderClass) với hai đối số đầu vào là tên lớp OTcl (PacketHeader/Common) và lượng bộ nhớ cần thiết để chứa lớp C++ (hdr_cmn) ở đây, hàm ―sizeof(hdr_cmn)‖ thực hiện việc tính toán không gian nhớ cần thiết để chứa cấu trúc hdr_cmn của header gói thông dụng Trong dòng 6 của Chương trình 8.10 hàm binđ_offset(&hdr_cmn" of f set_) thiết lập biến offset_ để chia sẻ địa chỉ header gói thông dụng trong đối số đầu vào Vì vậy mọi sự thay đổi trong hdr_cmn::offset_ sẽ được tự động cập nhật trong biến *offset_ của lớp CommonHeaderClass và ngược lại

Bảng 8.1 Các lớp và các đối tượng liên quan tới header gói thông dụng

Cơ chế truy cập Header gói tin

Trong phần này ta sẽ minh họa cách truy cập và chỉnh sửa các thuộc tính gói tin được lưu trong phần header của gói tin NS2 triển khai một cấu trúc hai mức để lưu các thuộc tính trong header của gói tin ở mức thứ nhất, các header theo giao thức được lưu trong header của gói tin ở mức thứ hai, mỗi header theo giao thức triển khai lưu các thuộc tính trong theo giao thức bằng một cấu trúc struct của C++ Cơ chế truy cập header bao gồm hai bước chính: (1) Lấy một tham chiếu tới một header theo giao thức và (2) Lấy hoặc sửa đồi các thuộc tính trong cấu trúc của header theo giao‗thức Trong phần này, ta sẽ giải thích về cơ chế truy nhập qua header gói thông dụng (xem tên các lớp tương ứng trong Bảng 8.1)

Lấy tham chiếu tới Header gói thông dụng

NS2 lấy một tham chiếu tới một header theo giao thức của một gói tin *p bằng cách sử dụng hàm access(p) trong lớp C++ Để lấy tham chiếu tới header gói thông dụng của một đối tượng Packet *p, ta sử dụng lệnh hdr_cmn‖access(p) (xem Ví dụ 8.2)

Trang 34

- 164 -

Ví dụ 8.2: Xét hàm allocpkto của lớp Agent trong Chương trình 8.13 Các dòng

1-6 tạo một đối tượng Packet và trả về con trỏ tham chiếu tới đối tượng được tạo Đầu tiên hàm allocpkto gọi hàm alloc() của lớp Packet trong dòng 3 đế cấp phát một gói tin (xem chi tiết trong Mục 8.2.1) Sau đó dòng 4 khởi tạo gói tin được cấp phát bằng cách gọi

hàm initpkt(p) Cuối cùng, dòng 5 trả về con trỏ p tham chiếu tới đối tượng đã được khởi

tạo

Hàm initpkt(p) theo cấu trúc đã được định nghĩa trong các lớp header theo giao thức trong C++ để thiết lập các thuộc tính gói tin nhận các giá trị mặc đinh Dòng 8 và 14 trong Chương trình 8.13 thực hiện bước đầu tiên trong cơ chế truy cập là lấy tham chiếu tới header gói thông dụng vào biến ch và lấy tham chiếu trong header gói IP vào biến iph

Sau khi lấy được các con trỏ ch và ỉph, các dòng 10-12 và 15-18 thực hiện bước thứ hai trong cơ chế truy cập là truy cập vào các thuộc tính theo cấu trúc đã được định nghĩa trong header theo giao thức Trong bước này, các thuộc tính Liên quan của gói tin chẳng hạn như ID định danh gói, loại gói, kích thước gói, địa chỉ IP nguồn và số hiệu cổng nguồn, địa chỉ IP đích và số hiệu cổng đích được cấu hình qua các con trỏ ch và iph Chú ý rằng biến uỉdcnt là một biến tĩnh của lớp Agent dùng để chứa tổng số gói tin đã sinh ra Ta sẽ thảo luận chi tiết về lớp Agent trong Chương 9

Trang 35

- 165 -

Hình 8.6 Cơ chế hên trong của hàm access(p) của kiểu dữ liệu hdr_cmn với p

là con trỏ tham chiếu tới đối tượng Packet Trong Hình 8.6 hàm access(off) thực hiện công việc đơn giản là trả về giá trị

&bits_[off ] trong đó bỉts_ là biến thành viên của lớp Packet chứa header của gói tin Do hdr_cmn đưa biến offset_ của nó làm đối số đầu vào, về bản chất, hàm access(offset_) trả lại giá trị &bits_[hdr_cmn‖offset_] Đây chính là địa chỉ tham chiếu tới header gói thông dụng được lưu trong đối tượng *p kiểu Packet Tham chiếu này được hàm access(off) của lớp Packet trả về cho lớp hdr_cmn dưới dạng một giá trị kiểu unsigned char* Sau đó, lớp hdr_cmn ép kiểu của tham chiếu nhận được thành kiểu hdr_cmn* và trả về giá trị này cho đối tượng gọi hàm

Truy cập các thuộc tính của gói tin trong một header theo giao thức

Sau khi nhận được tham chiếu tới một header theo giao thức, bước thứ hai là tmy cập vào các thuộc tính theo cấu trúc quy định trong lớp header theo giao thức của C++

Do NS2 khai báo một header theo giao thức dưới dạng dữ liệu cấu trúc kiểu struct, việc truy cập vào các thuộc tính của header theo giao thức của gói tin khá dễ dàng (xem Ví dụ 8.2)

 Bộ quản lý Header gói tín

Một bộ quản lý header gói tin có nhiệm vụ quản lý một danh sách các giao thức đang được sử dụng và thiết lập các giá trị độ lệch tương đối theo vị trí của các giao thức này Nó được thực hiện bằng cách sử dụng một lớp C++ có tên là PacketHeaderManager được liên kết với một lớp OTcl có cùng tên Chương trình 8.14 cho ta thấy khai báo của lớp PacketHeaderManager trong C++ cũng như lớp liên kết với nó Hình 8.7 biểu diễn sơ

đồ của lớp PacketHeaderManager trong OTcl

Trang 36

- 166 -

Hình 8.7 Kiến trúc của một đối tƣợng PacketHeaderManager trong OTcỉ

Trang 37

- 167 -

Lớp OTcl PacketHeaderManager có hai biến instvar là hdrlen_ và tab_ Biến hdrlen_ lưu giá trị kích thước phần header của gói tin Ban đầu biến này được gán giá trị bằng 0 trong dòng 1 của Chương trình 8.15, và giá trị của nó sẽ được tăng lên mỗi khi có một header theo giao thức được thêm vào header của gói tin Biến tab_ (dòng 2 trong Chương trình 8.16) biểu diễn danh sách các giao thức đang hoạt động Đây là một mảng liên kết trong đó mỗi chỉ số của mảng là một tên lớp header theo giao thức trong OTcl và giá trị của phần tử tương ứng bằng 1 nếu header theo giao thức này đang hoạt động Nếu header theo giao thức không hoạt động, phần tử tưong ứng của mảng tab_ sẽ không cỏ giá trị

Khỏi tạo header của gói tin

Header của gói tin được khởi tạo theo tiến trình ba bước sau đây:

Bước 1: Tại thời điểm biên dịch

Trong quá trình biên dịch, NS2 dịch mọi mã C++ thành một file thực thi được Nó thiết lập mọi biến cần thiết (bao gồm kích thước của mọi header theo giao thức) cho mọi header theo giao thức đã được xây dựng sẵn và đưa toàn bộ các header theo giao thức đã được xây dựng sẵn vào danh sách các giao thức hoạt động Có ba tác vụ chính trong bước này:

Tác vụ 1: Xây dựng các biến ánh xạ, cấu hình biến hdrlen_, đăng ký tên lớp OTcl

và liên kết giá trị offset

Trang 38

- 168 -

Do mọi biến ánh xạ được khởi tạo khi khai báo nên chúng được khởi tạo trong quá trình biên dịch bằng các lệnh khởi tạo của chúng Ví dụ xét header gói phổ biến có tiến trình khởi tạo được biểu diễn trong Hỉnh 8.8 Tiến trình này gồm các bước sau:

2 Lưu tên lớp OTcl tương ứng (ví dụ PacketHeader/Common) trong biến classname_ của lớp TclClass

3 Xác định giá tri kích thước của header theo giao thức (sử dụng hàm sizeof(-‖)) và lưu giá tộ vào biến hdrlen_ của lớp PacketHeaderClass

4 Liên kết biến PacketHeader::offset_ với biến tương ứng của lớp hdr_cmn trong C++

Hình 8.8 Khởi tạo của biến ánh xạ tĩnh cỉass_cmnhdr

• Tác vụ 2: Gọi hàm bind() của lớp TclClass để xuất biến hdrlen_

Hàm main của NS2 (main(argc, argv)) gọi hàm init(…) của lớp Tcl Hàm init(…) này tiếp theo sẽ gọi hàm bindO của lớp TclClass cho mọi biến ánh xạ Hàm bind() đăng ký và liên kểt tên một lớp trong OTcl với một lớp trong C-H- (xem file

~tclcl/Tcl.cc) Hàm này được xây dựng lại trong lớp PacketHeaderClass

Trong các dòng 12-17 của Chương trình 8.10, lớp PacketHeaderClass xây dựng lại hàm bind() của lớp Tcl Đầu tiên dòng 13 gọi hàm bind() của lớp TclClass Sau

đó, dòng 15 xuất biến hdrlen_vào biến cùng tên trong OTcl Cuối cùng, dòng 16 đăng ký phương thức offset trong OTcl

Đối với lớp CommonHeaderClass, biến classname_ có giá trị là PacketHeader/Common và biến hdrlen_ có giá tri là 104 byte Do đó, dòng 15 của Chương trình 8.10 thực thi lệnh sau trong miền OTcl:

PacketHeader/Common set hdrlen_ 104

Lệnh này thiết lập giá trị biến hdrlen_ của lớp PacketHeader/Common là 104 Chú

ý rằng biến hdrlen_ này không được liên kết với miền C++

Trang 39

- 169 -

Sau khi hoàn thành Tác vụ 1 và Tác vụ 2, mối quan hệ các lớp có liên quan hdr_cmn5 PacketHeader/Common và CommonHeaderClass được biếu diễn như trong Hình 8.9

Hình 8.9 Sơ đồ quan hệ của đối tượng ánh xạ tĩnh class_cmnhdr, lớp hdr_cmn,

lớp PacketHeader/Common và lớp Packet Đối tượng ánh xạ class_cmnhdr là biến tĩnh của lớp

CommonHeaderClass được dẫn xuất lần lượt từ các lớp PacketHeaderClass và TclClass Các biến classname_, hdrlen_ và offset_ của lớp này được thừa kế từ các lớp cha Sau khi hoàn thành việc khởi tạo đối tượng, biến classname_ sẽ chứa tên của lớp header gói thông dụng trong OTcl,

(PacketHeader/Common), biến hdr_len chứa kích thước bộ nhớ cần thiết (tính theo byte) để lưu trữ header gói thông dụng và biến offset_ trỏ đến biến hdr_cmn»offset_

ở đây, biến offset_ của lớp CommonHeaderClass chỉ trỏ tới biến offset_ của lớp hdr_cmn Tuy nhiên tại thời điểm này, giá trị offset đang được thiết lập bằng 0 Các mũi tên nét đứt trong Hình 8.9 chỉ ra rằng giá trị của biến hdr_cmn"offset_ sau đó sẽ được thiết lập để lưu giá trị độ lệch tương đối tính từ đầu header của gói tin tới điểm bắt đầu của header gói thông dụng Sau khi hàm Tcl::init() gọi hàm bind() của lớp PacketHeaderClass biến hdrlen_ của lớp PacketHeader/Common sẽ lưu giá trị của biến hdrlen_ của lớp CommonHeaderClass Chú ý rằng Tác vụ 1 và Tác vụ 2 chỉ thiết lập lớp

C++, lớp OTcl và lớp ánh xạ Vì thê, bộ quản lý header gói tin vẫn chưa được cấu hình

• Tác vụ 3: Chuyền đổi mã nguồn OTcl trong file ~ns/tcl/lỉb/ns-packet.tcl để thiết lập danh sách các giao thức hoạt động

Như đã nói trong Mục 3.7, NS2 sẽ chuyển đổi mọi file kịch bản Tcl thành mã C++ trong tiến trình biên dịch Chương trình 8.15 đưa ra một phần của file ~ns/t cl/lib/ns -

Trang 40

- 170 -

packet.tcl có liên quan tới header gói tin ở đây dòng 8 gọi thủ tục headeríport} cho mọi header theo giao thức được xây ị dựng sẵn Trong dòng 12, thủ tục này thiết lập mọi phần tử của mảng liên kết

ađđ-packet-tab_ có chỉ số là tên header theo giao thức có giá trị bằng 1

Bước 2: Trong Pha Câu hình mạng

Nhiệm vụ chính của Pha cấu hình mạng liên quan tới việc khởi tạo header gói tin

là thiết lập các biến offset_ của mọi header theo giao thức đang hoạt động và thiết lập định dạng header của gói tin Trình tự các bước tạo gói tin sẽ theo định dạng gói tin được tạo ra trong bước này

Tiến trình cấu hình vị trí tương đối offset được đưa vào tiến trình xây dựng mô phỏng Từ dòng 2 trong Chương trình 4.11, hàm khởi tạo của bộ mô phỏng gọi thủ tục create_packetformat{} của lớp Simulator Thủ tục này được đưa ra trong Chương trình 8.16

Thủ tục create_packetformat{} tạo một đối tượng pm của lớp I PacketHeaderManager (dòng 3), tính toán giá trị vị trí tương đối của mọi header theo giao thức đang hoạt động bằng cách sử dụng thủ tục allochdricl} (dòng 6) và cấu hình

giá trị các biến offset của mọi header theo giao thức (dòng 7) Vòng lặp foeach trong dòng 4 chạy cho tất cả mọi header theo giao thức đã được xây dựng Các header theo

giao thức này đều là lớp con của lớp PacketHeader Sau đó dòng 5 lọc ra những header

theo giao thức nào chưa có trong danh sách các giao thức đang hoạt động (xem Mục 8.3.7) Các dòng 6-7 ; được thực hiện với mọi header theo giao thức đang hoạt động được

xác định ' qua biến tab_ của đối tượng “pm” của lớp PacketHeaderManager Dòng 7 cấu hình các giá trị vị trí tương đối bằng cách sử dụng phương thức offset trong OTcl (xem Chương trình 8.11) của các lớp ánh xạ Phương thức OTcl offset lưu đối số đầu vào trong biến *offset_ của lớp ánh xạ

Các dòng 12-19 trong Chương trinh 8.16 là mã nguồn OTcl và Hình 8.10 là sơ đồ hoạt động của thủ tục allochdr(cl) của lớp OTcl PacketHeaderManager Thủ tục này lấy một đối số đầu vào cccl‖ (trong dòng 12) là tên của header theo giao thức và trả về giá trị

vị trí tương đối tương ứng với đối số đầu vào (cl)Dòng 13 lưu kích thước của header theo giao thức ―cl‖ của lớp PacketHeader/Common) vào biến cục bộ size Trên cơ sở biến size các dòng 15-16 tính lượng bộ nhớ “ilcr ,, cần thiết để lưu trữ header tương ứng Dòng

17 lưu kích thước header gói tin hiện tại (chưa tính header theo giao thức) vào biến cục

bọ “base” Do “base” chính là khoảng cách theo độ lệch tương đối về vị trí từ vị trí bắt

đầu của header gói tin cho đến vị trí bắt đầu của header theo giao thức đầu vào, giá trị độ

lệch offset sẽ được trả lại trong dòng 19 Cuối dùng, dòng 18 tăng giả tri độ dài của

header lên thêm ―incr‖ đơn vị

Trong quá trình khởi tạo đối tượng Simulator, bộ quản lý header gói tin cũng cập nhật biến hdrlen_ (dòng 19 trong Chương trinh 8.16) Chú ý rằng biến hdrlen_ của lớp

Ngày đăng: 13/07/2021, 08:10

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
[1] Kavin Fall, Kannan Varadhan. ―The ns Manual‖. The VINT Project, A Collaboration between researchers at UC Berkeley, LBL, USC/ISI, and Xerox PARC.December 13, 2008. http://www.isi.edu/nsnam/ns/ Link
[5] Jae Chung and Mark Claypool. ―NS by example‖. http://www.nile.wpi.edu/ns Link
[2] Paul Meeneghan and Declan Delaney. ―An Introduction to NS, Nam and OTcl Scripting‖. National University of Ireland, Maynooth, Co. Kildare, Ireland DEPARTMENT OF COMPUTER SCIENCE. April 2009 Khác
[3] Enrique Campos-Nanez. ―Nscript Version 1.0a User‘s Manual‖. Department of Systems Engineering, University of Virginia. March 13, 2011 Khác
[4] Eitan Altman and Tania Jiménez. ―NS Simulator for beginers‖. Univ de Los Andes, Mérida, Venezuela and ESSI, Sophia-Antipolis, France. December 4, 2008 Khác
[6] Peng Zhang, Raimo Kantola, Zhansong Ma. ―Design and Implement of a new routing Simulator‖. Laboratory of Telecommunication Technology, Helsinki University of Technology, Findland Khác
[7] Xipeng Xiao and Linoel M. Ni. ―Internet QoS: A big Picture‖. Departurement of Computer Science, 3115 Engineering Building, Michigan State University Khác
[9] Carey Williamson. ―Internet Traffic Measurement‖. Department of Computer Science, University of Calgary. November 24, 2011 Khác

TỪ KHÓA LIÊN QUAN

w