homework-05 服务器与客户端

首先非常抱歉第三次和第四次作业我没交上来,不想找借口强调原因,但是这两次作业我一定会补上,到时候会@助教。谢谢

 

回到这次作业!

这次作业邹老师没说博客的格式,所以在这里就没有什么回答问题的东西了。这次由于是自由组队我觉得猪脚应该没有我们的名单,所以在这里附上,如下

11061014  王冠乔
11061027  张盛兴

 

11061008  谢子鸣

 

这次作业主要是做一个服务器与客户端的连接,其中黄金点的算法思想应该是在下一周里面提交,所以在这里面就不说算法了,既然只是简单的建立一个小协议和简单的服务器客户端程序,就没必要大费周章,我是用c#的socket类来简单写的通信,而处理也比较简单。

客户端代码如下:

class client
    {
        public static string ToBeginGame = "Start";
        private static byte[] result = new byte[1024];
        public string sname { get; set; }
        public string scode { get; set; }

        IPAddress ip = IPAddress.Parse("192.168.137.1");
        Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        public void Sign_Receive()
        {
            Thread Client_thread = new Thread(new ThreadStart(ReceiveSMessage));
            Client_thread.Start();
        }

        public void ReceiveSMessage()
        {
            
            //通过clientSocket接收数据
            while (true)
            {
                
                int receiveLength = clientSocket.Receive(result);
                
                string ss = Encoding.ASCII.GetString(result, 0, receiveLength);
               
                if (ss == ToBeginGame)
                {
                    SendNum();
                }
            }
            
        }

        public void connnectserver()
        {
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 8885)); //配置服务器IP与端口
                Console.WriteLine("连接服务器成功");
            }
            catch
            {
                Console.WriteLine("连接服务器失败,请按回车键退出!");
                return;
            }
        }

        public void Regester()
        {
            SendClientMessage("Regester"+"+"+sname + "+" + scode);
        }

        public void SignIn()
        {
            SendClientMessage(sname + "" + scode);
        }

        public void SendNum()
        {
            Random _random = new Random();


            Random r = new Random();

            byte[] buffer = Guid.NewGuid().ToByteArray();
            int iSeed = BitConverter.ToInt32(buffer, 0);
            r = new Random(iSeed);
            int x;
            x = r.Next(1000);



            SendClientMessage(sname+"+"+x.ToString());
        }

        public void SendClientMessage(string smessage)
        {
                try
                {
                    clientSocket.Send(Encoding.ASCII.GetBytes(smessage));
                }
                catch
                {
                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close();
                }
            }
         

    }

主函数如下:

public static void Main()
        {


            client[] a = new client[20];
            for (int i = 0; i < 20; i++)
            {
                a[i] = new client { sname = "c-" + i.ToString(), scode = "123" };
                a[i].connnectserver();
                a[i].Sign_Receive();
                a[i].Regester();
            }

            Console.ReadLine();
        }

 

服务器代码如下:

class ClientData
    {
        public string Mname { get; set; }
        public string Mcode { get; set; }
        public double Mnum { get; set; }
        public bool IsSendNum { get; set; }
        public Socket client { get; set; }
    }

    class NumSeryer
    {

        public static DateTime StartTime = new DateTime();
        public static DateTime EndTime = new DateTime();

        public static List<ClientData> ClientList = new List<ClientData>();


        public static int Nround = 40;

        private static byte[] result = new byte[1024];
        private static int myProt = 8885;   //端口
        static Socket serverSocket;
        public static int nsum;
        static void Main(string[] args)
        {
            //服务器IP地址
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(new IPEndPoint(ip, myProt));  //绑定IP地址:端口
            serverSocket.Listen(50);
            Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
            //通过Clientsoket发送数据

            Thread myThread = new Thread(ListenClientConnect);
            myThread.Start();
            Console.ReadLine();
        }


        /// 监听客户端连接

        /// 



        public static void sendstart()
        {

            for (int i = 0; i < Nround; i++)
            {
                sendmessage();
                Thread.Sleep(1200);

                double sum = 0, ave, jiange = 1111111111;
                int n = 0, pos = 0;

                foreach (ClientData xx in ClientList)
                {
                    if (xx.IsSendNum)
                    {
                        sum += xx.Mnum;
                        n++;
                    }
                }


                ave = sum / n * 0.618;

                for (int j = 0; j < ClientList.Count; j++)
                {
                    ClientData xx = ClientList[j];
                    if (xx.IsSendNum && jiange > Math.Abs(xx.Mnum - ave))
                    {
                        jiange = Math.Abs(xx.Mnum - ave); pos = j;
                    }
                }

                Console.WriteLine("第{0}轮结果", i);
                Console.WriteLine("参与客户端数:{0},G-number:{1}", n, ave);
                Console.WriteLine("获胜客户端名字:{0},数值:{1}", ClientList[pos].Mname, ClientList[pos].Mnum);
                Console.WriteLine();
            }
        }

        public static void sendmessage()
        {
            foreach (ClientData xx in ClientList)
                xx.client.Send(Encoding.ASCII.GetBytes("Start"));
        }



        private static void ListenClientConnect()
        {
            while (true)
            {
                nsum++;


                StartTime = DateTime.Now;

                Socket clientSocket = serverSocket.Accept();

                ClientData _client = new ClientData { client = clientSocket };

                ClientList.Add(_client);

                Thread receiveThread = new Thread(ReceiveMessage);
                receiveThread.Start(clientSocket);

                if (nsum >= 20)
                {
                    sendstart();
                    //        return;
                }


            }
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="clientSocket"></param>
        /// 

        private static void ReceiveMessage(object clientSocket)
        {
            Socket myClientSocket = (Socket)clientSocket;


            while (true)
            {
                try
                {
                    //通过clientSocket接收数据
                    int receiveNumber = myClientSocket.Receive(result);

                    string ss = Encoding.ASCII.GetString(result, 0, receiveNumber);

                    string[] s = ss.Trim().Split('+');


                    double tnum = 0;

                    if (s[0] == "Regester")
                    {
                        string[] stemp = s[1].Trim().Split('-');
                        int index = int.Parse(stemp[1]);
                        ClientList[index].Mname = s[1];
                        ClientList[index].Mcode = s[2];
                        continue;
                    }



                    string tname = s[0];
                    tnum = int.Parse(s[1]);
                    int n = ClientList.FindIndex(x => x.Mname == s[0]);


                    ClientList[n].Mnum = tnum;
                    ClientList[n].IsSendNum = true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    myClientSocket.Shutdown(SocketShutdown.Both);
                    myClientSocket.Close();
                    break;
                }
            }
        }
    }

 

 

程序的大体框架就是首先服务器通过ListenClientConnect函数来一直监听客户端传来的消息,通过serverSocket.Accept得到socket类,服务器创建了一个客户端list来储存收到的注册的客户端,而没接受一个客户端泽新建一个线程来执行ReceiveMessage函数,ReceiveMessage负责接受注册的信息包括客户端的账号和密码,这里我们吧所有的信息(包括注册的信息和发送的有理数)都一起发送过来,只不过注册的信息开头会有一个Regester来区分,服务器统计我收的客户端数量囚达到20个就开始发送开始游戏命令到每个注册用户中,这时候另一台机(客户端)会建立20个线程(注册用户)来等待开始游戏命令,一旦接受送回一个随机数,每一轮锦标赛服务器都会统计一下在规定的1.2秒内(从发送开始游戏命令开始算起)的参与客户端数量,并算出优胜者,输出当前锦标赛轮数,参与的用户数量,黄金点的值和优胜用户的名字和对应的值;

进行规定论述的锦标赛,输出最佳的人;

posted on 2013-11-02 23:34  Josdon  阅读(247)  评论(0编辑  收藏  举报