4.3.2 使用子网时的分组转发

  • 划分子网后路由表 必须包含以下 三项内容
    目的网络地址子网掩码下一跳地址(形式是ip地址)
    在这里插入图片描述

  • 划分子网后,路由器转发分组的算法发生变化
    1、从收到的数据报的首部提取目的ip地址 D
    2、判断是否为直接交付,对当前路由器直接相连的网络逐个进行检查:
    各网络的子网掩码D 逐位相与,判断结果是否和相应的网络地址匹配:
    若匹配,则把分组进行直接交付,将D通过ARP转成mac地址,封装成mac帧发送出去
    否则就是间接交付,执行3
    3、若路由表中有 目的地址为D的特定主机路由 ,则把数据报传送给路由表所指明的下一跳路由器
    默认路由、主机路由、网络路由 概念
    否则执行4
    4、对路由表中的 每一行(目的网络地址,子网掩码,下一跳地址) ,用其中的 子网掩码目的ip地址 D 逐位相与,结果为N
    若N与该行的目的网络地址匹配,则把数据报传送给该行指明的下一跳路由器
    否则,执行5
    5、若路由表中有一个 默认路由,则把数据报传送给路由表中所指明的默认路由器
    否则,执行6
    6、报告转发分组出错
    (如何查看本机路由表并进行分析)

  • 示例
    在这里插入图片描述
    源主机H1向目的主机H2发送的分组,目的地址是H2的ip地址 128.30.33.138
    1、H1首先判断:是在本子网上直接交付,还是要通过本子网上的路由器间接交付:
    H1把本子网的 子网掩码 255.255.255.128 与 目的主机H2ip地址 128.30.33.138 按位与,结果是 128.30.33.128,不等于H1所在的网络地址 128.30.33.0,这说明 H2 和 H1 不在一个子网上,H1 不能把分组直接交付 H2,而必须要交给子网上的默认路由器R1,由 R1 来转发
    2、路由器 R1 收到一个分组后,就在其路由表中逐行寻找有无匹配的网络地址
    分组目的ip地址 分别与 每行的子网掩码 相与,再与 目的ip地址(此时是子网地址) 相比,发现第二行匹配,说明 目的网络接口1 相连,因此 R1将数据直接交付主机H2

  • 注意此时路由表中的目的网络地址可以是子网地址
    分组从路由器的某一个接口出发:
    可以是直接交付该接口所连网络上的 某个主机
    也可以是间接交付给该接口所连网络上的 某个路由器,去往另一个网络。

  • 同一个网络中的主机可以直接通信,这属于直接交付。
    不同网络中的主机不能直接通信,需要路由器的中转,这属于间接交付。

  • 转发表路由表的区别?
    1、路由表:其中包含三元素:目标地址,掩码,下一跳 ,重点是从 目的网络下一跳(用ip地址来表示) 的映射。
    负责对 网络拓补结构变化 的计算最优化。
    路由表总是用软件来实现。
    2、转发表:从 路由表 得出的。
    必须包含完成转发功能所必需的信息,转发表的每一行必须包含从 目的网络输出端口 和 某些mac地址信息(如下一跳的以太网地址) 的映射,转发表应当使查找过程最优化,转发表可以用 软件 也可以使用 特殊的硬件 来实现。

  • windows下查看本机路由表 route print

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用libwebsockets-4.3.2写的C++ Websockets服务端的示例代码: ```c++ #include <libwebsockets.h> #include <iostream> #include <string> using namespace std; struct WebsocketServerData { int counter; }; static int callback_websockets(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { WebsocketServerData *server_data = (WebsocketServerData*)lws_context_user(lws_get_context(wsi)); switch (reason) { case LWS_CALLBACK_ESTABLISHED: cout << "Websocket client connection established" << endl; break; case LWS_CALLBACK_SERVER_WRITEABLE: { string message = "Hello, World! " + to_string(server_data->counter); unsigned char *buffer = new unsigned char[LWS_SEND_BUFFER_PRE_PADDING + message.length() + LWS_SEND_BUFFER_POST_PADDING]; memcpy(buffer + LWS_SEND_BUFFER_PRE_PADDING, message.c_str(), message.length()); lws_write(wsi, buffer + LWS_SEND_BUFFER_PRE_PADDING, message.length(), LWS_WRITE_TEXT); delete[] buffer; server_data->counter++; } break; case LWS_CALLBACK_RECEIVE: cout << "Received message from client: " << string((char*)in, len) << endl; lws_callback_on_writable_all_protocol(lws_get_context(wsi), lws_get_protocol(wsi)); break; case LWS_CALLBACK_CLOSED: cout << "Websocket connection closed" << endl; break; default: break; } return 0; } int main(int argc, char **argv) { struct lws_context_creation_info context_info; struct lws_protocols protocols[] = { { "websockets", callback_websockets, sizeof(WebsocketServerData), 0 }, { NULL, NULL, 0, 0 } }; WebsocketServerData server_data = { 0 }; int port = 8080; int exit_code = 0; memset(&context_info, 0, sizeof(context_info)); context_info.port = port; context_info.protocols = protocols; context_info.user = &server_data; struct lws_context *context = lws_create_context(&context_info); if (!context) { cerr << "Failed to create libwebsocket context" << endl; exit_code = 1; goto cleanup; } while (true) { lws_service(context, 50); } cleanup: if (context) { lws_context_destroy(context); } return exit_code; } ``` 这个示例代码创建了一个Websocket服务端,监听指定的端口,并且每收到一条客户端消息就回复一条消息。你可以根据你的需求调整服务端回复消息的内容和频率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值