⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 form1.cs

📁 visual c# 网络编程技术与实践实例包括几个源码
💻 CS
📖 第 1 页 / 共 2 页
字号:
            //初始化用于显示信息的委托
            dgMyListBox = new SetMyListBox(SetMsgBox);
            //初始化委托
            MethodInvoker dgTRBtnTrue = new MethodInvoker(setTRBtnTrue);
            //获得主机地址信息
            string hostip = (string)ObTraceMsg;
            //初始化消息数据
            byte[] msgData = new byte[1024];
            int receive, starttime, stoptime;

            //初始化Socket对象 使用Raw套接字进行发送ICMP协议
            Socket hostSock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
            //获得远程主机的IP地址
            IPHostEntry hostIPhe = Dns.GetHostEntry(hostip);
            //使用指定的地址和端口号初始化IPEndPoint对象
            IPEndPoint hostIPep = new IPEndPoint(hostIPhe.AddressList[0], 0);
            //使用IPEndPoint对象初始化EndPoint对象
            EndPoint hostEndPoint = (EndPoint)hostIPep;
            //新建一个ICMP对象
            ICMP pkt = new ICMP();

            //设置ICMP包的类型为询问报文 回送请求
            pkt.packType = 0x08;
            //ICMP包的代码值为0
            pkt.packCode = 0x00;
            //校验和为0
            pkt.CheckSum = 0;
            //填写消息标识符
            Buffer.BlockCopy(BitConverter.GetBytes(1), 0, pkt.Msg, 0, 2);
            //填写消息序列
            Buffer.BlockCopy(BitConverter.GetBytes(1), 0, pkt.Msg, 2, 2);
            //填写数据信息
            msgData = Encoding.ASCII.GetBytes("test packet");
            Buffer.BlockCopy(msgData, 0, pkt.Msg, 4, msgData.Length);
            //设置ICMP包的大小
            pkt.msgSize = msgData.Length + 4;
            int pktSize = pkt.msgSize + 4;

            //获得ICMP包中的校验和
            UInt16 checksum = pkt.getChecksum();
            //将ICMP包的校验和填入
            pkt.CheckSum = checksum;
            //设置套接字的超时时间
            hostSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);
            //初始化错误消息计数器
            int wrongcount = 0;
            //最多经过50个路由器
            for (int i = 1; i < 50; i++)
            {
                //改变IP包的TTL值 使其发回一个超时包
                hostSock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, i);
                //获得数据包的发送时间
                starttime = Environment.TickCount;
                //发送数据包
                hostSock.SendTo(pkt.getBytes(), pktSize, SocketFlags.None, hostIPep);
                try
                {
                    //获得返回的消息
                    msgData = new byte[1024];
                    receive = hostSock.ReceiveFrom(msgData, ref hostEndPoint);
                    //获得数据包的接收时间
                    stoptime = Environment.TickCount;
                    //使用返回消息初始化ICMP对象
                    ICMP res = new ICMP(msgData, receive);
                    int dTime;
                    //获得从发送数据包到接收包所用的时间
                    dTime = stoptime - starttime;
                    //如果数据包类型为超时类型
                    if (res.packType == 11)
                        //显示这一跳所经过的路由器地址
                        msgListBox.Invoke(dgMyListBox, new object[] { "hop " + i + " :response from " + hostEndPoint.ToString() + ", " + dTime + " ms"});
                   //如果数据包类型为应答类型 说明数据包已经到达目的地
                    if (res.packType == 0)
                    {
                        //显示数据包已经到达目的地
                        msgListBox.Invoke(dgMyListBox, new object[] {hostEndPoint.ToString() + " reached in  " + i + " hops,  " + dTime + " ms" });
                        break;
                    }
                    //出错消息计数器置0
                    wrongcount = 0;
                }
                catch (SocketException)
                {
                    //如果没有受到返回的消息 显示错误信息
                    msgListBox.Invoke(dgMyListBox, new object[] {"hop " + i + " : No response from remote host" });
                    //出错消息计数器加1
                    wrongcount++;
                    //如果出错信息到达5条
                    if (wrongcount == 5)
                    {
                        //显示连接远程机器失败
                        msgListBox.Invoke(dgMyListBox, new object[] { "连接到远端主机失败"});
                        break;
                    }
                }
            }
            //关闭套接字
            hostSock.Close();
            //设置TraceRoute按钮为可用
            BeginInvoke(dgTRBtnTrue); 
        }

        public void setTRBtnTrue()
        {
            //设置TraceRoute按钮可用
            traceRtBtn.Enabled = true;
        }

        //寻找子网掩码
        private void findMaskBtn_Click(object sender, EventArgs e)
        {
            //初始化消息数据
            byte[] msgData = new byte[1024];
            int receive;
            //初始化Socket对象 使用Raw套接字进行发送ICMP协议
            Socket hostSock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
            //初始化IPEndPoint对象为广播方式
            IPEndPoint hostIep = new IPEndPoint(IPAddress.Broadcast, 0);
            //使用IPEndPoint对象初始化EndPoint对象
            EndPoint hostEp = (EndPoint)hostIep;
            //新建一个ICMP对象
            ICMP pkt = new ICMP();

            //设置ICMP包的类型为子网掩码请求
            pkt.packType = 0x11;
            //ICMP包的代码值为0
            pkt.packCode = 0x00;
            //校验和为0
            pkt.CheckSum = 0;
            //填写消息标识符
            Buffer.BlockCopy(BitConverter.GetBytes(1), 0, pkt.Msg, 0, 2);
            //填写消息序列
            Buffer.BlockCopy(BitConverter.GetBytes(1), 0, pkt.Msg, 2, 2);
            //这些区域全部设为0
            Buffer.BlockCopy(BitConverter.GetBytes(0), 0, pkt.Msg, 4, 4);
            //设置ICMP包的大小
            pkt.msgSize = 8;
            int pktSize = pkt.msgSize + 4;

            //获得ICMP包中的校验和
            UInt16 checkSum = pkt.getChecksum();
            //将ICMP包的校验和填入
            pkt.CheckSum = checkSum;

            //设置套接字的超时时间
            hostSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 30000);
            //设置套接字为广播类型
            hostSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            //使用套接字发送ICMP包
            hostSock.SendTo(pkt.getBytes(), pktSize, SocketFlags.None, hostIep);
            try
            {
                //使用返回的数据包来初始化字节数组
                msgData = new byte[1024];
                receive = hostSock.ReceiveFrom(msgData, ref hostEp);
            }
            catch (SocketException)
            {
                //如果没有收到返回包 则提示错误
                msgListBox.Items.Add("Unable to determine subnet mask for this subnet");
                return;
            }
            //使用返回的字节数组来初始化ICMP包
            ICMP res = new ICMP(msgData, receive);
            //显示返回的ICMP包的类型
            msgListBox.Items.Add("Received an ICMP type " + res.packType + " packet");
            //获得子网掩码值
            long answerMsg = BitConverter.ToUInt32(res.Msg, 4);
            //将子网掩码值转化为IP地址类型
            IPAddress hostNetMask = new IPAddress(answerMsg);
            //显示子网掩码地址
            msgListBox.Items.Add("The subnet mask for this subnet is : " + hostNetMask.ToString());
        }

        private void clearBtn_Click(object sender, EventArgs e)
        {
            //清空列表框
            msgListBox.Items.Clear();
        }
    }

    //ICMP类
    class ICMP
    {
        //声明ICMP类中的普通数据元素
        //ICMP类型
        public byte packType;
        //ICMP代码
        public byte packCode;
        //ICMP校验和
        public UInt16 CheckSum;
        //ICMP消息实际大小
        public int msgSize;
        //ICMP消息包
        public byte[] Msg = new byte[1024];

        public ICMP()
        {
        }

        //使用远程设备返回的IP包 创建ICMP对象
        public ICMP(byte[] msgdata, int size)
        {
            //前20个字节为IP包内容 后面开始为ICMP包内容
            //获得包的类型信息
            packType = msgdata[20];
            //获得包的代码信息
            packCode = msgdata[21];
            //获得包的校验和信息
            CheckSum = BitConverter.ToUInt16(msgdata, 22);
            //计算出ICMP包的大小
            msgSize = size - 24;
            //将IP包中ICMP的内容复制到ICMP类中的Msg数组中
            Buffer.BlockCopy(msgdata, 24, Msg, 0, msgSize);
        }

        //将ICMP信息转换为字节数组
        public byte[] getBytes()
        {
            //初始化字节数组的大小
            byte[] msgData = new byte[msgSize + 9];
            //将包类型信息填入字节数组
            Buffer.BlockCopy(BitConverter.GetBytes(packType), 0, msgData, 0, 1);
            //将包代码信息填入字节数组
            Buffer.BlockCopy(BitConverter.GetBytes(packCode), 0, msgData, 1, 1);
            //将包校验和信息填入字节数组
            Buffer.BlockCopy(BitConverter.GetBytes(CheckSum), 0, msgData, 2, 2);
            //将包中信息填入字节数组
            Buffer.BlockCopy(Msg, 0, msgData, 4, msgSize);
            //将组装好的字节数组返回
            return msgData;
        }

        //计算校验和方法
        public UInt16 getChecksum()
        {
            UInt32 chksum = 0;
            //将ICMP包转化为数组
            byte[] msgData = getBytes();
            //获得包的大小
            int packsize = msgSize + 8;

            int index = 0;
            //计算校验和算法
            while (index < packsize)
            {
                chksum += Convert.ToUInt32(BitConverter.ToUInt16(msgData, index));
                index += 2;
            }
            chksum = (chksum >> 16) + (chksum & 0xffff);
            chksum += (chksum >> 16);
            //返回校验和为16位的无符号整型值
            return (UInt16)(~chksum);
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -