这次作业的运行效果图:

新建了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#):

服务器:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading; namespace C1
{ 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=; private static byte[] result = new byte[];
private static int myProt = ; //端口
static Socket serverSocket;
public static int nsum;
static void Main(string[] args)
{
//服务器IP地址
IPAddress ip = IPAddress.Parse("192.168.12.169");
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(ip, myProt)); //绑定IP地址:端口
serverSocket.Listen();
Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
//通过Clientsoket发送数据 Thread myThread = new Thread(ListenClientConnect);
myThread.Start();
Console.ReadLine();
} /// 监听客户端连接 /// public static void sendstart()
{ for (int i = ; i < Nround; i++)
{
sendmessage();
Thread.Sleep(); double sum = , ave, jiange = ;
int n = , pos = ; foreach (ClientData xx in ClientList)
{
if (xx.IsSendNum)
{
sum += xx.Mnum;
n++;
}
} ave = sum / n * 0.618; for (int j = ; 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 >= )
{
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, , receiveNumber); string[] s = ss.Trim().Split('+'); double tnum = ; if (s[] == "Regester")
{
string[] stemp = s[].Trim().Split('-');
int index = int.Parse(stemp[]);
ClientList[index].Mname = s[];
ClientList[index].Mcode = s[];
continue;
} string tname = s[];
tnum = int.Parse(s[]);
int n = ClientList.FindIndex(x => x.Mname == s[]); ClientList[n].Mnum = tnum;
ClientList[n].IsSendNum = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();
break;
}
}
}
}
}

客户端:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading; namespace C2
{
class client
{
public static string ToBeginGame = "Start";
private static byte[] result = new byte[];
public string sname { get; set; }
public string scode { get; set; } IPAddress ip = IPAddress.Parse("192.168.12.169");
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, , receiveLength); if (ss == ToBeginGame)
{
SendNum();
}
} } public void connnectserver()
{
try
{
clientSocket.Connect(new IPEndPoint(ip, )); //配置服务器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, );
r = new Random(iSeed);
int x;
x = r.Next(); SendClientMessage(sname+"+"+x.ToString());
} public void SendClientMessage(string smessage)
{
try
{
clientSocket.Send(Encoding.ASCII.GetBytes(smessage));
}
catch
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
} }
}

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading; namespace C2
{ class saaaa
{
public static void Main()
{ client[] a =new client[];
for (int i = ; i < ; i++)
{
a[i] = new client { sname = "c-" + i.ToString(), scode = "" };
a[i].connnectserver();
a[i].Sign_Receive();
a[i].Regester();
} Console.ReadLine();
}
}
}

【现代程序设计】【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. HDU 3038 How Many Answers Are Wrong 并查集带权路径压缩

    思路跟 LA 6187 完全一样. 我是乍一看没反应过来这是个并查集,知道之后就好做了. d[i]代表节点 i 到根节点的距离,即每次的sum. #include <cstdio> #in ...

  2. Support Library官方教程(3)android studio中导入支援包

    Support Library Setup How you setup the Android Support Libraries in your development project depend ...

  3. 迷宫问题(bfs的应用)

    问题描述: 定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, ...

  4. APIO2015题解

    分组赛讲课讲了APIO2015的题,于是回去就做完了 稍微写一点题解吧 bzoj4069 逐位处理的简单题,然后就是bool型dp 然后a=1 的时候可以把一位状态干掉 当一维状态单调且是bool型d ...

  5. li添加浮动时不能完全包裹的方法

    <html> <head> <meta http-equiv="Content-Type" content="text/html;chars ...

  6. acdream 1684 娜娜梦游仙境系列——莫名其妙的插曲 (gcd)

    题意:一开始有一个集合,集合里有n个不同的数,然后Alice(娜娜)与Bob轮流进行操作,每人都可以任意选择两个数a,b,不妨设a>b,不过要求a-b不在集合中,把a-b放入集合(集合元素个数只 ...

  7. HDU 2544 最短路 (最短路,spfa)

    题意:中文题目 思路:spfa+SLF优化.关于SPFA的详情请戳我 #include <bits/stdc++.h> using namespace std; , INF=0x7f7f7 ...

  8. Java [Leetcode 125]Valid Palindrome

    题目描述: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ...

  9. TCP协议的一些问题

    1 连接握手三次 解释1:已失效的连接请求报文段 情况下如下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server.本 ...

  10. Ejabberd源码解析前奏--概述

    一.绪论    Ejabberd是一个用Erlang/OTP写的开源即时通讯服务器,其是跨平台.分布式.容错且基于开放标准的实时通讯系统.Ejabberd是一个功能丰富的XMPP服务器,同时适合小规模 ...