Hoàng Đăng Hải Học Viên: Lê Đăng Phong [1-22] Vũ Anh Tuấn



tải về 0.59 Mb.
trang19/19
Chuyển đổi dữ liệu13.08.2016
Kích0.59 Mb.
#17954
1   ...   11   12   13   14   15   16   17   18   19

10.2. Lớp định thời trong OTcl


Một lớp định thời đơn giản được định nghĩa trong ~ns/tcl/mcast/timer.tcl. Các lớp con của của Timer có thể được định nghĩa nếu cần. Không như các hàm API định thời trong C++ (hàm sched() bị bỏ qua nếu bộ định thời đã được thiết lập), các hàm sched() và resched() là như nhau; có nghĩa là trạng thái của các bộ định thời OTcl không được giữ. Trong lớp cơ sở Timer, có định nghĩa các phương thức sau đây:

$self sched $delay ;# causes "$self timeout" to be called $delay seconds in the future

$self resched $delay ;# same as "$self sched $delay"

$self cancel ;# cancels any pending scheduled callback

$self destroy ;# same as "$self cancel"

$self expire ;# calls "$self timeout" immediately


10.3. Một số lệnh cơ bản


$timer sched

$timer resched

$timer cancel

$timer destroy

$timer expire

11. Header gói và các định dạng


Các thủ tục và hàm mô tả trong chương này có thể tìm trong ~ns/tcl/lib/ns-lib.tcl, ~ns/tcl/lib/ns-packet.tcl và ~ns/packet.{cc, h}.

Các đối tượng trong lớp Packet là đơn vị cơ bản của việc chuyển đổi giữa các đối tượng khi mô phỏng. Lớp Packet cung cấp thông tin để liên kết một gói vào danh mục (có nghĩa là, trong một PacketQueue hoặc một danh mục gói trống), tham chiếu đến một bộ đệm chứa các header gói được định nghĩa trên cơ sở mỗi giao thức và để tham chiếu đến bộ đệm của dữ liệu gói. Các giao thức mới cps thể định nghĩa các header gói của chính nó hoặc có thể mở rộng các header hiện có bằng các trường bổ sung.

Các header gói mới được đưa vào bộ mô phỏng bằng cách định nghĩa một cấu trúc C++ có các trường cần thiết, định nghĩa một lớp tĩnh để tạo liên kết OTcl và sau đó thay đổi một số mã khởi tạo bộ mô phỏng để ấn định một byte offset trong mỗi gói ở nơi mà header mới dự định được đặt.

Khi bộ mô phỏng được khởi tạo nhờ OTcl, người dùng có thể chọn chỉ cho phép một tập con của các định dạng gói, như thế sẽ tiết kiệm được bộ nhớ khi thực hiện mô phỏng. Hiện nay, hầu hết các định dạng gói đều được cho phép. Việc quản lý các định dạng gói được cho phép trong bộ mô phỏng được điều khiển bằng một đối tượng quản lý headẻ gói đặc biệt như mô tả dưới đây. Đối tượng này hỗ trợ một phương thức OTcl được sử dụng để quy định các header gói được dùng trong khi mô phỏng. Nếu một đối tượng trong bộ mô phỏng sử dụng một trường trong 1 header không được cho phép, thì chương trình sẽ ngừng lại.


11.1. Header gói cho một giao thức cụ thể


Các nhà phát triển giao thức thường muốn tạo một kiểu header để sử dụng trong các gói. Điều đó cho phép thực hiện một giao thức mới mà không chồng chéo lên các trường header đã có. Ta xem xét bản đơn giản của giao thức RTP. Header RTP yêu cầu các trường số thứ tự và một trường định danh nguồn. Các lớp sau đây tạo ra header cần thiết (xem trong ~ns/rtp.h và ~ns/rtp.cc):

Trong file rtp.h:

/* rtp packet. For now, just have srcid + seqno. */

struct hdr_rtp {

u_int32_t srcid_;

int seqno_;

/* per-field member functions */

u_int32_t& srcid() { return (srcid_); }

int& seqno() { return (seqno_); }

/* Packet header access functions */

static int offset_;

inline static int& offset() { return offset_; }

inline static hdr_rtp* access(const Packet* p) {

return (hdr_rtp*) p->access(offset_);

}

};

Trong file rtp.cc:



class RTPHeaderClass : public PacketHeaderClass {

public:


RTPHeaderClass() : PacketHeaderClass("PacketHeader/RTP",

sizeof(hdr_rtp)) {

bind_offset(&hdr_rtp::offset_);

}

} class_rtphdr;



void RTPAgent::sendpkt()

{

Packet* p = allocpkt();



hdr_rtp *rh = hdr_rtp::access(p);

lastpkttime_ = Scheduler::instance().clock();

/* Fill in srcid_ and seqno */

rh->seqno() = seqno_++;

rh->srcid() = session_->srcid();

target_->recv(p, 0);

}

RTPAgent::RTPAgent()



: session_(0), lastpkttime_(-1e6)

{

type_ = PT_RTP;



bind("seqno_", &seqno_);

}

Cáu trúc đầu tiên, hdr_rtp, định nghĩa cách bố trí header gói của RTP (về khái niệm và chỗ đứng của nó): các trường cần thiết và kích thước của chúng. Định nghĩa cấu trúc này chỉ được trình biên dịch sử dụng để tính byte offset của trường; không có các đối tượng của cấu trúc này được định vị trực tiếp. Cấu trúc này cũng tạo ra các hàm bộ phận để tạo ra một lớp che dấu các các dữ liệu đối với các đối tượng muốn độc hoặc thay đổi trường header của các gói. Chú ý rằng các biến lớp tĩnh offset_ được dùng để tìm các byte offset tại đó header rtp được đặt trong một nspacket. Có 2 phương thức sử dụng biến này để truy nhập header này trong gói bất kỳ: offset() và access(). Phương thức trước được hầu hết người dùng lựa chọn để truy nhập header cụ thể này trong một gói; phương thức sau được sử dụng bởi lớp quản lý header gói nhưng cũng ít khi dùng. Ví dụ, để truy nhập header gói RTP trong một gói được trỏ bởi p, ta chỉ cần sử dụng hdr_rtp::access(p). Liên kết thực của offset_ đến vị trí của header này trong gói được thực hiện trong ~ns/tcl/lib/ns-packet.tcl và ~ns/packet.cc. Hằng số trong lệnh access() tạo một truy nhập read-only đến hằng Packet, mặc dù thuộc tính read-only bị bắt buộc do con trỏ trả về không phải là hằng số. Một cách chính xác để làm điều này là tạo ra 2 phương thức, một phương thức để truy nhập ghi, một phương thức để truy nhập read-only. Tuy nhiên, hiện nay chưa thực hiện điều này.



Đối tượng tĩnh class_rtphdr của lớp RTPHeaderClass được dùng để liên kết đến OTcl khi header RTP được cho phép tại thời điểm cấu hình. Khi bộ mô phỏng chạy, đối tượng tĩnh này gọi hàm khởi tạo PacketHeaderClass với lệnh "PacketHeader/RTP" và sizeof(hdr_rtp). Như vậy, kích thước của header RTP được lưu lại và sẵn sàng phục vụ đối tượng quản lý header gói tại thời điểm cấu hình (xem Section 12.2.4). Chú ý rằng bind_offset() phải được gọi trong hàm khởi tạo của lớp này, như vậy đối tượng quản lý header gói biết được nơi lưu giữ offset của header gói này.

Phương thức sendpkt() của hàm bộ phận ví dụ của RTPAgent tạo ra một gói mới để gửi đi bằng cách gọi allocpkt(), nó điều khiển việc ấn định tất cả các trường header gói lớp mạng (trong trường hợp này là IP). Các header khác ngoài IP được điều khiển riêng. Trong trường hợp này, agent sử dụng RTPHeader như đã định nghĩa ở trên. Hàm bộ phận Packet::access(void) trả về địa chỉ của byte đầu tiên trong bộ đệm được dùng để mang thông tin header. Giá trị trả về của nó là con trỏ đến header quan tâm, sau đó sử dụng hàm bộ phận của đối tượng RTPHeader để truy nhập các trường riêng.


11.1.1. Thêm một kiểu header gói mới


Giả thiết ta muốn tạo một header mới là newhdr, thực hiện các bước sau đây:

1. tạo một cấu trúc mới định nghĩa các trường (gọi là hdr_newhdr), định nghĩa offset_ và các phương thức truy nhập.

2. định nghĩa các hàm bộ phận cho các trường cần thiết.

3. tạo một lớp tính để thực hiện liên kết với OTcl (định nghĩa PacketHeader/Newhdr), thực hiện bind_offset() trong hàm khởi tạo của nó.

4. sửa ~ns/tcl/lib/ns-packet.tcl để cho phép định dạng gói mới (xem 12.2.2, 12.2.4).

11.1.2. Lựa chọn các header gói trong bộ mô phỏng


Mặc định ns bao gồm tất cả các header gói của tất cả các giao thức trong ns ở tất cả các gói trong bộ mô phỏng. Như vậy có rất nhiều overhead, và nó sẽ tăng theo số giao thức được thêm vào ns. Với các mô phỏng “gói nhạy cảm”, overhead sẽ rất lớn. Ví dụ, hiện nay (2000), kích thước headẻ gói của tất cả các giao thức trong ns khoảng 1,9 Kb; tuy nhiên, nếu bạn chỉ dùng heder gói chung, header IP và header TCP thì chỉ mất vào khoảng 100 Bytes. Nếu bạn thực hiện mô phỏng lưu lượng web cỡ lớn có nhiều đường dẫn lớn thì việc giảm header gói không sử dụng sẽ giảm được phần lớn bộ nhớ.

Để tính header gói ta quan tâm trong mô phỏng, ta làm như sau (ví dụ bạn muốn loại các header AODV và ARP khỏi mô phỏng):

remove-packet-header AODV ARP

......


set ns [new Simulator]

Chú ý rằng remove-packet-header phải được thực hiện trước khi bộ mô phỏn được tạo ra. Tất cả các tên header gói nằm trong PacketHeader/[hdr]. Bạn chỉ cần cung cấp phần [hdr]. Để tìm tên của các header gói, bạn có thể xem trong ~ns/tcl/lib/ns-packet.tcl, hoặc chạy lệnh sau trong ns:

foreach cl [PacketHeader info subclass] {

puts $cl


}

Để tính một tập hợp các header trong mô phỏng, ví dụ IP và TCP, làm như sau:

remove-all-packet-headers

add-packet-header IP TCP

......

set ns [new Simulator]



Quang trọng: Bạn không bao giờ được loại header chung khỏi mô phỏng. Bạn có thể thấy trong ~ns/tcl/lib/ns-packet.tcl.

11.2. Các lớp gói


Có 4 lớp gói C++ tương ứng để điều khiển gói và các header gói: Packet, p_info PacketHeader và PacketHeaderManager. Lớp Packet định nghĩa kiểu của tất cả các gói trong mô phỏng; nó là một lớp con của Event nên các gói có thể được định trình (ví dụ để đến sau vài hàng). Lớp packet_info giữ tất cả các biểu diễn văn bản cho tên gói. Lớp PacketHeader cung cấp một lớp cơ sở cho header gói bất kỳ được cấu hình cho mô phỏng. Nó cung cấp trạng thái nội cần thiết để định vị header gói bất kỳ trong tập hợp header gói. Lớp PacketHeaderManager định nghĩa một lớp được dùng để thu thập và quản lý các gói đã được cấu hình. Nó được gọi bằng một phương thức OTcl tại thời điểm cấu hình mô phỏng để cho phép một tập con của header gói đã biên dịch.

11.2.1. Lớp Packet


Lớp Packet định nghĩa cấu trúc của gói và cung cấp hàm bộ phận để điều khiển danh sách đối tượng trống. Nó được định nghĩa trong packet.h như sau:

class Packet : public Event {

private:

friend class PacketQueue;

u_char* bits_;

u_char* data_; /* variable size buffer for ’data’ */

u_int datalen_; /* length of variable size buffer */

protected:

static Packet* free_;

public:


Packet* next_; /* for queues and the free list */

static int hdrlen_;

Packet() : bits_(0), datalen_(0), next_(0) {}

u_char* const bits() { return (bits_); }

Packet* copy() const;

static Packet* alloc();

static Packet* alloc(int);

inline void allocdata(int);

static void free(Packet*);

inline u_char* access(int off) {

if (off < 0)

abort();


return (&bits_[off]);

}

inline u_char* accessdata() { return data_; }



};

Lớp này giữ một con trỏ đến một mảng ký tự chưa được đánh dấu (thường được gọi là “túi bit” hoặc BOB) tại đó lưu các trường header gói. Nó cũng giữ một con trỏ tới gói “dữ liệu” (thường không được sử dụng trong mô phỏng). Biến bits_ chứa địa chỉ của byte đầu tiên của BOB. BOB là một dãy gồm tất cả các cấu trúc được định nghĩa cho từng header gói (theo thoả thuận, các cấu trúc có tên bắt đầu bằng hdr_) đã được cấu hình. BOB thường có kích thước xác định trong toàn bộ mô phỏng và kích thước này được ghi trong một biến bộ phận Packet::hdrlen_. Thích thước này được cập nhật khi cấu hình bộ mô phỏng bằng OTcl.

Các phương thức khác của lớp Packet dùng để tạo ra các gói mới và lưu trữ các gói cũ (không sử dụng) trong một danh sách riêng. Việc định vị và giải toả được thực hiện bằng đoạn mã sau (trong ~ns/packet.h):

inline Packet* Packet::alloc()

{

Packet* p = free_;



if (p != 0)

free_ = p->next_;

else {

p = new Packet;



p->bits_ = new u_char[hdrsize_];

if (p == 0 || p->bits_ == 0)

abort();

}

return (p);



}

/* allocate a packet with an n byte data buffer */

inline Packet* Packet::alloc(int n)

{

Packet* p = alloc();



if (n > 0)

p->allocdata(n);

return (p);

}

/* allocate an n byte data buffer to an existing packet */



inline void Packet::allocdata(int n)

{

datalen_ = n;



data_ = new u_char[n];

if (data_ == 0)

abort();

}

inline void Packet::free(Packet* p)



{

p->next_ = free_;

free_ = p;

if (p->datalen_) {

delete p->data_;

p->datalen_ = 0;

}

}

inline Packet* Packet::copy() const



{

Packet* p = alloc();

memcpy(p->bits(), bits_, hdrlen_);

if (datalen_) {

p->datalen_ = datalen_;

p->data_ = new u_char[datalen_];

memcpy(p->data_, data_, datalen_);

}

return (p);



}

Phương thức alloc() là một hàm hỗ trợ được dùng để tạo các gói mới. Nó được gọi bằng phương thức Agent::allocpkt() thay mặt cho agent và như vậy nó không được các đối tượng gọi trực tiếp. Đầu tiên nó cố gắng định vị một gói cũ vào danh sách trống và nếu không được nó định vị một gói mới bằng toán tử new trong C++. Chú ý rằng các đối tượng lớp Packet và các BOB được định vị riêng rẽ. Phương thức free() giải phóng gói bằng cách chuyển nó vào danh sách trống. Chú ý rằng các gói không được trả lại cho bộ cấp phát nhớ của hệ thống. Thay vào đó, chúng được lưu trên một danh sách trống khi Packet::free() được gọi. Hàm bộ phận copy() tạo ra một bản mới của gói với khác biệt trường uid_. Hàm này được dùng bởi các đối tượng Replicator để hỗ trợ phân tán đa lường và các mạng LAN.


11.2.2. Lớp p_info


Lớp này được gọi là “keo dán” dùng để kết nôốicác giaátrị kiểu gói dạng số với tên tượng trưng của chúng. Khi một kiểu gói mới được định nghĩa, mã dạng số của nó cần đuợc thêm vào bảng packet_t (xem ~ns/packet.h) và tên tượng trưng của nó cần được thêm bào hàm khởi tạo của p_info:

enum packet_t {

PT_TCP,

...


PT_NTYPE // This MUST be the LAST one

};

class p_info



public:

p_info() {

name_[PT_TCP]= "tcp";

...


}

}

11.2.3. Lớp hdr_cmn


Các gói trong mô phỏng có một header chung được định nghĩa trong ~ns/packet.h như sau:

struct hdr_cmn {

double ts_; /* timestamp: for q-delay measurement */

packet_t ptype_; /* packet type (see above) */

int uid_; /* unique id */

int size_; /* simulated packet size */

int iface_; /* receiving interface (label) */

/* Packet header access functions */

static int offset_;

inline static int& offset() { return offset_; }

inline static hdr_cmn* access(Packet* p) {

return (hdr_cmn*) p->access(offset_);

}

/* per-field member functions */



int& ptype() { return (ptype_); }

int& uid() { return (uid_); }

int& size() { return (size_); }

int& iface() { return (iface_); }

double& timestamp() { return (ts_); }

};

Cấu trúc này định nghĩa các trường được dùng để ghi lại dòng gói hoặc đo các đại lượng khác. Trường dấu thời gian được dùng để đo trễ hàng đợi tại một nút chuyển mạch. Trường ptype_ được dùng để định danh kiểu gói. Trường uid_ được dùng bởi bộ định trình để định trình thời gian gói đến. Trường size_ được sử dụng chung, cung cấp kích thước của gói tính bằng byte. Chú ý rằng một số byte trong mô phỏng có thể không liên quan đến giá trị của trường (có nghĩa là size_ không có mối quan hệ với sizeof(struct hdr_cmn) hoặc các cấu trúc khác của ns). Hơn nữa, nó thường được dùng để tính thời gian chuyển gói trên mạng.


11.2.4. Lớp PacketHeaderManager


Một đối tượng của lớp PacketHeaderManager được dùng để quản lý tập hợp các kiểu header gói và ấn định cho chúng một offset duy nhất trong BOB. Nó được định nghĩa bằng cả C++ và OTcl:

Từ file tcl/lib/ns-packet.tcl:

PacketHeaderManager set hdrlen_ 0

......


foreach prot {

AODV


ARP

aSRM


Common

CtrMcast


Diffusion

......


TORA

UMP


} {

add-packet-header $prot

}

Simulator instproc create_packetformat {} {



PacketHeaderManager instvar tab_

set pm [new PacketHeaderManager]

foreach cl [PacketHeader info subclass] {

if [info exists tab_($cl)] {

set off [$pm allochdr $cl]

$cl offset $off

}

}

$self set packetManager_ $pm



}

PacketHeaderManager instproc allochdr cl {

set size [$cl set hdrlen_]

$self instvar hdrlen_

set NS_ALIGN 8 ;# round up to nearest NS_ALIGN bytes, (needed on sparc/solaris)

set incr [expr ($size + ($NS_ALIGN-1)) & ~($NS_ALIGN-1)]

set base $hdrlen_

incr hdrlen_ $incr

return $base

}

Từ file packet.cc:



/* manages active packet header types */

class PacketHeaderManager : public TclObject {

public:

PacketHeaderManager() {



bind("hdrlen_", &Packet::hdrlen_);

}

};



Đoạn mã trong ~ns/tcl/lib/ns-packet.tcl được thực hiện khi khởi tạo bộ mô phỏng. Như vậy, câu lệnh này được thực hiện trước khi mô phỏng bắt đầu và khởi tạo mảng lớp OTcl tab_ để chứa ánh xạ giữa lớp tên và tên của các lớp header gói hiện hành. Như đã trình bày trong 12.1, header gói có thể truy nhập bằng cách sử dụng hdr_> hdrname? ::access().

Thủ tục create_packetformat{} là một phần của lớp cơ bản Simulator và được gọi một lần khi cấu hình bộ mô phỏng. Đầu tiên nó tạo đối tượng PacketHeaderManager. Hàm khởi tạo trong C++ liên kết biến OTcl hdrlen_ (của lớp PacketHeaderManager) vào biến C++ Packet::hdrlen_ (một bộ phận tĩnh của lớp Packet).

Sau khi tạo đối tượng quản lý gói, vòng lệnh cho phép các header gói quan tâm. Vòng lặp này lặp lại danh mục các header gói được định nghĩa ở dạng @)ACBED_F1BHG trong đó ACB là tên của header thứ I và F1B là tên của biến chứa vị trí của header AJB trong BOB. Việc đặt các header được thực hiện bởi thủ tục allochdr của lớp PacketHeaderManager trong OTcl. Thủ tục này giữ biến chạy hdrlen_ và chiều dài hiện thời của BOB khi các header gói mới được cho phép. Nó cũng sắp xếp các khoảng 8-byte cho các header gói mới được cho phép. Điều này rất cần để đảm bảo rằng khi sử dụng đại lượng có chiều dài 2-word và cần sắp xếp các khoảng 2-word thì sẽ không bị lỗi khi truy nhập.

11.3. Các lệnh cơ bản


Sau đây là danh mục các thủ tục liên quan đến header gói:

Simulator::create_packetformat



PacketHeaderManager::allochdr




Каталог: Hoc%20Tap -> Cong%20Nghe%20Wan
Hoc%20Tap -> Point to Point Protocol (ppp) ppp được xây dựng dựa trên nền tảng giao thức điều khiển truyền dữ liệu lớp cao (High-Level Data link Control (hdlc)) nó định ra các chuẩn cho việc truyền dữ liệu các giao diện dte và dce của mạng wan như V
Hoc%20Tap -> Cấu hình Application Port-Mapping với cbac mục tiêu: Cấu hình để router nhận ra các ứng dụng không sử dụng port chuẩn. Mô hình
Hoc%20Tap -> ĐẢng cộng sản việt nam đẢng ủy phưỜng 04
Hoc%20Tap -> CiR = Bc / Tc
Hoc%20Tap -> Mean command : ip ospf mtu-ignore Diagram : Problems
Hoc%20Tap -> R1# ip route 0 0 0 0 FastEthernet0/0 R2# show run
Cong%20Nghe%20Wan -> Câu hỏi về kết nối chi nhánh về Head Office dùng wan
Cong%20Nghe%20Wan -> 1/ Cáp đồng gshdsl
Cong%20Nghe%20Wan -> 1. xu hưỚng chuẩn hoá VÀ CẤu trúc giao thứC

tải về 0.59 Mb.

Chia sẻ với bạn bè của bạn:
1   ...   11   12   13   14   15   16   17   18   19




Cơ sở dữ liệu được bảo vệ bởi bản quyền ©hocday.com 2024
được sử dụng cho việc quản lý

    Quê hương