基本原理
数据结构
链路感知
邻居侦听
MPR选择

基本原理:

网络中每个节点只选择自己邻居节点的一个子集,作为多点中继集MPR。根据MPR的节点产生链路状态信息。通过节点不断的选择自己的MPR或该节点作为其它节点MPR,对广播信息进行转发,最后根据新信息计算到达目的节点的最短路径。

比如:节点A向节点B发消息,节点A会选择自己的MPR节点,节点B也会选择自己的MPR节点,只有MPR节点会转发信息。


MPR节点具体的产生步骤:

比如节点A,在初始阶段,在他的一跳范围内,广播Hello消息,节点C收到这个消息,更新自己的本地链路信息表,即将节点A作为自己的邻居节点,并且标记C->A是非对称的。


然后,节点C在它的一跳范围内,广播Hello消息,这个Hello消息中包含着:节点A是他的邻居节点,并且C->A是非对称的,当节点A收到这个消息,更新自己的本地链路信息表,会在自己的邻居集中将节点C的状态更新为对称。


节点A再次广播Hello消息,此消息中包含,节点C是节点A的邻居节点,并且链路信息是对称的。

当节点C收到这个信息,在自己的邻居集中,将节点A的链路信息更新为对称。

总之,网络中的每个节点都要选择一部分自己的对称邻居节点作为通信的中继节点,即MPR节点。

数据结构:

每个分组封装了一一个或多个消息,这些消息共用一个消息头 OLSR使用同一的数据包格式,使用UDP进行通信。

OLSR路由协议头部的基本格式:

  • Packet length:包的字节长度
  • Packet sequence number 包的序列号,每产生一个新的数据包,序列号+1
  • Message type 消息类型:
  • 1 -> Hello
    
  •  2 -> topology control(TC)
    
  •  3 -> multiple interface declaration(MID)
    
  •  4 -> host and network association(HNA)
    
  • Vtime 节点接收消息后消息的有效时间
  • Message size 消息的字节长度,从消息类型开始到下一个消息类型结束。
  • Originator address 发送该节点的源地址,在传输的过程中保持不变
  • TTL 最大跳数,每转发一次,该值-1
  • Hop count 当前跳数
  • Message sequence number 消息的序列号
typedef struct OLSR_msg {u_int8_t    msg_type_;  ///< Message type.u_int8_t   vtime_;     ///< 有效时间.u_int16_t  msg_size_;  ///< 消息大小nsaddr_t    orig_addr_; ///< 发送此消息的源节点u_int8_t   ttl_;       ///生存时间,(最大跳数,每转发一次-1u_int8_t  hop_count_; ///消息跳数,(此消息在转发过程中经历的跳数)u_int16_t  msg_seq_num_;///消息序列号(唯一的)//union将所有字段重叠在内存中的相同偏移处,各字段共享一块内存//struct为每个字段在不同的偏移处分配内存空间union {OLSR_hello    hello_;OLSR_tc      tc_;OLSR_mid    mid_;} msg_body_;           ///< Message body.//在函数前加上inline关键字,成为内联函数,可以解决//频繁调用的函数大量消耗内存的问题//函数返回值为引用类型---》返回的是对象本身inline    u_int8_t&   msg_type()  { return msg_type_; }inline u_int8_t&   vtime()     { return vtime_; }inline    u_int16_t&  msg_size()  { return msg_size_; }inline nsaddr_t&   orig_addr() { return orig_addr_; }inline    u_int8_t&   ttl()       { return ttl_; }inline  u_int8_t&   hop_count() { return hop_count_; }inline    u_int16_t&  msg_seq_num()   { return msg_seq_num_; }inline  OLSR_hello& hello()     { return msg_body_.hello_; }inline  OLSR_tc&    tc()        { return msg_body_.tc_; }inline OLSR_mid&   mid()       { return msg_body_.mid_; }//分别计算每种类型的数据包大小inline u_int32_t size() {u_int32 += hello().size();else if (msg_type() == OLSR_TC_MSG)sz += tc().size();else if (msg_type() == OLSR_MID_MSG)sz += mid().size();return sz;}} OLSR_msg;

Hello消息基本格式:

HELLO消息用于建立一个节点的邻居表,其中包括邻居节点的地址以及本节点到邻居节点的延时和开销,OLSR采用周期性的广播HELLO分组来侦听邻居节点的状态和无线链路的对称性。节点之间无线链路的状态包括:非对称链路,对称链路,连接MPR的链路。但OLSR协议只关心对称链路,同时HELLO分组只在一跳的范围内广播,不能被转发。

  • Reserved:保留字段,设置为0000000000000
  • Htime: 发送hello分组的周期
  • Willingness: 表示节点为其他节点转发分组的愿意程度,如果一个节点的Willingness为WILL_NEVER,任何节点都不会选择该节点作为MPR.
  • Link Code: 标识了节点与其邻居节点之间的链路类型和邻居类型,链路的类型有:一般链路、非对称链路、对称链路和失效链路,邻居类型有:对称邻居、MPR邻居和非邻居;
  • (1) ASYM _ LINK:发送HELLO分组的节点与列表中的邻节点间的链路是非对称的。表示可以收到邻节点的消息,但不确定邻节点是否能收到本节点的消息
  • (2)SYM _LINK :发送HELLO分组的节点与列表中的邻节点间的链路是对称的。表示链路已经被验证为双向的。
  • (3)MPR_ LINK:表示列表中的节点已被发送该HELLO分组的节点选择为MPR 。
  • Link Message Size:链路信息的大小
  • Neighbor interface address:邻居节点的接口地址
typedef struct OLSR_hello {/// Reserved.设置为000000000u_int16_t    reserved_;/// 该节点发送hello分组的周期u_int8_t   htime_;/// 转发节点的意愿程度u_int8_t    willingness_;/// List of OLSR_hello_msg.OLSR_hello_msg  hello_body_[OLSR_MAX_HELLOS];//包含在hello_body中的OLSR_HELLO_msg消息的数量int        count;inline u_int16_t& reserved()      { return reserved_; }inline u_int8_t&   htime()         { return htime_; }inline u_int8_t&  willingness()       { return willingness_; }inline OLSR_hello_msg&  hello_msg(int i)    { return hello_body_[i]; }inline u_int32_t size() {u_int32_t sz = OLSR_HELLO_HDR_SIZE;for (int i = 0; i < count; i++)sz += hello_msg(i).size();return sz;}} OLSR_hello;typedef struct OLSR_hello_msg {/// 标识了节点与其邻居节点之间的链路类型和邻居类型u_int8_t  link_code_;/// Reserved.u_int8_t    reserved_;/// 链路信息的大小u_int16_t  link_msg_size_;/// 链路接口地址。OLSR_MAX_ADDRS是广播的最大地址数nsaddr_t   nb_iface_addrs_[OLSR_MAX_ADDRS];/// 当前接口地址数量.int        count;inline u_int8_t&  link_code()     { return link_code_; }inline u_int8_t&  reserved()      { return reserved_; }inline u_int16_t&  link_msg_size()     { return link_msg_size_; }inline nsaddr_t&  nb_iface_addr(int i)    { return nb_iface_addrs_[i]; }inline u_int32_t size() { return OLSR_HELLO_MSG_HDR_SIZE + count*ADDR_SIZE; }} OLSR_hello_msg;

TC分组格式:

在使用OLSR协议的网络中,每个节点都周期性发送TC分组。当一个节点接收到TC消息时,就进入拓扑信息维护模块。收到TC消息必要时进行转发(实现拓扑泛洪)﹔如果得到网络中一条有效的链路(拓扑),则将其添加到拓扑表中,用以计算路由。当检测到拓扑表发生变化时,就要转到路由建立与维护模块,重新计算路由。当收到数据包时,对其进行转发。

/// %OLSR TC message.
typedef struct OLSR_tc {/// 广播中的邻里序列号u_int16_t  ansn_;/// 保留位u_int16_t  reserved_;/// 邻居们的主要地址列表nsaddr_t    nb_main_addrs_[OLSR_MAX_ADDRS];/// 邻居节点主地址数量int     count;inline    u_int16_t&  ansn()          { return ansn_; }inline u_int16_t&  reserved()      { return reserved_; }inline nsaddr_t&   nb_main_addr(int i) { return nb_main_addrs_[i]; }inline u_int32_t size() { return OLSR_TC_HDR_SIZE + count*ADDR_SIZE; }} OLSR_tc;
  • ANSN(Advetised Neighbor Sequence Number):当节点发现其邻居节点集发生变化时,将TC分组中的ANSN加一,其他节点收到一个TC分组时,可以通过对ANSN的比较来确定该分组是否是较新的分组;
  • Reserved:这个域作为保留域,暂时没有使用;
  • Advertised Neighbor Main Address: MPR selector节点的主地址,发送TC分组的节点将所有的MPR selector主地址封装在TC分组中。

MID消息格式:

MID是Multiple Interface Declaration的简称,主要功能是实现协议中多重OLSR接口之间的通信。

typedef struct OLSR_mid {/// 接口地址列表nsaddr_t  iface_addrs_[OLSR_MAX_ADDRS];/// 接口地址的数量int     count;inline nsaddr_t&  iface_addr(int i)   { return iface_addrs_[i]; }inline u_int32_t size()          { return count*ADDR_SIZE; }} OLSR_mid;

HNA消息

HNA将OLSR的移动自组网接口与没有接口的OLSR自组网相连,HNA的结构如下图所示:

OLSR协议封装

Hello消息、TC分组、MID以及HNA都作为Message部分,OLSR协议封装如下:

链路感知:

目的:每个节点都要探测与其邻节点间的链路,所有链路必须双向验证才被认为是可用的。链路感知是通过HELLO分组的周期性交互实现的。本地链路信息表存储了该节点到邻居节点的链路信息。

节点发送HELLO分组时,本地链路信息表作为消息的内容

节点收到HELLO分组,更新本地链路信息表

OLSR 通过周期性地广播 HELLO 消息来进行邻节点探测,建立邻居表,一般检测两个节点之间链路状态的流程如下:

以 A 和 B 两个节点举例,想要检测它们之间链路的状态,需要进行以下几步:A 向 B 发送空的 HELLO 消息。(目的地址是广播地址)
B 接收到消息后,由于没有在消息中找到 B 自己的地址,所以将 A 设为非对称邻节点。
2秒后,B 向 A 发送携带 A 地址的 HELLO 消息。(源地址是B的地址,目的地址是A的地址)
A 接收到消息后,在消息中找到了自己的地址,所以将 B 定义为对称链路,接着再向 B 发送带有 B 地址的 HELLO 消息。
B 收到最新消息后,将 A 视为对称邻节点。

1、接收到一个HELLO分组,如果不存在如下的链路表项:

L_neighbor _iface _addr= =HELLO分组的originator address
建立一个新的表项如下:
L_ neighbor _ iface _ addr= =HELLO分组的originator address
L_local _ iface _ addr==接收HELLO分组的接口地址
L_sYM _TIME==当前时间-1(过期)
L_TIME==当前时间+有效时间

2、若存在前述的链路表项,则修改如下:

 L__ASYM _ TIME==当前时间+有效时间如果接收信息的接口地址在HELLO分组链路信息中,则修改如下:如果链路类型为LOST _LINK :L_SYM _TIME==当前时间-1(过期)如果链路类型为SYM _ LINK或ASYM _LINK :L_SYM _ TIME==当前时间+有效时间L_TIME==L_SYM _ TIME+ NEIGHB_ HOLD _TIMEL_TIME== MAX (L_TIME,L_ ASYM _TIME)
/// \brief   根据新收到的HELLO消息更新链接集
///
/// \param msg 包含HELLO消息的OLSR消息
/// \param receiver_iface 接收信息的接口的地址。
/// \param sender_iface 发送信息的接口的地址。
///链路感知
void OLSR::link_sensing(OLSR_msg& msg, nsaddr_t receiver_iface, nsaddr_t sender_iface) {OLSR_hello& hello   = msg.hello();double now       = CURRENT_TIME;bool updated        = false;//最初没有被更新bool created      = false;//没有被创建//OLSR_link_tuple是一个链接元组:本地地址和邻居地址,以及两者之间的状态OLSR_link_tuple* link_tuple = state_.find_link_tuple(sender_iface);//发送节点地址==一个节点的邻居节点,说明二者有关系,返回一个链接元组对象if (link_tuple == NULL) {// 之前没有链接,需要重新创建一个新的元组(第一次接触)link_tuple = new OLSR_link_tuple;link_tuple->nb_iface_addr()   = sender_iface;//发送信息的接口地址=该节点的邻居节点地址link_tuple->local_iface_addr()    = receiver_iface;//接收信息地址=本地节点地址link_tuple->sym_time()     = now - 1;//本地时间-1,(过期)link_tuple->lost_time()     = 0.0;link_tuple->time()        = now + OLSR::emf_to_seconds(msg.vtime());//当前时间+有效时间add_link_tuple(link_tuple, hello.willingness());//将链接元组插入到链接集中created = true;}else//已经有了链接(已经存在了链路表项)updated = true;link_tuple->asym_time() = now + OLSR::emf_to_seconds(msg.vtime());//当前时间+有效时间assert(hello.count >= 0 && hello.count <= OLSR_MAX_HELLOS);//验证hello.count的有效性for (int i = 0; i < hello.count; i++) {OLSR_hello_msg& hello_msg = hello.hello_msg(i);int lt = hello_msg.link_code() & 0x03;//计算链路状态int nt = hello_msg.link_code() >> 2;//计算链路状态// 我们决不能处理无效的广播链接if ((lt == OLSR_SYM_LINK && nt == OLSR_NOT_NEIGH) ||(nt != OLSR_SYM_NEIGH && nt != OLSR_MPR_NEIGH&& nt != OLSR_NOT_NEIGH))continue;assert(hello_msg.count >= 0 && hello_msg.count <= OLSR_MAX_ADDRS);//验证hello.count的有效性for (int j = 0; j < hello_msg.count; j++) {if (hello_msg.nb_iface_addr(j) == receiver_iface) {//接收信息的节点地址==一个节点的邻居节点的地址if (lt == OLSR_LOST_LINK) {//不存在链路(此路不通)link_tuple->sym_time() = now - 1;//(过期)updated = true;}else if (lt == OLSR_SYM_LINK || lt == OLSR_ASYM_LINK) {//如果链路状态为对称或者为非对称link_tuple->sym_time()    =now + OLSR::emf_to_seconds(msg.vtime());//当前时间+有效时间link_tuple->time()    =link_tuple->sym_time() + OLSR_NEIGHB_HOLD_TIME;link_tuple->lost_time() = 0.0;updated = true;}break;}}}link_tuple->time() = MAX(link_tuple->time(), link_tuple->asym_time());//有效时间通过消息头的Vtime实现if (updated)updated_link_tuple(link_tuple);//更新// 链路元组删除if (created && link_tuple != NULL) {OLSR_LinkTupleTimer* link_timer =new OLSR_LinkTupleTimer(this, link_tuple);link_timer->resched(DELAY(MIN(link_tuple->time(), link_tuple->sym_time())));}
}

邻居侦听:

目的:形成邻居信息库,邻居信息库与本地链路信息表有着紧密联系,节点每次收到HELLO消息之后,更新本地链路信息表,随后根据链路的改变,增添或者删减相邻节点。确保做到每一条链路都对应一个节点,每一个节点至少对应一条链路。

节点邻居侦听步骤如下:

  1. 如果分组的Originator Address是邻居集中一个邻居表项的N _neighbor _main addr ,则邻居集更新如下,N willingness更新为HELLO消息中的willingness 。

A给C发送Hello分组,分组的Originator Address=A的邻居集中的N _neighbor _main addr,说明A与C是邻居,则 N willingness更新为HELLO消息中的willingness

  1. 从一个对称邻居中接收到一个HELLO分组,节点应更新其两跳邻居集,如果链路集中的一个链路表项的L_neighbor _iface _addr是消息的Originator Address且L_SYM _TIME大于等于当前时间(即,HELLO源地址是一个对称邻节点),则两跳邻居集更新如下:

2.1 对HELLO消息中列出的每个具有SYM _ NEIGH 或MPR_ NEIGH 邻居类型的地址(即相对应于接收HELLO分组的节点的两跳邻居) :
1.如果两跳邻居的主地址等于接收节点的地址,丢弃这个两跳地址(即,节点不是自身的两跳邻节点)。

2.否则一个如下的两跳邻居表项生成:
N _ neighbor_ main_ addr =HELLO分组的originator address
N_ 2hop _ addr = HELLO分组相应邻居的地址,即接收HELLO分组节点的两跳邻居
N_time=当前时间+有效时间

3.对于HELLO消息中列出的每个具有NOT _ NEIGH邻居类型的两跳节点,如
下的两跳邻居表项必须被删除:
N _ neighbor_ main_ addr == HELLO分组的Originator Address
N _ 2hop_ addr == HELLO分组中相应的邻居地址

/// \brief   更新邻居集
/// \param msg
void OLSR::populate_nbset(OLSR_msg& msg) {OLSR_hello& hello = msg.hello();//nb_tuple是邻居元组对象,包括邻居节点的主节点,链路状态,意愿值OLSR_nb_tuple* nb_tuple = state_.find_nb_tuple(msg.orig_addr());if (nb_tuple != NULL)nb_tuple->willingness() = hello.willingness();
}
/// \brief 根据新收到的HELLO消息中包含的信息更新2跳邻居组。
/// \param msg 含有Hello消息的OLSR消息
void OLSR::populate_nb2hopset(OLSR_msg& msg) {double now        = CURRENT_TIME;OLSR_hello& hello   = msg.hello();for (linkset_t::iterator it_lt = linkset().begin(); it_lt != linkset().end(); it_lt++) {OLSR_link_tuple* link_tuple = *it_lt; //链接元组(主节点和邻居节点)if (get_main_addr(link_tuple->nb_iface_addr()) == msg.orig_addr()) {//如果链路集中的一个链路表项的//L_neighbor _ iface _addr是消息的Originator Addressif (link_tuple->sym_time() >= now) { //且 L_SYM _TIME大于等于当前时间(即,HELLO源地址是一个对称邻节点),//则两跳邻居集更新如下:assert(hello.count >= 0 && hello.count <= OLSR_MAX_HELLOS);for (int i = 0; i < hello.count; i++) {OLSR_hello_msg& hello_msg = hello.hello_msg(i);int nt = hello_msg.link_code() >> 2; //消息的链路状态assert(hello_msg.count >= 0 &&hello_msg.count <= OLSR_MAX_ADDRS);//OLSR_MAX_ADDRS是消息的广播地址数for (int j = 0; j < hello_msg.count; j++) {nsaddr_t nb2hop_addr = hello_msg.nb_iface_addr(j);if (nt == OLSR_SYM_NEIGH || nt == OLSR_MPR_NEIGH) {//对HELLO消息中列出的每个具有SYM _NEIGH//MPR_ NEIGH邻居类型的地址(即相对应于接收HELLO分组的节点的两跳邻居)∶//生成两跳邻居表项if (nb2hop_addr != ra_addr()) {// Otherwise, a 2-hop tuple is createdOLSR_nb2hop_tuple* nb2hop_tuple =state_.find_nb2hop_tuple(msg.orig_addr(), nb2hop_addr);if (nb2hop_tuple == NULL) {nb2hop_tuple =new OLSR_nb2hop_tuple;nb2hop_tuple->nb_main_addr() =msg.orig_addr();nb2hop_tuple->nb2hop_addr() =nb2hop_addr;add_nb2hop_tuple(nb2hop_tuple);nb2hop_tuple->time() =now + OLSR::emf_to_seconds(msg.vtime());// Schedules nb2hop tuple// deletionOLSR_Nb2hopTupleTimer* nb2hop_timer =new OLSR_Nb2hopTupleTimer(this, nb2hop_tuple);nb2hop_timer->resched(DELAY(nb2hop_tuple->time()));}//如果两跳邻居的主地址等于接收节点的地址,丢弃这个两跳地址(即,节点不是自身的两跳邻节点)。else {nb2hop_tuple->time() =now + OLSR::emf_to_seconds(msg.vtime());}}}else if (nt == OLSR_NOT_NEIGH) {//对于HELLO消息中列出的、邻居类型等于NOT_NEIGH的每个2跳节点,//所有2跳图元,其中。N_neighbor_main_addr == Originator Address //AND N_2hop_addr == main address of the 2-hop neighbor被删除。state_.erase_nb2hop_tuples(msg.orig_addr(),nb2hop_addr);}}}}}}
}

MPR选择:

计算MPR集:需要知道自身一跳和两跳邻居的信息。

OLSR 协议使用本地发送HELLO分组来获取一跳邻居信息。对于节点 i 的一跳邻居节点 j 而言,i 的一跳邻节点就是节点 j 的两跳邻节点。节点 i 发送HELLO分组的同时附上它自己的一跳邻居列表,当节点 j 收到节点 i 发送的HELLO分组时,就可以知道节点 i 的一跳邻节点的信息,对于节点 j 来说,就获得了节点 j 的两跳邻节点信息。

计算MPR集的要求是:节点与MPR节点之间必须是双向对称链路,节点所发送的分组通过MPR的中继,能够到达所有的严格两跳邻居节点。

//MPR节点的选择
//populate_mprselset这个函数是MPR节点的选择,这个函数在olsr类中定义
//以下部分是它的实现 OLSR_msg& msg是函数的引用
void OLSR::populate_mprselset(OLSR_msg& msg) {double now        = CURRENT_TIME; //从系统中获取当前时间OLSR_hello& hello  = msg.hello();//检验传入参数的合法性assert(hello.count >= 0 && hello.count <= OLSR_MAX_HELLOS);for (int i = 0; i < hello.count; i++) {OLSR_hello_msg& hello_msg = hello.hello_msg(i);int nt = hello_msg.link_code() >> 2;//右移两位if (nt == OLSR_MPR_NEIGH) {   //不对称邻居类型assert(hello_msg.count >= 0 && hello_msg.count <= OLSR_MAX_ADDRS);for (int j = 0; j < hello_msg.count; j++) {if (hello_msg.nb_iface_addr(j) == ra_addr()) {//ra_addr是路由代理的地址// 我们必须在mpr选择器集中创建一个新条目(链路感知部分)OLSR_mprsel_tuple* mprsel_tuple =state_.find_mprsel_tuple(msg.orig_addr());//如果不存在链路信息if (mprsel_tuple == NULL) {mprsel_tuple = new OLSR_mprsel_tuple;mprsel_tuple->main_addr() = msg.orig_addr();mprsel_tuple->time() =now + OLSR::emf_to_seconds(msg.vtime());add_mprsel_tuple(mprsel_tuple);// 计划删除mpr选择器元组OLSR_MprSelTupleTimer* mprsel_timer =new OLSR_MprSelTupleTimer(this, mprsel_tuple);mprsel_timer->resched(DELAY(mprsel_tuple->time()));}else//如果存在链路表项mprsel_tuple->time() =now + OLSR::emf_to_seconds(msg.vtime());}}}}
}

路由表计算:

在OLSR标准协议中,协议根据最小跳数建立每个节点的路由表。

任意一个节点路由表的添加过程可分为三部分:

  1. 首先,添加自己的邻节点进入路由表,即跳数h=1;
  2. 其次,添加自己的两跳邻节点进入路由表,即h=2;
  3. 最后,循环添加跳数等于h+1 (h=2开始)的节点进入路由表。

具体过程描述如下:
4. 首先清除现有路由表中的所有表项。
5. 将具有对称链路的邻居作为目的地址,一个如下的新的表项加入路由表:

R_ dest_ addr ==邻节点地址
R_ next _ addr ==邻节点地址
R _ dist==1
R _ iface_ addr ==本地地址

6.对于任意两跳邻居,其两跳邻居集中必然存在着这样一个表项:
N _ neighbor_ main_ addr 等于本地的一个一跳邻居且其willingness 不为WILL_ NEVER 。则将每个两跳邻居加入路由表如下

R_ dest _ addr ==两跳邻居地址
R_ next _ addr==已有的具有如下特征的路由表表项的R_ next_ addr :其R_ dest_ addr 为该两跳邻居表项的N _ neighbor_ main_ addr
R_ dist==2
R_iface _ addr ==已有的具有如下特征的路由表表项的R_ iface_ addr :其R_ dest_ addr 为该两跳邻居表项的N _ neighbor_ main_ addr





OLSR协议详解(1)相关推荐

  1. HTTP协议详解(真的很经典)

    转自:http://blog.csdn.net/gueter/archive/2007/03/08/1524447.aspx Author :Jeffrey 引言 HTTP是一个属于应用层的面向对象的 ...

  2. Http 协议详解笔记

    HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1.0的第 ...

  3. Http协议 详解(转载)

    http://blog.csdn.net/gueter/archive/2007/03/08/1524447.aspx 引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分 ...

  4. ARP协议详解之ARP动态与静态条目的生命周期

    ARP协议详解之ARP动态与静态条目的生命周期 ARP动态条目的生命周期 动态条目随时间推移自动添加和删除. q  每个动态ARP缓存条目默认的生命周期是两分钟.当超过两分钟,该条目会被删掉.所以,生 ...

  5. ARP缓存表的构成ARP协议全面实战协议详解、攻击与防御

    ARP缓存表的构成ARP协议全面实战协议详解.攻击与防御 1.4.3  ARP缓存表的构成 在局域网的任何一台主机中,都有一个ARP缓存表.该缓存表中保存中多个ARP条目.每个ARP条目都是由一个IP ...

  6. HTTP协议详解 转自小坦克

    HTTP协议详解 转自小坦克 -- 有些文章是引用别人的,为了方便我以后或不再备注;引用目的是因为直接网摘里面的地址经常被重置,找不到原来的文章 当今web程序的开发技术真是百家争鸣,ASP.NET, ...

  7. nbns协议_网络协议详解1 - NBNS

    NetBIOS 简介 NetBIOS,Network Basic Input/Output System的缩写,一般指用于局域网通信的一套API,相关RFC文档包括 RFC 1001, RFC 100 ...

  8. 转:SSL 握手协议详解

    SSL 握手协议详解 RSA作为身份认证,ECDHE来交换加密密钥,AES/DES等作为加密. 如果RSA来加解密,那么身份认证后,直接用认证后的RSA公钥解密.不需要再额外交换加密密钥了. 相关报文 ...

  9. 【HTTP协议】超详细的HTTP协议详解

    基本介绍 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/ ...

最新文章

  1. 字体设置_word字体设置:如何为常用字体设置快捷键
  2. hibernate的异常 Session was already closed
  3. PHP变参函数的实现
  4. QNX设置开机启动命令来修改IP地址
  5. openstack 调试
  6. Firewalld,iptables概述(netfilter和Firewalld,iptables三者之间的关系,四表五链,Firewalld防火墙的配置方发,SNAT,DNAT了解)
  7. python 连续三个数满足条件_计算满足条件的连续值数(Pandas Dataframe)
  8. java.util.concurrent.TimeUnit
  9. html2canvas图片坐标,html2canvas生成的图片偏移不完整的解决方法
  10. cartographer源码编译测试之开发环境搭建全在这里了
  11. 【ZooKeeper Notes 6】客户端对zookeeper的操作是不可回退的 [OK]
  12. rhce考试试题以及答案_RedHat红帽认证 RHCE 7.0题库和答案
  13. SXF终端检测平台 EDR漏洞复现
  14. 英飞凌基础学习笔记AURIX内核系统架构
  15. 2013总结之“酒肉穿肠过,佛在心中坐”
  16. 计算机win10搜不到wifi,Windows10笔记本找不到无线网络如何处理
  17. ORACLE常用工具介绍
  18. NLP入门从入门到实战 实体命名识别 +中文预处理之繁简体转换及获取拼音
  19. 免费天气api 真正可用
  20. 如何强制关闭mac后台程序

热门文章

  1. 各种投资产品的整理分析(持续更新)
  2. 《Linux/UNIX OpenLDAP实战指南》——2.4 OpenLDAP配置
  3. 新能车卡位生变,蔚来“咸鱼翻身”,能否守住销量王冠?
  4. 应广单片机休眠和按键唤醒
  5. solr 集成web项目后 执行查询时报错Error from server at http://localhost:8080/solr/collection1
  6. 如何做到卓有成效的敏捷?
  7. 交叉编译SPECCPU2006
  8. 当当网年中图书大促来了,全年买书最好时机
  9. OCR识别:纸币(人民币)号码识别
  10. 完美解决 Evernote / 印象笔记 的同步失败问题