c#-简单的局域网协议模拟3-跨路由器发生消息

本文介绍了一个网络模拟系统的设计,重点在于设备类、PC和路由的交互,包括数据发送接收、端口映射等核心功能。通过具体代码实现展示了网络数据包的构建与处理流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求

基本需求,设计如下两类对象,都继承于设备类。
设备类:可以接收数据,响应处理由继承的类自己完成。
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);
        }
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值