需求
基本需求,设计如下两类对象,都继承于设备类。
设备类:可以接收数据,响应处理由继承的类自己完成。
1.pc
1.1 发送数据,将数据打包发送给路由。
1.1 接收数据,并处理
2.路由
2.1 接收数据分以下几种情况处理
2.1.1 目标本域ip,转发给指定的ip进行处理
2.1.2 目标不是本地IP,将本地的ip源,做端口映射,并将请求发给目标ip.
2.1.3 目标是本地端口映射,将映射的端口转换为本地ip,并转换的目标地址。
代码
using System;
using System.Collections.Generic;
namespace 网络模拟
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
LuYou luYou = new LuYou("luyou");
Pc p1 = new Pc("p1");
Pc p2 = new Pc("p2");
FTP fTP = new FTP();
Http http = new Http();
YinyYong yinyYong1 = new YinyYong("应用1");
yinyYong1.xieYi = fTP;
yinyYong1.duanKou = 1;
YinyYong yinyYong2 = new YinyYong("应用2");
yinyYong2.xieYi = http;
p1.anZhuangXieyi(fTP);
p1.anZhuangXieyi(http);
p1.anZhuangYingYong(yinyYong1);
p1.anZhuangYingYong(yinyYong2);
p2.anZhuangXieyi(fTP);
p2.anZhuangXieyi(http);
p2.anZhuangYingYong(yinyYong1);
p2.anZhuangYingYong(yinyYong2);
luYou.insertWangXian(p1);
luYou.insertWangXian(p2);
Console.WriteLine("ip 1 发送数据");
p1.sent("ni hao", 2,0);
// 创建另一个路由
LuYou luYou2 = new LuYou("luyou2");
luYou2.indexBase = 10;
Pc p11 = new Pc("p11");
luYou2.insertWangXian(luYou);
luYou2.insertWangXian(p11);
YinyYong yinyYong11 = new YinyYong("应用11");
yinyYong1.xieYi = fTP;
yinyYong1.duanKou = 5;
p11.anZhuangXieyi(fTP);
p11.anZhuangXieyi(http);
p11.anZhuangYingYong(yinyYong11);
// 跨域发消息 pi的应用1=>p10的应用"应用11" 发消息
Console.WriteLine("跨域发消息 pi的应用1=>p10的应用应用11 发消息");
p1.send("你好我是来自", 11, 0, 5);
Console.ReadLine();
}
}
// 应用层协议
public abstract class YinYongXieYi
{
public YinYongXieYi(string name)
{
this.name = name;
}
public string name;
public YinYongBao daBao(string data)
{
YinYongBao yinYongBao = new YinYongBao();
yinYongBao.data = data;
setTou(yinYongBao);
return yinYongBao;
}
public string jieBao(YinYongBao yinYongBao) {
return yinYongBao.data;
}
public abstract void setTou(YinYongBao yinYongBao);
}
public class FTP : YinYongXieYi
{
public FTP() : base("FTP") { }
public override void setTou(YinYongBao yinYongBao)
{
yinYongBao.yingYongXieyi = "FTP";
}
}
public class Http : YinYongXieYi
{
public Http() : base("Http") { }
public override void setTou(YinYongBao yinYongBao)
{
yinYongBao.yingYongXieyi = "Http";
}
}
// 应用层数据包-http/FTP
public class YinYongBao {
public string data;
public string yingYongXieyi;
}
// 传输层数据包-TCP/UDP
public class TcpBao
{
public YinYongBao yinYongBao;
public int duanKou;
}
// 网络层数据包-IP
public class IpBao
{
public TcpBao tcpBao;
public int ip;
public int myIp;
}
// 数据链路层数据包
public class LianLuBao
{
public IpBao ipBao;
public string mac;
}
// 应用程序
public class YinyYong
{
public YinyYong(string name)
{
this.name = name;
}
private string name;
// 监听的端口
public int duanKou;
// 使用的协议
public YinYongXieYi xieYi;
public TcpBao daBao(string data)
{
TcpBao tcpBao = new TcpBao();
tcpBao.yinYongBao = xieYi.daBao(data);
tcpBao.duanKou = duanKou;
return tcpBao;
}
public TcpBao daBao(string data,int duankou)
{
TcpBao tcpBao = new TcpBao();
tcpBao.yinYongBao = xieYi.daBao(data);
tcpBao.duanKou = duanKou;
return tcpBao;
}
public void exe(TcpBao tcpBao) {
Console.WriteLine(name+"应用,"+ xieYi .name+ "协议" + "处理" +tcpBao.yinYongBao.data+"数据");
}
}
// 网络设备-网卡、路由器
public class SheBei {
public SheBei(string mac) {
this.mac = mac;
}
public int ip;
public string mac;
public LuYou luYou = null;
public virtual void accept(LianLuBao lianLuBao) { }
}
// 电脑
public class Pc: SheBei
{
List<YinYongXieYi> xieYis = new List<YinYongXieYi>();
List<YinyYong> yinyYongs = new List<YinyYong>();
// 协议安装
public void anZhuangXieyi(YinYongXieYi xieYi) {
xieYis.Add(xieYi);
}
// 安装应用
public void anZhuangYingYong(YinyYong yinyYong) {
yinyYongs.Add(yinyYong);
}
public Pc(string mac):base(mac) {
}
public void sent(string data, int ip,int yingYongId) {
TcpBao tcpBao = yinyYongs[yingYongId].daBao(data);
IpBao ipBao = new IpBao();
ipBao.ip = ip;
ipBao.tcpBao = tcpBao;
LianLuBao lianLuBao = new LianLuBao();
lianLuBao.mac = luYou.mac;
lianLuBao.ipBao = ipBao;
luYou.accept(lianLuBao);
}
public void send(string data, int ip, int yingYongId, int duankou) {
TcpBao tcpBao = yinyYongs[yingYongId].daBao(data,duankou);
IpBao ipBao = new IpBao();
ipBao.ip = ip;
ipBao.tcpBao = tcpBao;
LianLuBao lianLuBao = new LianLuBao();
lianLuBao.mac = luYou.mac;
lianLuBao.ipBao = ipBao;
luYou.accept(lianLuBao);
}
public override void accept(LianLuBao lianLuBao)
{
if (lianLuBao.mac == mac) {
Console.WriteLine("ip: "+ip+" 收到数据");
selectYingYong(lianLuBao.ipBao.tcpBao);
}
}
private void selectYingYong(TcpBao tcpBao)
{
foreach(YinyYong yinyYong in yinyYongs)
{
if(yinyYong.duanKou == tcpBao.duanKou)
{
yinyYong.exe(tcpBao);
}
}
}
}
// ip mac映射表-相当于arp协议的缓冲表
public class YingShe
{
public int ip;
public string mac;
public SheBei pc;
}
// 端口映射
public class DuanKouYingShe {
public int duanKou;
public int pcDuankou;
public YingShe yingShe;
}
// 路由器
public class LuYou : SheBei
{
public int indexBase = 1;
public int indexDuankouBase = 1;
public LuYou(string mac) : base(mac)
{
}
List<YingShe> list = new List<YingShe>();
List<DuanKouYingShe> duanKouYingShes = new List<DuanKouYingShe>();
public void sent(string data, int ip,int yingYongId)
{
}
// 插入网线
public void insertWangXian(SheBei pc) {
YingShe yingShe = new YingShe();
yingShe.mac = pc.mac;
pc.ip = yingShe.ip = createIp();
yingShe.pc = pc;
pc.luYou = this;
list.Add(yingShe);
}
// 端口映射的pc响应
private void baoDuankouYingsheAccept(LianLuBao lianLuBao, DuanKouYingShe duanKouYingSheFanHui) {
int pcDuankou = duanKouYingSheFanHui.pcDuankou;
SheBei pc = duanKouYingSheFanHui.yingShe.pc;
lianLuBao.ipBao.tcpBao.duanKou = pcDuankou;
lianLuBao.mac = duanKouYingSheFanHui.yingShe.pc.mac;
pc.accept(lianLuBao);
}
// 端口映射消息发生,发生给上级路由
private void baoDuankouYingsheSend(LianLuBao lianLuBao, DuanKouYingShe duanKouYingSheFanHui) {
lianLuBao.mac = luYou.mac ;
lianLuBao.ipBao.myIp = ip;
//lianLuBao.ipBao.tcpBao.duanKou = duanKouYingSheFanHui.duanKou;
luYou.accept(lianLuBao);
}
//public void
// 收到数据包的处理
public override void accept(LianLuBao lianLuBao) {
if (lianLuBao.mac == mac)
{
SheBei p = getPcBy(lianLuBao.ipBao.ip);
if (p != null)
{
lianLuBao.mac = p.mac;
p.accept(lianLuBao);
}
else
{
// 发给自己的,需要自己做映射用的
if (lianLuBao.ipBao.ip == ip)
{
DuanKouYingShe duanKouYingSheFanHui = getDuanKouYingSheByIp(lianLuBao.ipBao.myIp);
if (duanKouYingSheFanHui != null)
{
//将消息发给目标地址
baoDuankouYingsheAccept(lianLuBao, duanKouYingSheFanHui);
}
}
else {
DuanKouYingShe duanKouYingShe = xuyaoDuanKouYingShe(lianLuBao.ipBao.ip);
baoDuankouYingsheSend(lianLuBao, duanKouYingShe);
}
}
}
}
// 根据ip地质获取实际主机
public SheBei getPcBy(int ip) {
foreach (YingShe yingShe in list) {
if (ip == yingShe.ip) {
return yingShe.pc;
}
}
return null;
}
// 根据ip返回映射
public YingShe getYingShe(int ip) {
foreach (YingShe yingShe in list)
{
if (ip == yingShe.ip)
{
return yingShe;
}
}
return null;
}
private DuanKouYingShe xuyaoDuanKouYingShe(int ip) {
DuanKouYingShe duanKouYingShe = getDuanKouYingSheByIp(ip);
if (duanKouYingShe == null) {
duanKouYingShe = createDuanKouYingShe(ip);
}
return duanKouYingShe;
}
// 根据ip返回端口映射
private DuanKouYingShe getDuanKouYingSheByIp(int ip)
{
foreach(DuanKouYingShe duanKouYingShe in duanKouYingShes)
{
if (duanKouYingShe.yingShe.ip == ip)
{
return duanKouYingShe;
}
}
return null;
}
// 初始化端口映射
private DuanKouYingShe createDuanKouYingShe(int ip) {
YingShe yingShe = getYingShe(ip);
DuanKouYingShe d = new DuanKouYingShe();
d.duanKou = createDuankou();
d.yingShe = yingShe;
return d;
}
// 当插网线的时候为电脑分配ip
private int createIp() {
int index = indexBase;
foreach (YingShe yingShe in list) {
if (yingShe.ip >= index) {
index++;
}
}
return index;
}
// 返回端口
private int createDuankou() {
int index = indexDuankouBase;
foreach(DuanKouYingShe duanKouYingShe in duanKouYingShes)
{
if (duanKouYingShe.duanKou >= index)
{
index++;
}
}
return index;
}
}
}
运行结果
逐步优化
1 将端口映射逻辑独立出来
using System;
using System.Collections.Generic;
namespace 网络模拟
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
LuYou luYou = new LuYou("luyou");
Pc p1 = new Pc("p1");
Pc p2 = new Pc("p2");
FTP fTP = new FTP();
Http http = new Http();
YinyYong yinyYong1 = new YinyYong("应用1");
yinyYong1.xieYi = fTP;
yinyYong1.duanKou = 1;
YinyYong yinyYong2 = new YinyYong("应用2");
yinyYong2.xieYi = http;
p1.anZhuangXieyi(fTP);
p1.anZhuangXieyi(http);
p1.anZhuangYingYong(yinyYong1);
p1.anZhuangYingYong(yinyYong2);
p2.anZhuangXieyi(fTP);
p2.anZhuangXieyi(http);
p2.anZhuangYingYong(yinyYong1);
p2.anZhuangYingYong(yinyYong2);
luYou.insertWangXian(p1);
luYou.insertWangXian(p2);
Console.WriteLine("ip 1 发送数据");
p1.sent("ni hao", 2,0);
// 创建另一个路由
LuYou luYou2 = new LuYou("luyou2");
luYou2.indexBase = 10;
Pc p11 = new Pc("p11");
luYou2.insertWangXian(luYou);
luYou2.insertWangXian(p11);
YinyYong yinyYong11 = new YinyYong("应用11");
yinyYong1.xieYi = fTP;
yinyYong1.duanKou = 5;
p11.anZhuangXieyi(fTP);
p11.anZhuangXieyi(http);
p11.anZhuangYingYong(yinyYong11);
// 跨域发消息 pi的应用1=>p10的应用"应用11" 发消息
Console.WriteLine("跨域发消息 pi的应用1=>p10的应用应用11 发消息");
p1.send("你好我是来自", 11, 0, 5);
Console.ReadLine();
}
}
// 应用层协议
public abstract class YinYongXieYi
{
public YinYongXieYi(string name)
{
this.name = name;
}
public string name;
public YinYongBao daBao(string data)
{
YinYongBao yinYongBao = new YinYongBao();
yinYongBao.data = data;
setTou(yinYongBao);
return yinYongBao;
}
public string jieBao(YinYongBao yinYongBao) {
return yinYongBao.data;
}
public abstract void setTou(YinYongBao yinYongBao);
}
public class FTP : YinYongXieYi
{
public FTP() : base("FTP") { }
public override void setTou(YinYongBao yinYongBao)
{
yinYongBao.yingYongXieyi = "FTP";
}
}
public class Http : YinYongXieYi
{
public Http() : base("Http") { }
public override void setTou(YinYongBao yinYongBao)
{
yinYongBao.yingYongXieyi = "Http";
}
}
// 应用层数据包-http/FTP
public class YinYongBao {
public string data;
public string yingYongXieyi;
}
// 传输层数据包-TCP/UDP
public class TcpBao
{
public YinYongBao yinYongBao;
public int duanKou;
}
// 网络层数据包-IP
public class IpBao
{
public TcpBao tcpBao;
public int ip;
public int myIp;
}
// 数据链路层数据包
public class LianLuBao
{
public IpBao ipBao;
public string mac;
}
// 应用程序
public class YinyYong
{
public YinyYong(string name)
{
this.name = name;
}
private string name;
// 监听的端口
public int duanKou;
// 使用的协议
public YinYongXieYi xieYi;
public TcpBao daBao(string data)
{
TcpBao tcpBao = new TcpBao();
tcpBao.yinYongBao = xieYi.daBao(data);
tcpBao.duanKou = duanKou;
return tcpBao;
}
public TcpBao daBao(string data,int duankou)
{
TcpBao tcpBao = new TcpBao();
tcpBao.yinYongBao = xieYi.daBao(data);
tcpBao.duanKou = duanKou;
return tcpBao;
}
public void exe(TcpBao tcpBao) {
Console.WriteLine(name+"应用,"+ xieYi .name+ "协议" + "处理" +tcpBao.yinYongBao.data+"数据");
}
}
// 网络设备-网卡、路由器
public class SheBei {
public SheBei(string mac) {
this.mac = mac;
}
public int ip;
public string mac;
public LuYou luYou = null;
public virtual void accept(LianLuBao lianLuBao) { }
}
// 电脑
public class Pc: SheBei
{
List<YinYongXieYi> xieYis = new List<YinYongXieYi>();
List<YinyYong> yinyYongs = new List<YinyYong>();
// 协议安装
public void anZhuangXieyi(YinYongXieYi xieYi) {
xieYis.Add(xieYi);
}
// 安装应用
public void anZhuangYingYong(YinyYong yinyYong) {
yinyYongs.Add(yinyYong);
}
public Pc(string mac):base(mac) {
}
public void sent(string data, int ip,int yingYongId) {
TcpBao tcpBao = yinyYongs[yingYongId].daBao(data);
IpBao ipBao = new IpBao();
ipBao.ip = ip;
ipBao.tcpBao = tcpBao;
LianLuBao lianLuBao = new LianLuBao();
lianLuBao.mac = luYou.mac;
lianLuBao.ipBao = ipBao;
luYou.accept(lianLuBao);
}
public void send(string data, int ip, int yingYongId, int duankou) {
TcpBao tcpBao = yinyYongs[yingYongId].daBao(data,duankou);
IpBao ipBao = new IpBao();
ipBao.ip = ip;
ipBao.tcpBao = tcpBao;
LianLuBao lianLuBao = new LianLuBao();
lianLuBao.mac = luYou.mac;
lianLuBao.ipBao = ipBao;
luYou.accept(lianLuBao);
}
public override void accept(LianLuBao lianLuBao)
{
if (lianLuBao.mac == mac) {
Console.WriteLine("ip: "+ip+" 收到数据");
selectYingYong(lianLuBao.ipBao.tcpBao);
}
}
private void selectYingYong(TcpBao tcpBao)
{
foreach(YinyYong yinyYong in yinyYongs)
{
if(yinyYong.duanKou == tcpBao.duanKou)
{
yinyYong.exe(tcpBao);
}
}
}
}
// ip mac映射表-相当于arp协议的缓冲表
public class YingShe
{
public int ip;
public string mac;
public SheBei pc;
}
// 端口映射
public class DuanKouYingShe {
public int duanKou;
public int pcDuankou;
public YingShe yingShe;
}
public class DuankouYingshe
{
public DuankouYingshe(LuYou luYou)
{
this.frame = luYou;
}
LuYou frame;
List<DuanKouYingShe> duanKouYingShes = new List<DuanKouYingShe>();
// 初始化端口映射
public DuanKouYingShe createDuanKouYingShe(int ip)
{
YingShe yingShe = frame.getYingShe(ip);
DuanKouYingShe d = new DuanKouYingShe();
d.duanKou = createDuankou();
d.yingShe = yingShe;
return d;
}
// 返回端口
public int createDuankou()
{
int index = frame.luYou.indexDuankouBase;
foreach (DuanKouYingShe duanKouYingShe in duanKouYingShes)
{
if (duanKouYingShe.duanKou >= index)
{
index++;
}
}
return index;
}
public DuanKouYingShe xuyaoDuanKouYingShe(int ip)
{
DuanKouYingShe duanKouYingShe = getDuanKouYingSheByIp(ip);
if (duanKouYingShe == null)
{
duanKouYingShe = createDuanKouYingShe(ip);
}
return duanKouYingShe;
}
// 根据ip返回端口映射
public DuanKouYingShe getDuanKouYingSheByIp(int ip)
{
foreach (DuanKouYingShe duanKouYingShe in duanKouYingShes)
{
if (duanKouYingShe.yingShe.ip == ip)
{
return duanKouYingShe;
}
}
return null;
}
// 端口映射的pc响应
public void baoDuankouYingsheAccept(LianLuBao lianLuBao, DuanKouYingShe duanKouYingSheFanHui)
{
int pcDuankou = duanKouYingSheFanHui.pcDuankou;
SheBei pc = duanKouYingSheFanHui.yingShe.pc;
lianLuBao.ipBao.tcpBao.duanKou = pcDuankou;
lianLuBao.mac = duanKouYingSheFanHui.yingShe.pc.mac;
pc.accept(lianLuBao);
}
// 端口映射消息发生,发生给上级路由
public void baoDuankouYingsheSend(LianLuBao lianLuBao, DuanKouYingShe duanKouYingSheFanHui)
{
lianLuBao.mac = frame.luYou.mac;
lianLuBao.ipBao.myIp = frame.luYou.ip;
//lianLuBao.ipBao.tcpBao.duanKou = duanKouYingSheFanHui.duanKou;
frame.luYou.accept(lianLuBao);
}
}
// 路由器
public class LuYou : SheBei
{
public int indexBase = 1;
public int indexDuankouBase = 1;
public DuankouYingshe duankouYingshe;
public LuYou(string mac) : base(mac)
{
duankouYingshe = new DuankouYingshe(this);
}
List<YingShe> list = new List<YingShe>();
List<DuanKouYingShe> duanKouYingShes = new List<DuanKouYingShe>();
// 插入网线
public void insertWangXian(SheBei pc) {
YingShe yingShe = new YingShe();
yingShe.mac = pc.mac;
pc.ip = yingShe.ip = createIp();
yingShe.pc = pc;
pc.luYou = this;
list.Add(yingShe);
}
//public void
// 收到数据包的处理
public override void accept(LianLuBao lianLuBao) {
if (lianLuBao.mac == mac)
{
SheBei p = getPcBy(lianLuBao.ipBao.ip);
if (p != null)
{
lianLuBao.mac = p.mac;
p.accept(lianLuBao);
}
else
{
// 发给自己的,需要自己做映射用的
if (lianLuBao.ipBao.ip == ip)
{
DuanKouYingShe duanKouYingSheFanHui = duankouYingshe.getDuanKouYingSheByIp(lianLuBao.ipBao.myIp);
if (duanKouYingSheFanHui != null)
{
//将消息发给目标地址
duankouYingshe.baoDuankouYingsheAccept(lianLuBao, duanKouYingSheFanHui);
}
}
else {
DuanKouYingShe duanKouYingShe = duankouYingshe.xuyaoDuanKouYingShe(lianLuBao.ipBao.ip);
duankouYingshe.baoDuankouYingsheSend(lianLuBao, duanKouYingShe);
}
}
}
}
// 根据ip地质获取实际主机
public SheBei getPcBy(int ip) {
foreach (YingShe yingShe in list) {
if (ip == yingShe.ip) {
return yingShe.pc;
}
}
return null;
}
// 根据ip返回映射
public YingShe getYingShe(int ip) {
foreach (YingShe yingShe in list)
{
if (ip == yingShe.ip)
{
return yingShe;
}
}
return null;
}
// 当插网线的时候为电脑分配ip
private int createIp() {
int index = indexBase;
foreach (YingShe yingShe in list) {
if (yingShe.ip >= index) {
index++;
}
}
return index;
}
}
}
2.代码优化
2.1 问题修正(发送端端口打包除外)
2.2 追加收到消息后的回复代码
using System;
using System.Collections.Generic;
namespace 网络模拟
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
LuYou luYou = new LuYou("luyou");
Pc p1 = new Pc("p1");
Pc p2 = new Pc("p2");
FTP fTP = new FTP();
Http http = new Http();
YinyYong yinyYong1 = new YinyYong("应用1");
yinyYong1.xieYi = fTP;
yinyYong1.duanKou = 1;
YinyYong yinyYong2 = new YinyYong("应用2");
yinyYong2.xieYi = http;
p1.anZhuangXieyi(fTP);
p1.anZhuangXieyi(http);
p1.anZhuangYingYong(yinyYong1);
p1.anZhuangYingYong(yinyYong2);
p2.anZhuangXieyi(fTP);
p2.anZhuangXieyi(http);
p2.anZhuangYingYong(yinyYong1);
p2.anZhuangYingYong(yinyYong2);
luYou.insertWangXian(p1);
luYou.insertWangXian(p2);
Console.WriteLine("ip 1 发送数据");
p1.send("ni hao", 2,0,1);
// 创建另一个路由
LuYou luYou2 = new LuYou("luyou2");
luYou2.indexBase = 10;
Pc p11 = new Pc("p11");
luYou2.insertWangXian(luYou);
luYou2.insertWangXian(p11);
YinyYong yinyYong11 = new YinyYong("应用11");
yinyYong11.xieYi = fTP;
yinyYong11.duanKou = 5;
p11.anZhuangXieyi(fTP);
p11.anZhuangXieyi(http);
p11.anZhuangYingYong(yinyYong11);
// 跨域发消息 pi的应用1=>p10的应用"应用11" 发消息
Console.WriteLine("\n跨域发消息: pi的应用1=>p10的应用应用11 发消息");
p1.send("你好我是来自", 11, 0, 5);
Console.ReadLine();
}
}
// 应用层协议
public abstract class YinYongXieYi
{
public YinYongXieYi(string name)
{
this.name = name;
}
public string name;
public YinYongBao daBao(string data)
{
YinYongBao yinYongBao = new YinYongBao();
yinYongBao.data = data;
setTou(yinYongBao);
return yinYongBao;
}
public string jieBao(YinYongBao yinYongBao) {
return yinYongBao.data;
}
public abstract void setTou(YinYongBao yinYongBao);
}
public class FTP : YinYongXieYi
{
public FTP() : base("FTP") { }
public override void setTou(YinYongBao yinYongBao)
{
yinYongBao.yingYongXieyi = "FTP";
}
}
public class Http : YinYongXieYi
{
public Http() : base("Http") { }
public override void setTou(YinYongBao yinYongBao)
{
yinYongBao.yingYongXieyi = "Http";
}
}
// 应用层数据包-http/FTP
public class YinYongBao {
public string data;
public string yingYongXieyi;
}
// 传输层数据包-TCP/UDP
public class TcpBao
{
public YinYongBao yinYongBao;
public int duanKou;
public int myDuanKou;
}
// 网络层数据包-IP
public class IpBao
{
public TcpBao tcpBao;
public int ip;
public int myIp;
}
// 数据链路层数据包
public class LianLuBao
{
public IpBao ipBao;
public string mac;
}
// 应用程序
public class YinyYong
{
public YinyYong(string name)
{
this.name = name;
}
private string name;
// 监听的端口
public int duanKou;
// 使用的协议
public YinYongXieYi xieYi;
public TcpBao daBao(string data,int toduankou)
{
TcpBao tcpBao = new TcpBao();
tcpBao.yinYongBao = xieYi.daBao(data);
tcpBao.myDuanKou = this.duanKou;
tcpBao.duanKou = toduankou;
return tcpBao;
}
public void exe(TcpBao tcpBao) {
Console.WriteLine(name+"应用,"+ xieYi .name+ "协议" + "处理" +tcpBao.yinYongBao.data+"数据");
}
}
// 网络设备-网卡、路由器
public class SheBei {
public SheBei(string mac) {
this.mac = mac;
}
public int ip;
public string mac;
public LuYou luYou = null;
public virtual void accept(LianLuBao lianLuBao) { }
}
// 电脑
public class Pc: SheBei
{
List<YinYongXieYi> xieYis = new List<YinYongXieYi>();
List<YinyYong> yinyYongs = new List<YinyYong>();
// 构造函数
public Pc(string mac):base(mac) {
}
// 协议安装
public void anZhuangXieyi(YinYongXieYi xieYi)
{
xieYis.Add(xieYi);
}
// 安装应用
public void anZhuangYingYong(YinyYong yinyYong)
{
yinyYongs.Add(yinyYong);
}
// 发送数据
public void send(string data, int ip, int yingYongId, int duankou) {
send(data, ip, yinyYongs[yingYongId], duankou);
}
// 数据处理
public override void accept(LianLuBao lianLuBao)
{
if (lianLuBao.mac == mac)
{
Console.WriteLine("ip: " + ip + " 收到数据");
selectYingYong(lianLuBao);
}
}
private void send(string data, int ip, YinyYong yinyYong, int duankou)
{
TcpBao tcpBao = yinyYong.daBao(data, duankou);
IpBao ipBao = new IpBao();
ipBao.ip = ip;
ipBao.myIp = this.ip;
ipBao.tcpBao = tcpBao;
LianLuBao lianLuBao = new LianLuBao();
lianLuBao.mac = luYou.mac;
lianLuBao.ipBao = ipBao;
luYou.accept(lianLuBao);
}
private void selectYingYong(LianLuBao lianLuBao)
{
foreach(YinyYong yinyYong in yinyYongs)
{
if(yinyYong.duanKou == lianLuBao.ipBao.tcpBao.duanKou)
{
yinyYong.exe(lianLuBao.ipBao.tcpBao);
//send("收到", lianLuBao.ipBao.myIp, yinyYong, lianLuBao.ipBao.tcpBao.duanKou);
}
}
}
}
// ip mac映射表-相当于arp协议的缓冲表
public class YingShe
{
public int ip;
//public string mac;
public SheBei pc;
}
// 端口映射
public class DuanKouYingShe {
public int duanKou;
public int pcDuankou;
public YingShe yingShe;
}
// 路由器
public class LuYou : SheBei
{
public int indexBase = 1;
public int indexDuankouBase = 1;
public DuankouYingshe duankouYingshe;
public LuYou(string mac) : base(mac)
{
duankouYingshe = new DuankouYingshe(this);
}
List<YingShe> list = new List<YingShe>();
List<DuanKouYingShe> duanKouYingShes = new List<DuanKouYingShe>();
// 插入网线
public void insertWangXian(SheBei pc) {
YingShe yingShe = new YingShe();
//yingShe.mac = pc.mac;
pc.ip = yingShe.ip = createIp();
yingShe.pc = pc;
pc.luYou = this;
list.Add(yingShe);
}
//public void
// 收到数据包的处理
public override void accept(LianLuBao lianLuBao) {
if (lianLuBao.mac == mac)
{
SheBei p = getPcBy(lianLuBao.ipBao.ip);
if (p != null)
{
lianLuBao.mac = p.mac;
p.accept(lianLuBao);
}
else
{
// 发给自己的,需要自己做映射用的
if (lianLuBao.ipBao.ip == ip)
{
DuanKouYingShe duanKouYingSheFanHui = duankouYingshe.getDuanKouYingSheByIp(lianLuBao.ipBao.myIp);
if (duanKouYingSheFanHui != null)
{
//将消息发给目标地址
duankouYingshe.baoDuankouYingsheAccept(lianLuBao, duanKouYingSheFanHui);
}
}
else {
DuanKouYingShe duanKouYingShe = duankouYingshe.xuyaoDuanKouYingShe(lianLuBao.ipBao.ip);
duankouYingshe.baoDuankouYingsheSend(lianLuBao, duanKouYingShe);
}
}
}
}
// 根据ip地质获取实际主机
public SheBei getPcBy(int ip) {
foreach (YingShe yingShe in list) {
if (ip == yingShe.ip) {
return yingShe.pc;
}
}
return null;
}
// 根据ip返回映射
public YingShe getYingShe(int ip) {
foreach (YingShe yingShe in list)
{
if (ip == yingShe.ip)
{
return yingShe;
}
}
return null;
}
// 当插网线的时候为电脑分配ip
private int createIp() {
int index = indexBase;
foreach (YingShe yingShe in list) {
if (yingShe.ip >= index) {
index++;
}
}
return index;
}
}
// 端口映射
public class DuankouYingshe
{
public DuankouYingshe(LuYou luYou)
{
this.frame = luYou;
}
LuYou frame;
List<DuanKouYingShe> duanKouYingShes = new List<DuanKouYingShe>();
// 初始化端口映射
public DuanKouYingShe createDuanKouYingShe(int ip)
{
YingShe yingShe = frame.getYingShe(ip);
DuanKouYingShe d = new DuanKouYingShe();
d.duanKou = createDuankou();
d.yingShe = yingShe;
return d;
}
// 返回端口
public int createDuankou()
{
int index = frame.luYou.indexDuankouBase;
foreach (DuanKouYingShe duanKouYingShe in duanKouYingShes)
{
if (duanKouYingShe.duanKou >= index)
{
index++;
}
}
return index;
}
// 需要做端口映射的情景
public DuanKouYingShe xuyaoDuanKouYingShe(int ip)
{
DuanKouYingShe duanKouYingShe = getDuanKouYingSheByIp(ip);
if (duanKouYingShe == null)
{
duanKouYingShe = createDuanKouYingShe(ip);
duanKouYingShes.Add(duanKouYingShe);
}
return duanKouYingShe;
}
// 根据ip返回端口映射
public DuanKouYingShe getDuanKouYingSheByIp(int ip)
{
foreach (DuanKouYingShe duanKouYingShe in duanKouYingShes)
{
if (duanKouYingShe.yingShe.ip == ip)
{
return duanKouYingShe;
}
}
return null;
}
// 端口映射的pc响应
public void baoDuankouYingsheAccept(LianLuBao lianLuBao, DuanKouYingShe duanKouYingSheFanHui)
{
int pcDuankou = duanKouYingSheFanHui.pcDuankou;
SheBei pc = duanKouYingSheFanHui.yingShe.pc;
//lianLuBao.ipBao.tcpBao.duanKou = pcDuankou;
lianLuBao.mac = duanKouYingSheFanHui.yingShe.pc.mac;
pc.accept(lianLuBao);
}
// 端口映射消息发生,发生给上级路由
public void baoDuankouYingsheSend(LianLuBao lianLuBao, DuanKouYingShe duanKouYingSheFanHui)
{
lianLuBao.mac = frame.luYou.mac;
lianLuBao.ipBao.myIp = frame.luYou.ip;
//lianLuBao.ipBao.tcpBao.duanKou = duanKouYingSheFanHui.duanKou;
frame.luYou.accept(lianLuBao);
}
}
}