计算机网络实验 - C/C++实现模拟网桥功能

4 篇文章 0 订阅
2 篇文章 0 订阅

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

要求: Windows或Linux环境下运行,程序应在单机上运行。

分析: 用程序模拟网桥功能,可以假定用两个文件分别代表两个网段上的网络帧数据。而两个文件中的数据应具有帧的特征,即有目的地址,源地址和帧内数据。程序交替读入帧的数据,就相当于网桥从网段中得到帧数据。

对于网桥来说,能否转发帧在于把接收到的帧与网桥中的转发表相比较。判断目的地址后才决定是否转发。由此可见转发的关键在于构造转发表。这里转发表可通过动态生成。

网段1文件
在这里插入图片描述
网段2文件
在这里插入图片描述
转发表文件
在这里插入图片描述
思路:
其实是模拟题没什么好说的,主要是能够理解网桥的作用已经如何运行,实现就用map乱搞就行了。
然后还有个点就是交替读入网段1与网段2,学习了一下别人的交替读入用py写不用担心这个问题

ifstream infile1,infile2;
infile1.open("seg1.txt");
assert(infile1.is_open());
infile2.open("seg2.txt");
assert(infile2.is_open());
string frame;
int flag=0,f1=0,f2=0;
//交替读入网段
while(!infile1.eof()||!infile2.eof()) {
    if(!flag) { //读入网段1
        if(!infile1.eof()) {
            getline(infile1,frame);
            if(!f1) {
                f1=1,flag=1;
                continue;
            }
            frameInput(frame);
        }
        flag=1;
    }
    if(flag) { //读入网段2
        if(!infile2.eof()) {
            getline(infile2,frame);
            if(!f2) {
                f2=1,flag=0;
                continue;
            }
            frameInput(frame);
        }
        flag=0;
    }
}
infile1.close();
infile2.close();

添加系统时间使用time_t

time_t nowtime;
    struct tm* p;
    time(&nowtime);
    p=localtime(&nowtime);

系统时间具体可以参考这篇博客

实现代码:

#pragma GCC optimize(3)
#include <bits/stdc++.h>

#define ull unsigned long long
#define ll long long
#define inf 0x3f3f3f
#define endl '\n'
#define pii pair<int,int>

using namespace std;

template <class T>
void debug(T x) { cout<<x<<endl; }

const int maxn=1e4+100;
const int mod=1e9+7;
const ull p=13331;

struct transmit {
    string Macname;
    int port;
    string t;
};
vector<transmit>tran; //转发表
map<string,int>mp; //查找mac地址对应的端口
vector<string>s1,s2;//网段

int qpow(int a,int b) {
    int ans=1;
    while(b) {
        if(b&1) ans*=a;
        a*=a;
        b>>=1;
    }
    return ans;
}

int turn(string x) {
    int ans=0;
    for(int i=x.length()-1;i>=0;i--) {
        ans+=(x[i]-'0')*qpow(10,x.length()-i-1);
    }
    return ans;
}

//读入转发表
void transmitInput() {
    ifstream infile;
    infile.open("transmit.txt");
    assert(infile.is_open());
    string s;
    int f=0;
    while(getline(infile,s)) {
        if(!f) {
            f=1;
            continue;
        }
        transmit q;
        string tmp="";
        int cnt=0;
        //读入
        for(int i=0;i<s.length();i++) {
            if(i==s.length()-1) tmp+=s[i];
            if(s[i]==' '||i==s.length()-1) { //读到空格就存储数据
                if(!cnt) q.Macname=tmp; //mac名
                else if(cnt==1) { //对应端口号
                    int u=turn(tmp);
                    q.port=u;
                    mp[q.Macname]=u;
                }
                else if(cnt==2) q.t=tmp; //时间
                tmp="";
                cnt++;
                continue;
            }
            tmp+=s[i];
        }
        tran.emplace_back(q); //存入转发表
    }
    infile.close();
}

//获取当前系统时间
string gettime() {
    string ans="";
    time_t nowtime;
    struct tm* p;
    time(&nowtime);
    p=localtime(&nowtime);
    ans+=to_string(p->tm_year+1900);
    ans+='.';
    ans+=to_string(p->tm_mon+1);
    ans+='.';
    ans+=to_string(p->tm_mday);
    ans+='-';
    ans+=to_string(p->tm_hour);
    ans+=':';
    ans+=to_string(p->tm_min);
    ans+=':';
    ans+=to_string(p->tm_sec);
    return ans;
}

//输出转发表
void outputtran() {
    cout<<"now network bridges : "<<endl;
    cout<<"mac port time"<<endl;
    for(int i=0;i<tran.size();i++)  {
        cout<<tran[i].Macname<<" "<<tran[i].port<<" "<<tran[i].t<<endl;
    }
    cout<<endl;
}

//读入帧,自学习/转发
void frameInput(string x) {
    //debug(x);
    int cnt=0;
    string src,des,data,tmp=""; //来源名,目标名,数据
    //一行中读取网段信息
    for(int i=0;i<x.length();i++) {
        if(i==x.length()-1) tmp+=x[i];
        if(x[i]==' '||i==x.length()-1) {
            if(!cnt) src=tmp;
            if(cnt==1) des=tmp;
            if(cnt==2) data=tmp;
            tmp="";
            cnt++;
            continue;
        }
        tmp+=x[i];
    }
    cout<<"source destination data"<<endl;
    cout<<src<<" "<<des<<" "<<data<<endl<<endl;
    if(mp[des]) {
        cout<<"destination's port of "<<data<<" exist in network bridges, transmit successfully!"<<endl;
        cout<<"data "<<data<<" has been sent to port "<<mp[des]<<" from "<<src<<" !"<<endl;
        cout<<"network self_learning start-up !"<<endl;
        cout<<"source : "<<src<<" has been studied ! "<<endl<<endl;
        int ftmp=0;
        for(int i=0;i<s1.size();i++) {
            if(src==s1[i]) {
                ftmp=1;
                break;
            }
        }
        if(!ftmp) {
            for(int i=0;i<s2.size();i++) {
                if(src==s2[i]) {
                    ftmp=2;
                    break;
                }
            }
        }
        string ntime=gettime();
        transmit q;
        q.Macname=src;
        q.port=ftmp;
        q.t=ntime;
        //添加进表
        tran.emplace_back(q);
        mp[src]=ftmp;
        outputtran();
    }
    else {
        cout<<"destination's port of "<<data<<" doesn't exist in network bridges !"<<endl;
        int u=mp[src];
        int ftmp=0;
        for(int i=0;i<s1.size();i++) {
            if(src==s1[i]) {
                ftmp=1;
                break;
            }
        }
        if(!ftmp) {
            for(int i=0;i<s2.size();i++) {
                if(src==s2[i]) {
                    ftmp=2;
                    break;
                }
            }
        }
        cout<<"data :"<<data<<" has been sent into segment: "<<ftmp<<endl<<endl;
    }
}

//初始化网段信息
void init() {
    s1.emplace_back("a");
    s1.emplace_back("b");
    s1.emplace_back("c");
    s1.emplace_back("d");
    s2.emplace_back("e");
    s2.emplace_back("q");
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    init();
    ifstream infile1,infile2;
    infile1.open("seg1.txt");
    assert(infile1.is_open()); //打开失败,则终止
    infile2.open("seg2.txt");
    assert(infile2.is_open());
    transmitInput(); //读入转发表
    outputtran();
    string frame; //读入帧
    int flag=0,f1=0,f2=0;
    //交替读入网段
    cout<<"Start to read segments ! "<<endl<<endl;
    while(!infile1.eof()||!infile2.eof()) {
        if(!flag) { //读入网段1
            if(!infile1.eof()) {
                getline(infile1,frame);
                if(!f1) {
                    f1=1,flag=1;
                    continue;
                }
                frameInput(frame);
            }
            flag=1;
        }
        if(flag) { //读入网段2
            if(!infile2.eof()) {
                getline(infile2,frame);
                if(!f2) {
                    f2=1,flag=0;
                    continue;
                }
                frameInput(frame);
            }
            flag=0;
        }
    }
    infile1.close();
    infile2.close();
    return 0;
}
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值