C#拟DHCP运行

使用TcpClient不完备实现DHCP服务器端

namespace DHCPserver

{

    /// <summary>

    /// 客户端申请组件

    /// </summary>

    struct clientComputerInfo

    {

        private string computerMac;   //暂时还不知道如何取MAC地址,先用这个吧

        public string ComputerMac

        {

            get { return computerMac; }

            set { computerMac = value; }

        }

        private string computerName;

        public string ComputerName

        {

            get { return computerName; }

            set { computerName = value; }

        }

        public clientComputerInfo(string computerName)

        {

            this.computerName = computerName;

            this.computerMac = "00-00-00-00-00-00-00-E0";

        }

        public void showDhcpClientInfo()

        {

            Console.WriteLine("有一个DHCP客户端向你索要地址,它的信息如下");

            Console.WriteLine("计算机名为:" + computerName);

            Console.WriteLine("计算机mac地址:" + computerMac);

        }

    }

    /// <summary>

    /// 数据访问组件

    /// </summary>

    class sqlDataSourceAccess

    {

        //放心,实际开发中绝对不会把它硬编码在此,通过反编译可以反回这个.如果是在ASP.NET中的Web.Config中还可以通过命令行加密.aspnet_regiis -pef ...

        private string sqlConnStr = "Data Source=HELLA-PC;Integrated Security=true;Initial Catalog=DHCPServerIPPool;";

        private SqlConnection sqlConn = null;

        private DataSet sqlDataSet = null;

        private SqlCommand sqlCmd = null;

       /// <summary>

       /// 打开一个连接

       /// </summary>

       /// <returns>返回一个连接</returns>

        public SqlConnection getSqlConn()

        {

            try

            {

                sqlConn = new SqlConnection(sqlConnStr);

                sqlConn.Open();

                return sqlConn;

            }

            catch (Exception)

            {

                throw new Exception("数据库连接发生要异常!");

            }

        }

        /// <summary>

        /// 关闭一个已打开的连接

        /// </summary>

        /// <param name="sqlConn">已打开的连接对象</param>

        public void closeSqlConn(SqlConnection sqlConn)

        {

            if (sqlConn.State == ConnectionState.Open)

            {

                sqlConn.Close();

            }

        }

        /// <summary>

        /// 使用存过

        /// </summary>

        /// <param name="stor">存过名</param>

        /// <param name="paras">存过参数</param>

        /// <returns></returns>

        public DataSet getDataSetSto(string stor, SqlParameter[] paras)

        {

            sqlCmd = new SqlCommand(stor, getSqlConn());

            sqlCmd.CommandType = CommandType.StoredProcedure;

            for (int i = 0; i < paras.Length; i++)

            {

                if (paras[i] != null)

                {

                    sqlCmd.Parameters.Add(paras[i]);

                }

            }

            using (SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlCmd))

            {

                sqlDataSet = new DataSet();

                sqlAdapter.Fill(sqlDataSet);

                return sqlDataSet;

            }

        }

        /// <summary>

        /// 返一个sql命令返回的结果集

        /// </summary>

        /// <param name="sql">sql命令</param>

        /// <param name="paras">ql命令中的参数</param>

        /// <returns>sql命令的结果集</returns>

        public DataSet getDataSet(string sql, SqlParameter[] paras)

        {

            sqlCmd = new SqlCommand(sql, getSqlConn());

            for (int i = 0; i < paras.Length; i++)

            {

                if (paras[i] != null)

                {

                    sqlCmd.Parameters.Add(paras[i]);

                }

            }

            using (SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlCmd))

            {

                sqlDataSet = new DataSet();

                sqlAdapter.Fill(sqlDataSet);

                return sqlDataSet;

            }

        }

    }

    class LogInto

    {

        public void writeAssignIpInfo(clientComputerInfo AssignIpInfo, string assignIp)

        {

            if (!File.Exists(@"G:\Exception\AssignIpInfo.txt"))

            {

                StreamWriter sw = new StreamWriter(File.Create(@"G:\Exception\AssignIpInfo.txt"));

                sw.WriteLine("时间为:" + DateTime.Now.ToString() + ":第一次分配IP" + assignIp + 分配给了mac-->" + AssignIpInfo.ComputerMac + "  主机名为:" + AssignIpInfo.ComputerName);

                sw.Flush();

                sw.Close();

            }

            else

            {

                File.AppendAllText(@"G:\Exception\AssignIpInfo.txt""时间为:" + DateTime.Now.ToString() + ":分配IP" + assignIp + 分配给了mac-->" + AssignIpInfo.ComputerMac + "  主机名为:" + AssignIpInfo.ComputerName);

            }

        }

        public void writerException(Exception ex)

        {

            if (!File.Exists(@"G:\Exception\exception.txt"))

            {

                StreamWriter sw = new StreamWriter(File.Create(@"G:\Exception\exception.txt"));

                sw.WriteLine(DateTime.Now.ToString() + "这是第一次发生异常:" + ex.Message);

                sw.Flush();

                sw.Close();

            }

            else

            {

                File.AppendAllText(@"G:\Exception\exception.txt", DateTime.Now + "异常信息:" + ex.Message);

            }

        }

    }

    class Program

    {

        static sqlDataSourceAccess findIpObj = new sqlDataSourceAccess();

        static LogInto logInto = new LogInto();

        static List<TcpClient> dhcpClient = new List<TcpClient>();

        static void Main(string[] args)

        {

            Console.BackgroundColor = ConsoleColor.Blue;

            IPAddress ip = IPAddress.Parse("192.168.1.1");  //DHCP服务器地址

            IPEndPoint ipAndEnd = new IPEndPoint(ip, 68);

            TcpListener tcpListener = new TcpListener(ipAndEnd);

            tcpListener.Start();

            //起来无限监听的线程,该线程下还有两儿子线程

            Thread listenerTh1 = new Thread(listenerClient);

            listenerTh1.Start(tcpListener);

            //再来一个广播线程

            Thread broadCastTh = new Thread(new ThreadStart(broadCastClient));

            broadCastTh.Start();

            //再来服务器展示时间线程

            Thread serverShowTime = new Thread(new ThreadStart(showTimeClient));

            serverShowTime.Start();

        

        }

        /// <summary>

        /// 一个时间展示的小线程

        /// </summary>

        static void showTimeClient()

        {

            while (true)

            {

                Console.Title = DateTime.Now.ToString();

                Thread.Sleep(1000);

            }

        }

        /// <summary>

        /// 对每个向此服务器索引过ip的客户端广播信息。

        /// </summary>

        static void broadCastClient()

        {

            try

            {

                StreamWriter broadCast = null;

                while (true)

                {

                    Console.WriteLine("果断向客户端广播信息");

                    string broadCastMess = Console.ReadLine();

                    foreach (TcpClient temp in dhcpClient)

                    {

                        broadCast = new StreamWriter(temp.GetStream());

                        broadCast.WriteLine(broadCastMess);

                        broadCast.Flush();

                    }

                }

            }

            catch (Exception ex)  //使用老祖宗比较爽

            {

                logInto.writerException(ex);

            }

        }

        static void listenerClient(object obj)

        {

            TcpListener tcpListener = obj as TcpListener;

            TcpClient clientTcpclient = null;

            while (true)

            {

                 clientTcpclient = tcpListener.AcceptTcpClient();

                 dhcpClient.Add(clientTcpclient);   //每来一个索取IP的客户加入此泛型集合 

                 //来一个读线程,来说明有索取IP的客户向我们索要地址来了

                Thread clientReader = new Thread(toClientReader);

                clientReader.Start(clientTcpclient.GetStream());

                //向客户的线程,为索取IP的客户展示选择.注意,此线程采有形式参数的委托类型

                Thread clientWriter = new Thread(toClientWriter);

                clientWriter.Start(clientTcpclient.GetStream());

          

            }

        }

        /// <summary>

        /// 输出申请IP客户端的详细信息

        /// </summary>

        /// <param name="obj">是委托ParameterizedThreadStart()中的Object参数,以便与此委托相匹配.</param>

        private static void toClientReader(object obj)

        {

            NetworkStream nsC = obj as NetworkStream;

            // 对网络络流进行一次包装,方便操作

            StreamReader serverReader = new StreamReader(nsC);

            StreamWriter serverWriter = new StreamWriter(nsC);

            //输出索取IP客户的详细信息,待一下可以写日志

            clientComputerInfo dhcpClient = new clientComputerInfo();

            dhcpClient.ComputerMac = serverReader.ReadLine();

            dhcpClient.ComputerName = serverReader.ReadLine();

            dhcpClient.showDhcpClientInfo();

            try

            {

                string optionIp = serverReader.ReadLine();

                int option = Convert.ToInt32(optionIp);

                if (option >= 1 && option <= 200)

                {

                     Console.WriteLine("这是一个DHCP Offer包的过程");   //放心,这里以后会用UdpClient来改,引外,这里还要进行广播,因为毕竟这个DHCPLinux中的DHCP工作原理有点不同.

                     SqlParameter para = new SqlParameter("@ID", SqlDbType.Int);

                     para.Value = option;

                     DataSet ipDataSet = findIpObj.getDataSetSto("selectIP"new SqlParameter[] { para });

                     serverWriter.WriteLine("好这个ip就分给你了!IP:-->" + ipDataSet.Tables[0].Rows[0][0].ToString() + "再见!"); //这里里在数据库中忘记了设置"子网"+"网关"+"Dns地址",记得加上.

                     serverWriter.Flush();

                     //进行分配后进行日志记录

                     logInto.writeAssignIpInfo(dhcpClient, ipDataSet.Tables[0].Rows[0][0].ToString());

                }

                else

                {

                    serverWriter.WriteLine("你选择有误!");

                    serverWriter.Flush();

                }

            }

            catch (Exception ex)

            {

                logInto.writerException(ex);

            }

        }

        /// <summary>

        /// 向客户端发放还没有用的IP

        /// </summary>

        /// <param name="obj">是委托ParameterizedThreadStart()中的Object参数,以便与此委托相匹配.</param>

        private static void toClientWriter(object obj)

        {

             NetworkStream nsC = obj as NetworkStream;

             StreamWriter serverWriter = new StreamWriter(nsC);

             DataSet selectDataSet = findIpObj.getDataSet("SELECT ID,IP FROM DHCPIpPool WHERE IPStatus=0"new SqlParameter[0]);

             string sendLine = string.Empty;

             for (int i = 0; i < selectDataSet.Tables.Count; i++)  //有多少个表

             {

                 for (int j = 0; j < selectDataSet.Tables[i].Rows.Count; j++)   //每个表有多少行

                 {

                     for (int z = 0; z < selectDataSet.Tables[i].Columns.Count; z++)  //每个有多少列

                     {

                       

                         sendLine += selectDataSet.Tables[i].Rows[j][z].ToString() + "  ";

                     }

                 

                     serverWriter.WriteLine(sendLine.ToString());

                     serverWriter.Flush();

                     sendLine = "";

                     Thread.Sleep(1);

                  

                 }

             }

             serverWriter.WriteLine("请选择一个IP的编号:");

             serverWriter.Flush();

        }

     

    }

}

/*

 CREATE PROC selectIP

@ID INT 

AS 

SELECT IP FROM DHCPIpPool WHERE ID=@ID AND IPStatus=0

UPDATE DHCPIpPool SET IPStatus=1 WHERE ID=@ID

 

 */

使用TcpClient不完备实现DHCP客户端

namespace client

{

    struct clientComputerInfo

    {

        private string computerMac;   //暂时还不知道如何取MAC地址,先用这个吧

        public string ComputerMac

        {

            get { return computerMac; }

            set { computerMac = value; }

        }

        private string computerName;

        public string ComputerName

        {

            get { return computerName; }

            set { computerName = value; }

        }

        public clientComputerInfo(string computerName)

        {

            this.computerName = computerName;

            this.computerMac = "00-00-00-00-00-00-00-E0";

        }

        public void showDhcpClientInfo()

        {

            Console.WriteLine("有一个DHCP客户端向你索要地址");

            Console.WriteLine("计算机名为:" + computerName);

            Console.WriteLine("计算机mac地址:" + computerMac);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Console.BackgroundColor = ConsoleColor.Red;

            IPAddress ip = IPAddress.Parse("192.168.1.1");  //原本是要":0.0.0.0 :255.255.255.255 :67",而且使用的UDP端口,现在是使用TcpClient模拟

            IPEndPoint ipAndEnd = new IPEndPoint(ip, 68);

            TcpClient clientConnection = new TcpClient();

            clientConnection.Connect(ipAndEnd);

            Console.WriteLine("连接DHCP服务器成功!");

            StreamReader clientReader = new StreamReader(clientConnection.GetStream());

            StreamWriter clientWriter = new StreamWriter(clientConnection.GetStream());

            //向服务器申请,关于自己机器的详细信息,很快走完.

            Thread sendServerInfoTh = new Thread(new ParameterizedThreadStart(sendServerInfo));

            sendServerInfoTh.Start(clientWriter);

            //取得服务器的IP选择列表

            Thread getServerIpList = new Thread(new ParameterizedThreadStart(getServerIpListClient));

            getServerIpList.Start(clientReader);

            clientWriter.WriteLine(Console .ReadLine());

            clientWriter.Flush();

            Console.WriteLine("正在等待服务器发放ip,请稍候..");

            Thread.Sleep(2000);

            string assIp = clientReader.ReadLine();

            Console.WriteLine(assIp);

        }

        //使用有参数的委托,也就是使用" public delegate void ParameterizedThreadStart(object obj);"这个委托

        private static void sendServerInfo(object obj)

        {

            StreamWriter clientWriter = obj as StreamWriter;  //进行一次类型转换,因为ParameterizedThreadStart的参数是object,是老祖宗

            Console.WriteLine("正向它发送DHCP Discover!...");

            clientComputerInfo DHCPDiscover = new clientComputerInfo(Dns.GetHostName());

            clientWriter.WriteLine(DHCPDiscover.ComputerMac);  //发送客户端的mac

            clientWriter.WriteLine(DHCPDiscover.ComputerName);

            clientWriter.Flush();

            Console.WriteLine("我已经发送完向DHCP服务器索要IP等信息的关于自己的信息");

        }

        /// <summary>

        /// 读取服务器中可用的IP选择列表,还方便进行接收服务器广播

        /// </summary>

        /// <param name="obj"> public delegate void ParameterizedThreadStart(object obj);</param>

        private static void getServerIpListClient(object obj)

        {

            StreamReader clientReader = obj as StreamReader;

            while (true)

            {

                Console.WriteLine(clientReader.ReadLine());

            }

        }

       

    }

}

你可能感兴趣的:(DHCP)