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;
}