这次作业的运行效果图:

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

客户端:

  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[];
  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, , 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, )); //配置服务器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. Random r = new Random();
  76.  
  77. byte[] buffer = Guid.NewGuid().ToByteArray();
  78. int iSeed = BitConverter.ToInt32(buffer, );
  79. r = new Random(iSeed);
  80. int x;
  81. x = r.Next();
  82.  
  83. SendClientMessage(sname+"+"+x.ToString());
  84. }
  85.  
  86. public void SendClientMessage(string smessage)
  87. {
  88. try
  89. {
  90. clientSocket.Send(Encoding.ASCII.GetBytes(smessage));
  91. }
  92. catch
  93. {
  94. clientSocket.Shutdown(SocketShutdown.Both);
  95. clientSocket.Close();
  96. }
  97. }
  98.  
  99. }
  100. }

一个控制台程序,用于生成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. class saaaa
  14. {
  15. public static void Main()
  16. {
  17.  
  18. client[] a =new client[];
  19. for (int i = ; i < ; i++)
  20. {
  21. a[i] = new client { sname = "c-" + i.ToString(), scode = "" };
  22. a[i].connnectserver();
  23. a[i].Sign_Receive();
  24. a[i].Regester();
  25. }
  26.  
  27. Console.ReadLine();
  28. }
  29. }
  30. }

【现代程序设计】【homework-05】的更多相关文章

  1. 标准C程序设计七---05

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  2. 现代程序设计homework——04

    题目: 详见:http://www.cnblogs.com/xinz/p/3341551.html 题目本身确实很难,“很难想到一个比较优雅的算法”,这是一个老师请来专门讲解这道题的大牛的原话.确实, ...

  3. 软工+C(9): 助教指南,持续更新...

    上一篇:提问与回复 下一篇:从命令行开始逐步培养编程能力(Java) 目录: ** 0x00 Handshake ** 0x01 点评 ** 0x02 评分 ** 0x03 知识储备 ** 0x04 ...

  4. 20172319 2018.03.27-04.05 《Java程序设计》第4周学习总结

    20172319 2018.03.27-04.05 <Java程序设计>第4周学习总结 教材学习内容总结 第四章 编写类 类与对象的回顾:对象是有状态的,状态由对象的属性值确定.属性由类中 ...

  5. 20145219 《Java程序设计》第05周学习总结

    20145219 <Java程序设计>第05周学习总结 教材学习内容总结 try.catch 1.求平均数程序示例 import java.util.Scanner; public cla ...

  6. C语言程序设计|05

    问题 回答 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-4/homework/9772 我在 ...

  7. 20145218 《Java程序设计》第05次实验报告

    北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验名称:Java网络编程及安全 一.实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使 ...

  8. # 20145210 《Java程序设计》第05周学习总结

    教材学习内容总结 第八章 异常处理 8.1语法与继承架构 •使用 try.catch •Java中所有信息都会被打包为对象,如果愿意,可以尝试(try)捕捉(catch)代表错误的对象后做一些处理 • ...

  9. 2017"百度之星"程序设计大赛 - 复赛 01,03,05

    Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  10. 读书笔记(05) - 事件 - JavaScript高级程序设计

    HTML依托于JavaScript来实现用户与WEB网页之间的动态交互,接收用户操作并做出相应的反馈,而事件在此间则充当桥梁的重要角色. 日常开发中,经常会为某个元素绑定一个事件,编写相应的业务逻辑, ...

随机推荐

  1. C# 静态类 + c# 访问器 用途

    C# 静态类    http://blog.csdn.net/dodream/article/details/4588498 静态类的主要特性:仅包含静态成员. 无法实例化. 是密封的. 不能包含实例 ...

  2. [Lintcode 3sum]三数之和(python,二分)

    题目链接:http://www.lintcode.com/zh-cn/problem/3sum/?rand=true# 用这个OJ练练python…这个题意和解法就不多说了,O(n^2lgn)就行了, ...

  3. linux/unix网络编程之 poll

    转自http://www.cnblogs.com/zhuwbox/p/4222382.html poll 与 select 很类似,都是对描述符进行遍历,查看是否有描述符就绪.如果有就返回就绪文件描述 ...

  4. Ionic开发中常见问题和解决方案记录

    1npm按装包失败 更换源:npm config set registry https://registry.npm.taobao.org 或者使用cnpm sudo npm install -g c ...

  5. BZOJ_1624_ [Usaco2008_Open]_Clear_And_Present_Danger_寻宝之路_(最短路_Floyd)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1025 给出\(n\)个点以及之间的边的长度,给出必须访问的点的顺序,求最短路线长度. 分析 用 ...

  6. vssettings 的备份和导入

    vssettings 的作用:   vssettings的导出(也就是相当于是保存):   现在我们试试导入:找一个别人导出的包,我们导入试试.

  7. Java 7 语法新特性

    一.二进制数字表达方式 原本整数(以60为例)能够用十进制(60).八进制(074).十六进制(0x3c)表示,唯独不能用二进制表示(111100),Java 7 弥补了这点. public clas ...

  8. h.264码流解析_一个SPS的nalu及获取视频的分辨率

    00 00 00 01 67 42 00 28 E9 00  A0 0B 77 FE 00 02 00 03 C4 80  00 00 03 00 80 00 00 1A 4D 88  10 94 0 ...

  9. Android -- Support包特性

    干货 每一个 Support 包版本后缀 vX 所代表的含义是他能够被使用的最低版本等级.之所以无法在更低版本进行使用的原因,是因为随着版本的升级,在新版本中有很多之前不支持的特性或者 API,因此如 ...

  10. Zend Framework 入门(4)—页面布局

    Zend Framework 的页面布局模块——Zend_Layout——既可以跟 MVC 一起使用,也可以单独使用.本文只讨论与 MVC 一起使用的情况. 1. 布局脚本 在 application ...