Exemplo n.º 1
0
        /// <summary>
        /// 阻塞的方式处理控制器的消息,处理完之前无法接受控制器消息,属于监听子线程
        /// </summary>
        /// <param name="packetInfo"></param>
        public static void DealControllerPacket(PacketInfo packetInfo)
        {
            int iPhyPortNo = packetInfo.GetPhyPort();

            byte[]       buffer  = packetInfo.GetPacketByte();
            PacketEntity packet  = (PacketEntity)Util.BytesToObject(buffer);
            string       content = packet.GetStrContent();
            string       srcIP   = packet.GetHead().strSrcIP;
            string       desIP   = packet.GetHead().strDesIP;

            PacketHead.EN_PACKET_TYPE packetType = packet.GetHead().enPacketType;

            switch (packetType)
            {
            case PacketHead.EN_PACKET_TYPE.EN_ACK_SWITCH_ONLINE:
                Util.Log(Util.EN_LOG_LEVEL.EN_LOG_INFO, "控制器上线");
                break;

            //收到控制器下发的流表
            case PacketHead.EN_PACKET_TYPE.EN_PACKET_OUT_WITH_FLOW_ITEM:
                DealPacketOut(packetInfo);
                break;

            case PacketHead.EN_PACKET_TYPE.EN_PACKET_OUT_DUMP:
                //TODO
                break;

            default:
                break;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 处理消息队列中的消息
        /// </summary>
        /// <param name="packetInfo">待处理的消息包</param>
        public static void DealReceivePacket(PacketInfo packetInfo)
        {
            int iPhyPortNo = packetInfo.GetPhyPort();

            byte[]       buffer = packetInfo.GetPacketByte();
            PacketEntity packet = (PacketEntity)Util.BytesToObject(buffer);

            PacketHead.EN_PACKET_TYPE packetType = packet.GetHead().enPacketType;

            switch (packetType)
            {
            case PacketHead.EN_PACKET_TYPE.EN_NORMAL_PACKET:
                TranNormalPacket(packetInfo);
                break;

            default:
                break;
            }

            //Console.WriteLine("从端口" + iPhyPortNo + "收到消息:" + content);
            //Console.WriteLine("SrcIP: " + srcIP + "\tDesIP" + desIP);
        }
Exemplo n.º 3
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.º 4
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");
        }