【现代程序设计】【homework-05】

 

 

这次作业的运行效果图:

 

新建了20个客户端线程,服务器相应开了20个线程接收客户端数据,每一秒输出每一轮的结果

这次作业用c#完成

利用 Socket 类实现了局域网中的客户端和服务器之间的通信

 

主要设计思路:

对于服务器:

每连接到一个客户端,就新建一个线程用于监听该客户端过来的数据

每一轮新的游戏开始,服务器即向连接到的客户端发送开始游戏的标志

在1.2s内,处理所有接收到的数据,显示结果,并再次发起新的一轮游戏

 

对于客户端:

每个客户端有个线程来接受服务器的发送的数据

在连接阶段客户端主动向服务器注册

客户端并不主动向服务器发送数据,而是根据服务器发送过来的指令类型,选择是否向服务器发送数据

 

 

下面是服务器和客户端用于通信的函数

对于服务器

public static void sendmessage() 向客户端发送数据

private static void ListenClientConnect():开一个线程监听客户端发送的数据

private static void ReceiveMessage(object clientSocket:处理接受到的客户端数据

 

 

对于客户端:

 

public void SendClientMessage(string smessage):用于向服务器发送数据

public void connnectserver():初始阶段连接到服务器

public void ReceiveSMessage():开一个线程接收服务器发送的数据

 

 

下面是完整的代码(c#):

 

 

服务器:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using System.Net.Sockets;
  7 using System.Net;
  8 using System.Threading;
  9 
 10 namespace C1
 11 {
 12 
 13 
 14     class ClientData
 15     {
 16         public string Mname { get; set; }
 17         public string Mcode { get; set; }
 18         public double Mnum { get; set; }
 19         public bool IsSendNum { get; set; }
 20         public Socket client { get; set; }
 21     }
 22 
 23     class NumSeryer
 24     {
 25 
 26         public static DateTime StartTime =new DateTime();
 27         public static DateTime EndTime = new DateTime();
 28 
 29         public static List<ClientData> ClientList = new List<ClientData>();
 30 
 31 
 32         public static int Nround=40;
 33 
 34         private static byte[] result = new byte[1024];
 35         private static int myProt = 8885;   //端口
 36         static Socket serverSocket;
 37         public static int nsum;
 38         static void Main(string[] args)
 39         {
 40             //服务器IP地址
 41             IPAddress ip = IPAddress.Parse("192.168.12.169");
 42             serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 43             serverSocket.Bind(new IPEndPoint(ip, myProt));  //绑定IP地址:端口
 44             serverSocket.Listen(50);    
 45             Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
 46             //通过Clientsoket发送数据
 47 
 48             Thread myThread = new Thread(ListenClientConnect);
 49             myThread.Start();
 50             Console.ReadLine();
 51         }
 52 
 53         
 54         /// 监听客户端连接
 55         
 56         /// 
 57 
 58 
 59 
 60         public static void sendstart()
 61         {
 62 
 63             for (int i = 0; i < Nround; i++)
 64             {
 65                 sendmessage();
 66                 Thread.Sleep(1200);
 67 
 68                 double sum = 0, ave, jiange = 1111111111;
 69                 int n = 0, pos = 0;
 70 
 71                 foreach (ClientData xx in ClientList)
 72                 {
 73                     if (xx.IsSendNum)
 74                     {
 75                         sum += xx.Mnum;
 76                         n++;
 77                     }
 78                 }
 79 
 80 
 81                 ave = sum / n * 0.618;
 82 
 83                 for (int j = 0; j < ClientList.Count; j++)
 84                 {
 85                     ClientData xx = ClientList[j];
 86                     if (xx.IsSendNum && jiange > Math.Abs(xx.Mnum - ave))
 87                     {
 88                         jiange = Math.Abs(xx.Mnum - ave); pos = j;
 89                     }
 90                 }
 91 
 92                 Console.WriteLine("第{0}轮结果", i);
 93                 Console.WriteLine("参与客户端数:{0},G-number:{1}", n, ave);
 94                 Console.WriteLine("获胜客户端名字:{0},数值:{1}", ClientList[pos].Mname, ClientList[pos].Mnum);
 95                 Console.WriteLine();
 96             }
 97         }
 98 
 99         public static void sendmessage()
100         {
101             foreach(ClientData xx in ClientList)
102             xx.client.Send(Encoding.ASCII.GetBytes("Start"));
103         }
104 
105 
106 
107         private static void ListenClientConnect()
108         {
109             while (true)
110             {
111                 nsum++;
112 
113 
114                 StartTime = DateTime.Now;
115 
116                 Socket clientSocket=serverSocket.Accept();
117 
118                 ClientData _client = new ClientData { client =clientSocket  };
119 
120                 ClientList.Add(_client);
121 
122                 Thread receiveThread = new Thread(ReceiveMessage);
123                 receiveThread.Start(clientSocket);
124 
125                 if (nsum >= 20)
126                 {
127                     sendstart();
128                     //        return;
129                 }
130 
131 
132             }
133         }
134 
135         /// <summary>
136         /// 接收消息
137         /// </summary>
138         /// <param name="clientSocket"></param>
139         private static void ReceiveMessage(object clientSocket)
140          {
141             Socket myClientSocket = (Socket)clientSocket;
142 
143 
144             while (true)
145             {
146                 try
147                 {
148                     //通过clientSocket接收数据
149                     int receiveNumber = myClientSocket.Receive(result);
150 
151                     string ss = Encoding.ASCII.GetString(result, 0, receiveNumber);
152 
153                     string[] s = ss.Trim().Split('+');
154 
155 
156                     double tnum = 0;
157 
158                     if (s[0] == "Regester")
159                     {
160                         string[] stemp = s[1].Trim().Split('-');
161                         int index = int.Parse(stemp[1]);
162                         ClientList[index].Mname = s[1];
163                         ClientList[index].Mcode = s[2];
164                         continue;
165                     }
166 
167 
168 
169                     string tname = s[0];
170                     tnum = int.Parse(s[1]);
171                     int n = ClientList.FindIndex(x => x.Mname == s[0]);
172 
173 
174                     ClientList[n].Mnum = tnum;
175                     ClientList[n].IsSendNum = true;
176                 }
177                 catch (Exception ex)
178                 {
179                     Console.WriteLine(ex.Message);
180                     myClientSocket.Shutdown(SocketShutdown.Both);
181                     myClientSocket.Close();
182                     break;
183                 }
184             }
185         }
186     }
187 }

 

 

 

客户端:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using System.Net;
  7 using System.Net.Sockets;
  8 using System.Threading;
  9 
 10 namespace C2
 11 {
 12     class client
 13     {
 14         public static string ToBeginGame = "Start";
 15         private static byte[] result = new byte[1024];
 16         public string sname { get; set; }
 17         public string scode { get; set; }
 18 
 19         IPAddress ip = IPAddress.Parse("192.168.12.169");
 20         Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 21 
 22         public void Sign_Receive()
 23         {
 24             Thread Client_thread = new Thread(new ThreadStart(ReceiveSMessage));
 25             Client_thread.Start();
 26         }
 27 
 28         public void ReceiveSMessage()
 29         {
 30             
 31             //通过clientSocket接收数据
 32             while (true)
 33             {
 34                 
 35                 int receiveLength = clientSocket.Receive(result);
 36                 
 37                 string ss = Encoding.ASCII.GetString(result, 0, receiveLength);
 38                
 39                 if (ss == ToBeginGame)
 40                 {
 41                     SendNum();
 42                 }
 43             }
 44             
 45         }
 46 
 47         public void connnectserver()
 48         {
 49             try
 50             {
 51                 clientSocket.Connect(new IPEndPoint(ip, 8885)); //配置服务器IP与端口
 52                 Console.WriteLine("连接服务器成功");
 53             }
 54             catch
 55             {
 56                 Console.WriteLine("连接服务器失败,请按回车键退出!");
 57                 return;
 58             }
 59         }
 60 
 61         public void Regester()
 62         {
 63             SendClientMessage("Regester"+"+"+sname + "+" + scode);
 64         }
 65 
 66         public void SignIn()
 67         {
 68             SendClientMessage(sname + "" + scode);
 69         }
 70 
 71         public void SendNum()
 72         {
 73             Random _random = new Random();
 74 
 75 
 76             Random r = new Random();
 77 
 78             byte[] buffer = Guid.NewGuid().ToByteArray();
 79             int iSeed = BitConverter.ToInt32(buffer, 0);
 80             r = new Random(iSeed);
 81             int x;
 82             x = r.Next(1000);
 83 
 84 
 85 
 86             SendClientMessage(sname+"+"+x.ToString());
 87         }
 88 
 89         public void SendClientMessage(string smessage)
 90         {
 91                 try
 92                 {
 93                     clientSocket.Send(Encoding.ASCII.GetBytes(smessage));
 94                 }
 95                 catch
 96                 {
 97                     clientSocket.Shutdown(SocketShutdown.Both);
 98                     clientSocket.Close();
 99                 }
100             }
101          
102 
103     }
104 }

 

 

 

一个控制台程序,用于生成20个客户端:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Net;
 7 using System.Net.Sockets;
 8 using System.Threading;
 9 
10 namespace C2
11 {
12 
13 
14     class saaaa
15     {
16         public static void Main()
17         {
18 
19 
20             client[] a =new client[20];
21             for (int i = 0; i < 20; i++)
22             {
23                 a[i] = new client { sname = "c-" + i.ToString(), scode = "123" };
24                 a[i].connnectserver();
25                 a[i].Sign_Receive();
26                 a[i].Regester();
27             }
28             
29             Console.ReadLine();
30         }
31     }
32     }

 

 

 

 

 

 

posted @ 2013-11-03 11:28  早餐  阅读(283)  评论(0编辑  收藏  举报