C++模拟网桥转发功能

题目:写一个程序来模拟网桥功能。

模拟实现网桥的转发功能,以从文件中读取帧模拟网桥从网络中收到一帧,即从两个文件中读入一系列帧,从第一个文件中读入一帧然后从第二个文件中再读入一帧,如此下去。对每一帧,显示网桥是否会转发,及显示转发表内容。

  • 要求:Windows或Linux环境下运行,程序应在单机上运行。
  • 分析:
    1. 用程序模拟网桥功能,可以假定用两个文件分别代表两个网段上的网络帧数据。而两个文件中的数据应具有帧的特征,即有目的地址,源地址和帧内数据。程序交替读入帧的数据,就相当于网桥从网段中得到帧数据。
    2. 对于网桥来说,能否转发帧在于把接收到的帧与网桥中的转发表相比较。判断目的地址后才决定是否转发。由此可见转发的关键在于构造转发表。这里转发表可通过动态生成。

本地数据样式

注意文档中不要有多余的空格,换行。每个字符串中间是一个tab键不是8个空格键。
第一次运行时,转发表可以什么内容都没有

  • 网段一
    C++模拟网桥转发功能

  • 网段二
    C++模拟网桥转发功能

  • 转发表
    C++模拟网桥转发功能

分析

  1. 理解好网桥的功能,代码实现并不困难(当然我的代码并不是完全符合网桥的逻辑的,是一个最简单的网桥功能实现);
  2. 这个实验让我们实现网桥的自学习和转发帧
    • 自学习:查找转发表中与收到帧的源地址有无相匹配的项目。
      -如果有,更新原有项目(简单的代码实现就更新一下时间);
      -如果没有,新增一个项目。
    • 转发帧:查找转发表中与收到帧的目的地址有无相匹配的项目。
      - 如果有,按转发表给出接口进行转发;
      - 如果没有,通过所有接口进行转发;
      - 若转发表给出的接口就是该帧进入网桥的接口,丢弃该帧。

程序流程图

C++模拟网桥转发功能

代码

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <Windows.h>
#include <cstdio>
 #include <time.h>
using namespace std;

//获取string类型的本地时间
string GetSystemTimeStr()
{
    struct tm t;   //tm结构指针
    time_t now;  //声明time_t类型变量
    time(&now);      //获取系统日期和时间
    localtime_s(&t, &now);   //获取当地日期和时间
    string time;
    time.append(to_string(t.tm_year+1900));
    time.append(".");
    time.append(to_string(t.tm_mon+1));
    time.append(".");
    time.append(to_string(t.tm_mday));
    time.append("  ");
    time.append(to_string(t.tm_hour));
    time.append(":");
    time.append(to_string(t.tm_min));
    time.append(":");
    time.append(to_string(t.tm_sec));
    return time;
}

//查表,自学习并进行转发
bool forword(map<string, pair<string, string>>& forwordingTable, string frame, int flag) {
    //如果是读到文件中的第一行,返回
    if (frame == "sourcetdestntdata") return false;
    cout << "网桥接口" << flag << "接收到帧数据" << endl;
    //网桥解析帧数据
    int firstTabIndex = frame.find_first_of("t");
    int lastTabIndex = frame.find_last_of("t");
    //源地址
    string source = frame.substr(0, firstTabIndex);
    //目的地址
    string destination = frame.substr(firstTabIndex + 1, lastTabIndex - firstTabIndex - 1);
    //帧内数据
    string data = frame.substr(lastTabIndex + 1, frame.size() - lastTabIndex);

    //帧离开源地址,到达网桥(按道理这语句应该在最上面,但是要用到几个变量只能放在这里)
    cout << "PC" << source << " send data to " << "PC" << destination << ": " << data << endl;
    //查转发表
    //自学习,先用源地址更新转发表
    map<string, pair<string, string>>::iterator iter = forwordingTable.find(source);
    //表中没有匹配,新增项目
    if (iter == forwordingTable.end()) {
        pair<string, string> save(to_string(flag), GetSystemTimeStr());
        forwordingTable.insert(pair<string, pair<string, string>>(source, save));
    }
    //表中有匹配,更新项目
    else forwordingTable[source].second = GetSystemTimeStr();
    //转发帧,判断转发表中是否有目的地址
    iter = forwordingTable.find(destination);
    //没有有目的地址,通过所有接口进行转发;有目的地址,按给定接口进行转发
    if (iter == forwordingTable.end()) cout << "转发表中无PC" << destination << "的信息,网桥通过所有接口进行转发" << endl;
    else if (forwordingTable[destination].first == to_string(flag)) cout << "PC" << source << "和PC" << destination << "在同一网段下,丢弃该帧数据" << endl;
    else cout << "从接口" << flag << "处进行转发" << endl;
    //帧离开网桥网桥,到达目的地址
    cout << "PC" << destination << " receive data from " << source << ": " << data << endl << endl;
    return true;
}

int main() {
    //读取两网段和转发表文件
    ifstream segment1File("segment1.txt");
    if (!segment1File.is_open()) {
        cout << "segmeng1文件打开失败!" << endl;
        return 1;
    }
    ifstream segment2File("segment2.txt");
    if (!segment2File.is_open()) {
        cout << "segmeng2文件打开失败!" << endl;
        return 1;
    }
    ifstream forwordingTableFileRead("forwordingTable.txt");
    if (!forwordingTableFileRead.is_open()) {
        cout << "forwordingTable文件打开失败!" << endl;
        return 1;
    }

    //用地图存起来转发表
    map<string, pair<string,string>> forwordingTable;
    string row;
    while (getline(forwordingTableFileRead, row))
    {
        //忽略第一行标题
        if (row == "PCtsegmentttime") continue;
        //找到制表符位置
        int firstTabIndex = row.find_first_of('t');
        int lastTabIndex = row.find_last_of("t");
        //获取map的key和value,插入map
        string key = row.substr(0, firstTabIndex);
        string value = row.substr(firstTabIndex +1, lastTabIndex - firstTabIndex - 1);
        string time = row.substr(lastTabIndex + 1, row.size() - lastTabIndex);
        pair <string, string> save(value, time);
        forwordingTable.insert(pair<string, pair<string,string>>(key, save));
    }

    //帧数据
    string frame;
    //交替读入标志
    int flag = 1;
    //网桥开始工作
    while (!segment1File.eof() || !segment2File.eof()) {
        if (flag == 1) {
            if (!segment1File.eof()) {
                //读网段一中的一行
                getline(segment1File, frame);
                if(!forword(forwordingTable, frame, flag)) continue;
            }
            //交替
            flag = 2;
        }
        if (flag == 2) {
            if (!segment2File.eof()) {
                //读网段二中的一行
                getline(segment2File, frame);
                if (!forword(forwordingTable, frame, flag)) continue;
            }
            //交替
            flag = 1;
        }
    }

    //更新转发表到本地
    ofstream forwordingTableFileWrite("forwordingTable.txt");
    if (!forwordingTableFileWrite.is_open()) {
        cout << "forwordingTable文件打开失败!" << endl;
        return 1;
    }
    forwordingTableFileWrite << "PCtsegmentttime" << endl;
    for (auto mapIndex : forwordingTable) {
        forwordingTableFileWrite << mapIndex.first << "t" << mapIndex.second.first << "t" << mapIndex.second.second<<endl;
    }

    //完成工作,关闭文件
    segment1File.close();
    segment2File.close();
    forwordingTableFileRead.close();
    forwordingTableFileWrite.close();
    return 0;
}

结果截图

  • 第一次转发表中没有任何信息
    C++模拟网桥转发功能

  • 第二次转发表中已经有了全部信息
    C++模拟网桥转发功能

原文链接: https://www.cnblogs.com/wasi-991017/p/12911140.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++模拟网桥转发功能

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/349221

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午5:35
下一篇 2023年3月2日 上午5:35

相关推荐