Exemplo n.º 1
0
        static void Main(string[] args)
        {
            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "控制器启动");

            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;

            //进行系统初始化
            retVal = SystemInit();
            if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "系统初始化失败!");
                Environment.Exit(0);
            }
            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "系统初始化完成");

            //进行控制器应用的初始化
            retVal = ControllerApp.Init();
            if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "控制器初始化失败");
                Environment.Exit(0);
            }
            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "控制器初始化完成");

            //ShowPathInfo();

            //开始控制器应用
            ControllerApp.StartApp();
        }
Exemplo n.º 2
0
        /// <summary>
        /// 控制器系统初始化
        /// </summary>
        private static Const.EN_RET_CODE SystemInit()
        {
            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;

            //初始化邻接矩阵
            retVal = InitPathInfoArr();
            if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
            {
                return(retVal);
            }

            //初始化IP
            retVal = InitIPArry();
            if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
            {
                return(retVal);
            }

            //清空消息队列
            PacketQueue.Clear();

            //从文件读取拓扑信息
            retVal = FileReader.InitFromFile("..\\..\\..\\topology.xml");
            if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
            {
                return(retVal);
            }

            return(Const.EN_RET_CODE.EN_RET_SUCC);
        }
Exemplo n.º 3
0
        /// <summary>
        /// 转发常规数据包
        /// </summary>
        /// <param name="packetInfo"></param>
        /// <returns></returns>
        public static void TranNormalPacket(PacketInfo packetInfo)
        {
            byte[]       packetByte   = packetInfo.GetPacketByte();
            PacketEntity packetEntity = (PacketEntity)Util.BytesToObject(packetByte);
            string       srcIP        = packetEntity.GetHead().strSrcIP;
            string       desIP        = packetEntity.GetHead().strDesIP;

            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;
            int tranPort             = Const.INVALID_NUM;

            //流表中存在转发选项,直接转发
            if (FlowTable.GetInstance().TryGetItem(desIP, out tranPort))
            {
                retVal = Transmitter.SendViaPhyPort(tranPort, packetByte);
                if (Const.EN_RET_CODE.EN_RET_SUCC != retVal)
                {
                    Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "数据包转发失败");
                }
            }
            //流表中不存在转发选项,将数据包暂存缓冲区,上报控制器
            else
            {
                Program.BufferQueue.Enqueue(packetInfo);
                PacketHead   head     = new PacketHead(srcIP, desIP, PacketHead.EN_PACKET_TYPE.EN_PACKET_IN);
                PacketEntity packetIn = new PacketEntity(head, "");
                retVal = Transmitter.SendViaPhyPort(0, Util.ObjectToBytes(packetIn));
                if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
                {
                    Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "packet_in发送失败");
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// 交换机程序启动
        /// </summary>
        public static void Start()
        {
            ////测试
            //if (Program.iCurSwitchID == 0)
            //{
            //	int temp = 0;
            //	while (++temp < 10)
            //	{
            //		PacketEntity packet = new PacketEntity(new PacketHead("1.1.1.1", "2.2.2.2", PacketHead.EN_PACKET_TYPE.EN_NORMAL_PACKET), "Lancer");
            //		byte[] buffer = Util.ObjectToBytes(packet);
            //		Transmitter.SendViaPhyPort(1, buffer);
            //		Transmitter.SendViaPhyPort(2, buffer);
            //		Transmitter.SendViaPhyPort(0, buffer);
            //		Console.WriteLine("发送完成");
            //		Thread.Sleep(1000);
            //	}
            //}



            PacketInfo packetInfo = null;
            bool       firstLoop  = true;

            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;
            while (true)
            {
                if (firstLoop)
                {
                    //发送初始化完成信息给控制器
                    PacketHead   head   = new PacketHead("", "", PacketHead.EN_PACKET_TYPE.EN_SWITCH_ONLINE);
                    PacketEntity packet = new PacketEntity(head, "");
                    retVal = Transmitter.SendViaPhyPort(0, Util.ObjectToBytes(packet));
                    if (Const.EN_RET_CODE.EN_RET_SUCC != retVal)
                    {
                        //TODO
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "初始化完成信息发送失败");
                    }
                    firstLoop = false;
                }

                packetInfo = null;

                //P操作
                Program.PktQueueMutex.WaitOne();
                //消息队列为空,进行V操作之后继续循环读队列
                if (Program.PacketQueue.Count == 0)
                {
                    Program.PktQueueMutex.ReleaseMutex();
                    continue;
                }
                //消息队列不为空,消息包出队后进行V操作
                packetInfo = Program.PacketQueue.Dequeue();
                Program.PktQueueMutex.ReleaseMutex();

                //处理接收到的消息
                DealReceivePacket(packetInfo);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// 暴露给上层,通过物理端口发送数据包
        /// </summary>
        /// <param name="PhyPortNo">物理端口号</param>
        /// <param name="buffer">发送内容</param>
        public static Const.EN_RET_CODE SendViaPhyPort(int PhyPortNo, byte[] buffer)
        {
            if (buffer.Length > Const.MAX_PACKET_LENGTH)
            {
                return(Const.EN_RET_CODE.EN_RET_PACKET_LENGTH_OVERFOLW);
            }

            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;
            retVal = PhyPortManager.GetInstance().SendTo(PhyPortNo, buffer);
            return(retVal);
        }
Exemplo n.º 6
0
        /// <summary>
        /// 系统初始化
        /// </summary>
        /// <returns></returns>
        private static Const.EN_RET_CODE SystemInit()
        {
            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;

            //建立拓扑
            retVal = FileReader.InitFromFile("..\\..\\..\\topology.xml");
            if (Const.EN_RET_CODE.EN_RET_SUCC != retVal)
            {
                return(retVal);
            }
            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "初始化拓扑完成");

            return(Const.EN_RET_CODE.EN_RET_SUCC);
        }
Exemplo n.º 7
0
        /// <summary>
        /// 开始主机业务,死循环读取命令
        /// </summary>
        public static void Start()
        {
            while (true)
            {
                //命令字符串
                string cmdStr = Console.ReadLine();

                Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;

                retVal = DealCommandStr(cmdStr);
                if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
                {
                    continue;
                }
            }
        }
Exemplo n.º 8
0
        static void Main(string[] args)
        {
            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "系统启动");
            if (0 == args.Length)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "输入参数不存在");
                Environment.Exit(0);
            }

            if (!int.TryParse(args[0], out iCurSwitchID))
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "输入参数格式不正确");
                Environment.Exit(0);
            }

            if (iCurSwitchID > Const.MAX_DEVICE_NUM || iCurSwitchID < Const.MIN_DEVICE_NUM)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机ID过大或过小");
                Environment.Exit(0);
            }

            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "交换机ID: " + iCurSwitchID.ToString());

            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;

            //进行系统初始化工作,包括建立拓扑等
            retVal = SystemInit();
            if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "初始化失败");
                Environment.Exit(0);
            }
            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "系统初始化完成");

            //交换机应用初始化
            retVal = SwitchApp.Init();
            if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机应用初始化失败");
                Environment.Exit(0);
            }
            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "交换机应用初始化完成");

            //开始交换机应用,其中死循环
            SwitchApp.Start();
        }
Exemplo n.º 9
0
        /// <summary>
        /// 处理交换机上线消息
        /// </summary>
        /// <param name=""></param>
        public static void DealSwitchOnlinePacket(PacketInfo packetInfo)
        {
            byte[]       packetByte = packetInfo.GetPacketByte();
            int          iPhyPortNo = packetInfo.GetPhyPort();
            PacketEntity packet     = (PacketEntity)Util.BytesToObject(packetByte);
            string       content    = packet.GetStrContent();
            string       srcIP      = packet.GetHead().strSrcIP;
            string       desIP      = packet.GetHead().strDesIP;

            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;

            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "交换机" + iPhyPortNo + "上线");

            //回复上线消息
            PacketHead   head      = new PacketHead("", "", PacketHead.EN_PACKET_TYPE.EN_ACK_SWITCH_ONLINE);
            PacketEntity ackPakcet = new PacketEntity(head, "");

            retVal = Transmitter.SendViaPhyPort(iPhyPortNo, Util.ObjectToBytes(ackPakcet));
            if (Const.EN_RET_CODE.EN_RET_SUCC != retVal)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机上线ACK发送失败");
            }
        }
Exemplo n.º 10
0
        public static Const.EN_RET_CODE InitFromFile(string fileName)
        {
            XmlDocument doc = new XmlDocument();

            try
            {
                doc.Load(fileName);
            }
            catch (Exception)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, fileName + "拓扑结构文件不存在!");
                return(Const.EN_RET_CODE.EN_RET_FILE_NOT_EXIST);
            }

            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "读取拓扑文件");

            try
            {
                XmlElement root = doc.DocumentElement;

                //遍历所有Host
                XmlNodeList hostList = root.GetElementsByTagName("Host");

                foreach (XmlNode hostNode in hostList)
                {
                    string strHostID     = "";
                    string strHostIP     = "";
                    string strHostPort   = "";
                    string strSwitchPort = "";

                    int iHostID     = Const.INVALID_NUM;
                    int iHostPort   = Const.INVALID_NUM;
                    int iSwitchPort = Const.INVALID_NUM;

                    strHostID = ((XmlElement)hostNode).GetElementsByTagName("HostID")[0].InnerText;
                    strHostIP = ((XmlElement)hostNode).GetElementsByTagName("HostIP")[0].InnerText;

                    bool boolTryParseResult = false;

                    boolTryParseResult = int.TryParse(strHostID, out iHostID);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "主机ID转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    if (iHostID != Program.iCurHostID)
                    {
                        continue;
                    }

                    strHostPort   = ((XmlElement)hostNode).GetElementsByTagName("HostPort")[0].InnerText;
                    strSwitchPort = ((XmlElement)hostNode).GetElementsByTagName("switchPort")[0].InnerText;

                    boolTryParseResult = int.TryParse(strHostPort, out iHostPort);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "主机端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strSwitchPort, out iSwitchPort);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;
                    //添加物理端口
                    retVal = PhyPortManager.GetInstance().AddPort(0, iSwitchPort, iHostPort);
                    if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "添加物理端口失败");
                    }
                }
            }
            catch (XmlException)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "Xml格式错误");
                return(Const.EN_RET_CODE.EN_XML_FILE_FORMAT_ERR);
            }

            return(Const.EN_RET_CODE.EN_RET_SUCC);
        }
Exemplo n.º 11
0
        /// <summary>
        /// 从文件中读取拓扑信息,记录到邻接矩阵,并完成与各个交换机的连接
        /// </summary>
        /// <param name="fileName">拓扑文件的路径和文件名</param>
        /// <returns></returns>
        public static Const.EN_RET_CODE InitFromFile(string fileName)
        {
            XmlDocument doc = new XmlDocument();

            try
            {
                doc.Load(fileName);
            }
            catch (Exception)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, fileName + "拓扑结构文件不存在!");
                return(Const.EN_RET_CODE.EN_RET_FILE_NOT_EXIST);
            }

            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "读取拓扑文件");

            try
            {
                XmlElement root = doc.DocumentElement;

                bool boolTryParseResult = false;

                //遍历所有pair,记录邻接矩阵
                XmlNodeList pairList = root.GetElementsByTagName("pair");
                foreach (XmlNode PairNode in pairList)
                {
                    boolTryParseResult = false;

                    string strID0;
                    string strID1;
                    string strDistance;
                    string strPhyPort0;
                    string strPhyPort1;

                    int iID0;
                    int iID1;
                    int iDistance;
                    int iPhyPort0;
                    int iPhyPort1;

                    strDistance = ((XmlElement)PairNode).GetElementsByTagName("distance")[0].InnerText;

                    XmlNodeList switchList = ((XmlElement)PairNode).GetElementsByTagName("switch");

                    strID0      = ((XmlElement)switchList[0]).GetElementsByTagName("id")[0].InnerText;
                    strPhyPort0 = ((XmlElement)switchList[0]).GetElementsByTagName("PhyPortNo")[0].InnerText;

                    strID1      = ((XmlElement)switchList[1]).GetElementsByTagName("id")[0].InnerText;
                    strPhyPort1 = ((XmlElement)switchList[1]).GetElementsByTagName("PhyPortNo")[0].InnerText;

                    boolTryParseResult = int.TryParse(strDistance, out iDistance);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "距离转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strID0, out iID0);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机ID转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strPhyPort0, out iPhyPort0);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机物理接口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strID1, out iID1);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机ID转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strPhyPort1, out iPhyPort1);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机物理接口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    //距离不在范围内
                    if (iDistance < Const.MIN_DISTANCE || iDistance > Const.MAX_DISTANCE)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "距离数据不在范围内");
                        return(Const.EN_RET_CODE.EN_RET_DISTAANCE_OVERFLOW);
                    }

                    //交换机ID不在范围内
                    if (iID0 < Const.MIN_DEVICE_NUM || iID0 > Const.MAX_DEVICE_NUM ||
                        iID1 < Const.MIN_DEVICE_NUM || iID1 > Const.MAX_DEVICE_NUM)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机ID不在范围内");
                        return(Const.EN_RET_CODE.EN_RET_SWITCH_ID_OVERFLOW);
                    }

                    //物理端口号不在范围内
                    if (iPhyPort0 < Const.MIN_PHY_PORT_NUM || iPhyPort0 > Const.MAX_PHY_PORT_NUM ||
                        iPhyPort1 < Const.MIN_PHY_PORT_NUM || iPhyPort1 > Const.MAX_PHY_PORT_NUM)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "物理端口号不在范围内");
                        return(Const.EN_RET_CODE.EN_RET_PHY_PORT_OVERFLOW);
                    }

                    //记录到邻接矩阵中
                    Program.PathInfoArr[iID0, iID1].distance  = iDistance;
                    Program.PathInfoArr[iID0, iID1].phyPortNo = iPhyPort0;

                    Program.PathInfoArr[iID1, iID0].distance  = iDistance;
                    Program.PathInfoArr[iID1, iID0].phyPortNo = iPhyPort1;

                    //Console.WriteLine("id0:{0}, port0:{1}, id1:{2}, port1:{3}, distance:{4}", iID0, iPhyPort0, iID1, iPhyPort1, iDistance);
                }

                //遍历controller标签
                XmlNodeList controllerList = root.GetElementsByTagName("controller");
                foreach (XmlNode ctrlNode in controllerList)
                {
                    boolTryParseResult = false;

                    string strSwitchID;
                    string strSwitchPort;
                    string strControllerPort;
                    string strSwitchIP;

                    int iSwitchID       = Const.INVALID_NUM;
                    int iSwitchPort     = Const.INVALID_NUM;
                    int iControllerPort = Const.INVALID_NUM;

                    strSwitchID       = ((XmlElement)ctrlNode).GetElementsByTagName("switchID")[0].InnerText;
                    strSwitchIP       = ((XmlElement)ctrlNode).GetElementsByTagName("switchIP")[0].InnerText;
                    strSwitchPort     = ((XmlElement)ctrlNode).GetElementsByTagName("switchPort")[0].InnerText;
                    strControllerPort = ((XmlElement)ctrlNode).GetElementsByTagName("controllerPort")[0].InnerText;

                    boolTryParseResult = int.TryParse(strSwitchID, out iSwitchID);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机ID转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strSwitchPort, out iSwitchPort);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strControllerPort, out iControllerPort);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "控制器端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    //交换机ID不在范围内
                    if (iSwitchID > Const.MAX_DEVICE_NUM || iSwitchID < Const.MIN_DEVICE_NUM)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机ID不在范围内");
                        return(Const.EN_RET_CODE.EN_RET_SWITCH_ID_OVERFLOW);
                    }

                    //交换机或控制器端口号不在范围内
                    if (iSwitchPort > Const.MAX_PORT_NUM || iSwitchPort < Const.MIN_PORT_NUM ||
                        iControllerPort > Const.MAX_PORT_NUM || iControllerPort < Const.MIN_PORT_NUM)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机或控制器端口号不在范围内");
                        return(Const.EN_RET_CODE.EN_RET_PORT_OVERFLOW);
                    }

                    Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;
                    //将交换机ID作为控制器的物理端口号
                    retVal = PhyPortManager.GetInstance().AddPort(iSwitchID, iSwitchPort, iControllerPort);
                    if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "添加物理端口失败");
                    }

                    //记录最大交换机ID
                    if (iSwitchID > Program.iMaxDeviceID)
                    {
                        Program.iMaxDeviceID = iSwitchID;
                    }

                    //记录IP
                    Program.IDtoIP[iSwitchID]   = strSwitchIP;
                    Program.IPtoID[strSwitchIP] = iSwitchID;
                }

                //遍历Host标签
                XmlNodeList hostList = root.GetElementsByTagName("Host");
                foreach (XmlNode hostNode in hostList)
                {
                    boolTryParseResult = false;

                    string strHostID;
                    string strSwitchID;
                    string strDistance;
                    string strHostIP;
                    string strSwitchPhyPortNum;

                    int iHostID           = Const.INVALID_NUM;
                    int iSwitchID         = Const.INVALID_NUM;
                    int iDistance         = Const.INVALID_NUM;
                    int iSwitchPhyPortNum = Const.INVALID_NUM;

                    strHostIP           = ((XmlElement)hostNode).GetElementsByTagName("HostIP")[0].InnerText;
                    strHostID           = ((XmlElement)hostNode).GetElementsByTagName("HostID")[0].InnerText;
                    strSwitchID         = ((XmlElement)hostNode).GetElementsByTagName("switchID")[0].InnerText;
                    strDistance         = ((XmlElement)hostNode).GetElementsByTagName("distance")[0].InnerText;
                    strSwitchPhyPortNum = ((XmlElement)hostNode).GetElementsByTagName("PhyPortNo")[0].InnerText;

                    boolTryParseResult = int.TryParse(strHostID, out iHostID);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "主机ID转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strSwitchID, out iSwitchID);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机ID转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strDistance, out iDistance);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "距离转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strSwitchPhyPortNum, out iSwitchPhyPortNum);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "距离转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    //记录最大交换机ID
                    if (iHostID > Program.iMaxDeviceID)
                    {
                        Program.iMaxDeviceID = iHostID;
                    }

                    //记录IP
                    Program.IDtoIP[iHostID]   = strHostIP;
                    Program.IPtoID[strHostIP] = iHostID;

                    //记录路径到邻接矩阵
                    Program.PathInfoArr[iSwitchID, iHostID].distance  = iDistance;
                    Program.PathInfoArr[iSwitchID, iHostID].phyPortNo = iSwitchPhyPortNum;

                    Program.PathInfoArr[iHostID, iSwitchID].distance = iDistance;
                    //主机的物理端口默认为0
                    Program.PathInfoArr[iHostID, iSwitchID].phyPortNo = 0;
                }
            }
            catch (XmlException)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "Xml格式错误");
                return(Const.EN_RET_CODE.EN_XML_FILE_FORMAT_ERR);
            }
            return(Const.EN_RET_CODE.EN_RET_SUCC);
        }
Exemplo n.º 12
0
        /// <summary>
        /// 从文件中初始化拓扑结构
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static Const.EN_RET_CODE InitFromFile(string fileName)
        {
            XmlDocument doc = new XmlDocument();

            try
            {
                doc.Load(fileName);
            }catch (Exception)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, fileName + "拓扑结构文件不存在!");
                return(Const.EN_RET_CODE.EN_RET_FILE_NOT_EXIST);
            }

            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "读取拓扑文件");


            //记录当前交换机的ID在pair中的下标
            int selfIndexInPair = Const.INVALID_NUM;

            try
            {
                XmlElement root = doc.DocumentElement;

                //遍历所有pair
                XmlNodeList pairList = root.GetElementsByTagName("pair");

                foreach (XmlNode PairNode in pairList)
                {
                    string strID0;
                    string strID1;
                    string strPhyPortNo;
                    string strLocalPortNum;
                    string strRemotePortNum;

                    int iPhyPortNo     = Const.INVALID_NUM;
                    int iLocalPortNum  = Const.INVALID_NUM;
                    int iRemotePortNum = Const.INVALID_NUM;

                    XmlNodeList switchList = ((XmlElement)PairNode).GetElementsByTagName("switch");
                    strID0 = ((XmlElement)switchList[0]).GetElementsByTagName("id")[0].InnerText;
                    strID1 = ((XmlElement)switchList[1]).GetElementsByTagName("id")[0].InnerText;

                    //检测pair 中是否有某个交换机ID和当前交换机的ID相同
                    if (strID0 == Program.iCurSwitchID.ToString())
                    {
                        selfIndexInPair = 0;
                    }
                    else if (strID1 == Program.iCurSwitchID.ToString())
                    {
                        selfIndexInPair = 1;
                    }
                    else
                    {
                        selfIndexInPair = Const.INVALID_NUM;
                        continue;
                    }

                    //pair 中某个交换机ID和当前交换机的ID相同
                    if (selfIndexInPair != Const.INVALID_NUM)
                    {
                        strPhyPortNo     = ((XmlElement)switchList[selfIndexInPair]).GetElementsByTagName("PhyPortNo")[0].InnerText;
                        strLocalPortNum  = ((XmlElement)switchList[selfIndexInPair]).GetElementsByTagName("LocalPortNum")[0].InnerText;
                        strRemotePortNum = ((XmlElement)switchList[(selfIndexInPair + 1) % 2]).GetElementsByTagName("LocalPortNum")[0].InnerText;

                        //String转int失败,说明xml数据格式错误,直接抛出异常
                        if (!int.TryParse(strPhyPortNo, out iPhyPortNo) || !int.TryParse(strLocalPortNum, out iLocalPortNum) ||
                            !int.TryParse(strRemotePortNum, out iRemotePortNum))
                        {
                            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "string转int失败");
                            throw new Exception("xml格式错误");
                        }

                        //转换后数值不在规定大小内,同样视为格式不正确,直接抛出异常
                        if (iPhyPortNo > Const.MAX_PHY_PORT_NUM || iPhyPortNo < Const.MIN_PHY_PORT_NUM ||
                            iLocalPortNum > Const.MAX_PORT_NUM || iLocalPortNum < Const.MIN_PORT_NUM ||
                            iRemotePortNum > Const.MAX_PORT_NUM || iRemotePortNum < Const.MIN_PORT_NUM)
                        {
                            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "值不在范围内");
                            throw new Exception("xml格式错误");
                        }

                        //增加物理端口
                        Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;
                        retVal = PhyPortManager.GetInstance().AddPort(iPhyPortNo, iRemotePortNum, iLocalPortNum);
                        if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
                        {
                            //TODO
                            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "增加物理端口失败");
                            return(retVal);
                        }
                    }
                }

                //string转int成功标志
                bool boolTryParseResult = false;

                //遍历controller标签
                XmlNodeList controllerList = root.GetElementsByTagName("controller");

                foreach (XmlNode ctrlNode in controllerList)
                {
                    string strSwitchID = ((XmlElement)ctrlNode).GetElementsByTagName("switchID")[0].InnerText;

                    if (Program.iCurSwitchID.ToString() != strSwitchID)
                    {
                        continue;
                    }

                    string strSwitchPort     = ((XmlElement)ctrlNode).GetElementsByTagName("switchPort")[0].InnerText;
                    string strControllerPort = ((XmlElement)ctrlNode).GetElementsByTagName("controllerPort")[0].InnerText;;
                    int    iSwitchPort       = Const.INVALID_NUM;
                    int    iControllerPort   = Const.INVALID_NUM;

                    boolTryParseResult = int.TryParse(strSwitchPort, out iSwitchPort);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strControllerPort, out iControllerPort);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "控制器端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    //增加物理端口,监听控制器发送的数据,默认控制器连接交换机的0端口
                    Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;
                    retVal = PhyPortManager.GetInstance().AddPort(Const.PHY_PORT_FOR_CONTROLLER, iControllerPort, iSwitchPort);
                    if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
                    {
                        //TODO
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "连接控制器失败");
                        return(retVal);
                    }
                }

                //遍历Host标签
                XmlNodeList hostList = root.GetElementsByTagName("Host");
                foreach (XmlNode hostNode in hostList)
                {
                    string strSwitchID = ((XmlElement)hostNode).GetElementsByTagName("switchID")[0].InnerText;

                    if (Program.iCurSwitchID.ToString() != strSwitchID)
                    {
                        continue;
                    }

                    string strSwitchPort       = ((XmlElement)hostNode).GetElementsByTagName("switchPort")[0].InnerText;
                    string strSwitchPhyPortNum = ((XmlElement)hostNode).GetElementsByTagName("PhyPortNo")[0].InnerText;
                    string strHostPort         = ((XmlElement)hostNode).GetElementsByTagName("HostPort")[0].InnerText;

                    int iSwitchPort       = Const.INVALID_NUM;
                    int iSwitchPhyPortNum = Const.INVALID_NUM;
                    int iHostPort         = Const.INVALID_NUM;

                    boolTryParseResult = int.TryParse(strSwitchPort, out iSwitchPort);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strSwitchPhyPortNum, out iSwitchPhyPortNum);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "交换机物理端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    boolTryParseResult = int.TryParse(strHostPort, out iHostPort);
                    if (boolTryParseResult != true)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "主机端口号转换整型变量失败");
                        return(Const.EN_RET_CODE.EN_RET_INT_TRY_PARSE_ERR);
                    }

                    //增加物理端口,监听主机发送的消息
                    Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;
                    retVal = PhyPortManager.GetInstance().AddPort(iSwitchPhyPortNum, iHostPort, iSwitchPort);
                    if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
                    {
                        Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "连接主机失败");
                        return(retVal);
                    }
                }
            }
            catch (Exception)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_FATAL, "Xml格式错误");
                return(Const.EN_RET_CODE.EN_XML_FILE_FORMAT_ERR);
            }
            return(Const.EN_RET_CODE.EN_RET_SUCC);
        }
Exemplo n.º 13
0
        /// <summary>
        /// 处理packet_in消息,计算最短路径后,发送packet_out消息
        /// </summary>
        /// <param name="packetInfo"></param>
        public static void DealPakcetIn(PacketInfo packetInfo)
        {
            byte[]       packetByte = packetInfo.GetPacketByte();
            int          iPhyPortNo = packetInfo.GetPhyPort();
            PacketEntity packet     = (PacketEntity)Util.BytesToObject(packetByte);
            string       content    = packet.GetStrContent();
            string       srcIP      = packet.GetHead().strSrcIP;
            string       desIP      = packet.GetHead().strDesIP;

            Const.EN_RET_CODE retVal = Const.EN_RET_CODE.EN_RET_INIT;

            //Console.WriteLine("switch No : " + iPhyPortNo + "srcIP :" + srcIP + " desIP : " + desIP);

            //源点交换机ID
            int srcSwitchID = iPhyPortNo;

            //目的点交换机ID
            int desSwitchID;

            //目的IP有效标志
            //bool isDesIPValid = true;

            //记录到当前点的最短路径数值
            int[] distance = new int[Program.iMaxDeviceID + 1];

            //标记是否在最短路径中
            bool[] isInPath = new bool[Program.iMaxDeviceID + 1];

            //最短路径的前驱点
            int[] preSwitchID = new int[Program.iMaxDeviceID + 1];

            //获取目的节点的ID
            try
            {
                desSwitchID = GetSwitchIDByIP(desIP);
            }
            catch (Exception)
            {
                //如果目的IP不在拓扑图中,则命令交换机丢弃数据包
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "目的IP错误");
                PacketHead   dumpHead   = new PacketHead(srcIP, desIP, PacketHead.EN_PACKET_TYPE.EN_PACKET_OUT_DUMP);
                PacketEntity dumpPacket = new PacketEntity(dumpHead, "");
                retVal = Transmitter.SendViaPhyPort(srcSwitchID, Util.ObjectToBytes(dumpPacket));
                return;
            }

            //初始化数组
            for (int i = 0; i < Program.iMaxDeviceID + 1; i++)
            {
                //设置标记为false,即未计算出到i的最短路
                isInPath[i] = false;

                //初始化为最大值加一
                distance[i] = Const.MAX_DISTANCE + 1;

                //前驱点设置为无效点
                preSwitchID[i] = Const.INVALID_NUM;

                //自己到自己的路径长度设为0
                if (i == srcSwitchID)
                {
                    distance[i] = 0;
                    isInPath[i] = true;
                }

                //两个交换机之间有相连路径
                if (Program.PathInfoArr[srcSwitchID, i].distance != Const.INVALID_NUM)
                {
                    distance[i] = Program.PathInfoArr[srcSwitchID, i].distance;

                    //前驱暂时设置为源点
                    preSwitchID[i] = srcSwitchID;
                }
            }

            //循环n - 1次
            for (int loop = 0; loop < Program.iMaxDeviceID; loop++)
            {
                int minDis       = Const.MAX_DISTANCE + 1;
                int nextSwitchID = Const.INVALID_NUM;

                //找距离最小的点
                for (int i = 0; i < Program.iMaxDeviceID + 1; i++)
                {
                    if (!isInPath[i])
                    {
                        if (distance[i] < minDis)
                        {
                            minDis       = distance[i];
                            nextSwitchID = i;
                        }
                    }
                }

                //Console.WriteLine("next : " + nextSwitchID);
                //将距离最小的点加入路径
                isInPath[nextSwitchID] = true;

                //更新数组
                for (int i = 0; i < Program.iMaxDeviceID + 1; i++)
                {
                    if (!isInPath[i] && (Program.PathInfoArr[nextSwitchID, i].distance != Const.INVALID_NUM))
                    {
                        if (minDis + Program.PathInfoArr[nextSwitchID, i].distance < distance[i])
                        {
                            distance[i]    = minDis + Program.PathInfoArr[nextSwitchID, i].distance;
                            preSwitchID[i] = nextSwitchID;
                        }
                    }
                }

                //如果已经找到目的交换机,则退出循环
                if (nextSwitchID == desSwitchID)
                {
                    break;
                }
            }

            //for (int i = 0; i < Program.iMaxSwitchID + 1; i++)
            //{
            //	Console.Write(preSwitchID[i] + "\t");
            //}
            //Console.Write("\n");

            Dictionary <string, int> FlowTableDic = new Dictionary <string, int>();

            //遍历找到最短路的终点
            for (int i = 0; i < Program.iMaxDeviceID + 1; i++)
            {
                if (!isInPath[i])
                {
                    continue;
                }
                if (i == srcSwitchID)
                {
                    continue;
                }

                //TODO
                int curID = i;
                int preID = preSwitchID[curID];

                //Console.WriteLine("Path: ");
                while (preSwitchID[preID] != Const.INVALID_NUM)
                {
                    //Console.WriteLine(curID);
                    curID = preID;
                    preID = preSwitchID[curID];
                }
                //此时curID是下一跳的交换机
                //Console.WriteLine(curID);
                int transPort = Program.PathInfoArr[srcSwitchID, curID].phyPortNo;

                FlowTableDic.Add(GetSwitchIPByID(i), transPort);
            }

            for (int i = 0; i < FlowTableDic.Count; i++)
            {
                Console.Write(FlowTableDic.ElementAt(i).Key + "\t");
                Console.Write(FlowTableDic.ElementAt(i).Value);
                Console.Write("\n");
            }

            PacketHead head = new PacketHead(srcIP, desIP, PacketHead.EN_PACKET_TYPE.EN_PACKET_OUT_WITH_FLOW_ITEM);

            byte[]       dicByte   = Util.ObjectToBytes(FlowTableDic);
            PacketEntity packetOut = new PacketEntity(head, dicByte);

            //PacketEntity packetOut = new PacketEntity(head, Encoding.Default.GetBytes("asdf"));
            retVal = Transmitter.SendViaPhyPort(srcSwitchID, Util.ObjectToBytes(packetOut));
            if (retVal != Const.EN_RET_CODE.EN_RET_SUCC)
            {
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, srcSwitchID + "号交换机路径请求发送失败");
                return;
            }
            Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, srcSwitchID + "号交换机路径请求发送成功");
            //Console.WriteLine("distance: ");
            //for (int i = 0; i < Program.iMaxSwitchID + 1; i++)
            //{
            //	Console.Write(distance[i] + "\t");
            //}
            //Console.Write("\n");
        }