homework-05 服务器与客户端
首先非常抱歉第三次和第四次作业我没交上来,不想找借口强调原因,但是这两次作业我一定会补上,到时候会@助教。谢谢
回到这次作业!
这次作业邹老师没说博客的格式,所以在这里就没有什么回答问题的东西了。这次由于是自由组队我觉得猪脚应该没有我们的名单,所以在这里附上,如下
11061014 王冠乔
11061027 张盛兴
11061008 谢子鸣
这次作业主要是做一个服务器与客户端的连接,其中黄金点的算法思想应该是在下一周里面提交,所以在这里面就不说算法了,既然只是简单的建立一个小协议和简单的服务器客户端程序,就没必要大费周章,我是用c#的socket类来简单写的通信,而处理也比较简单。
客户端代码如下:
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.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, , 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();
}
} }
主函数如下:
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();
}
服务器代码如下:
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("127.0.0.1");
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;
}
}
}
}
程序的大体框架就是首先服务器通过ListenClientConnect函数来一直监听客户端传来的消息,通过serverSocket.Accept得到socket类,服务器创建了一个客户端list来储存收到的注册的客户端,而没接受一个客户端泽新建一个线程来执行ReceiveMessage函数,ReceiveMessage负责接受注册的信息包括客户端的账号和密码,这里我们吧所有的信息(包括注册的信息和发送的有理数)都一起发送过来,只不过注册的信息开头会有一个Regester来区分,服务器统计我收的客户端数量囚达到20个就开始发送开始游戏命令到每个注册用户中,这时候另一台机(客户端)会建立20个线程(注册用户)来等待开始游戏命令,一旦接受送回一个随机数,每一轮锦标赛服务器都会统计一下在规定的1.2秒内(从发送开始游戏命令开始算起)的参与客户端数量,并算出优胜者,输出当前锦标赛轮数,参与的用户数量,黄金点的值和优胜用户的名字和对应的值;
进行规定论述的锦标赛,输出最佳的人;
homework-05 服务器与客户端的更多相关文章
- 看完这篇包你进大厂,实战即时聊天,一文说明白:聊天服务器+聊天客户端+Web管理控制台。
一.前言 说实话,写这个玩意儿是我上周刚刚产生的想法,本想写完后把代码挂上来赚点积分也不错.写完后发现这东西值得写一篇文章,授人予鱼不如授人以渔嘛(这句话是这么说的吧),顺便赚点应届学生MM的膜拜那就 ...
- SVN服务器和客户端安装教程
SVN是什么?有何用? SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁 ...
- 2016windows(10) wamp 最简单30分钟thrift入门使用讲解,实现php作为服务器和客户端的hello world
2016最简单windows(10) wamp 30分钟thrift入门使用讲解,实现php作为服务器和客户端的hello world thrift是什么 最简单解释 thrift是用来帮助各个编程语 ...
- python web编程-CGI帮助web服务器处理客户端编程
这几篇博客均来自python核心编程 如果你有任何疑问,欢迎联系我或者仔细查看这本书的地20章 另外推荐下这本书,希望对学习python的同学有所帮助 概念预热 eb客户端通过url请求web服务器里 ...
- GATT两个角色 服务器与客户端
两个设备应用数据的通信是通过协议栈的GATT层实现的. 从GATT角度来看,当两个设备建立连接后,他们处于以下两种角色之一: GATT服务器: 它是为GATT客户端提供数据服务的设备 GATT客户端: ...
- golang thrift 源码分析,服务器和客户端究竟是如何工作的
首先编写thrift文件(rpcserver.thrift),运行thrift --gen go rpcserver.thrift,生成代码 namespace go rpc service RpcS ...
- GATT 服务器与客户端角色
两个设备应用数据的通信是通过协议栈的GATT层实现的.从GATT角度来看,当两个设备建立连接后,他们处于以下两种角色之一: GATT服务器: 它是为GATT客户端提供数据服务的设备 GATT客户端: ...
- Node.js权威指南 (8) - 创建HTTP与HTTPS服务器及客户端
8.1 HTTP服务器 / 177 8.1.1 创建HTTP服务器 / 177 8.1.2 获取客户端请求信息 / 182 8.1.3 转换URL字符串与查询字符串 / 184 8.1.4 发送服务器 ...
- 单点登录CAS使用记(二):部署CAS服务器以及客户端
CAS-Server下载地址:https://www.apereo.org/projects/cas/download-cas CAS-Client下载地址:http://developer.jasi ...
随机推荐
- thinkphp 独立分组配置
详见tp官网. 此处为笔记: <?php return array( // 0,为普通分组,1为独立分组 ', // 独立分组目录 'APP_GROUP_PATH' => 'Modules ...
- 组策略限制添加用户作为服务登录导致ITAtomcat服务无法启动(log on as a service)
[故障类型]:ITA tomcat服务器无法启动. [关 键 词]:Logon as a service 作为服务登录 tomcat loggeter [适用版本]:FusionCloud So ...
- dynamic_cast 用法
dynamic_cast < type-id > ( expression ) 该运算符把expression转换成type-id类型的对象.Type-id必须是类的指针.类的引用或者vo ...
- Why it is good practice to declare loggers private, static, and final?
// Jakarta Commons Loggingprivate static final Log log = LogFactory.getLog(MyClass.class);The above ...
- 关于SQL Server 数据库的备份
备份 第一 :选择数据库右键任务,然后直接选择分离,再选择删除和更新上打勾,之后到sqlsever安装目录下查看,会生成xx.mdf和xx.ldf两个文件(既有表结构又有数据). 第二:可以选择备份, ...
- 【ZOJ】2112 Dynamic Rankings
树状数组套主席树模板题目. /* 2112 */ #include <iostream> #include <sstream> #include <string> ...
- 编写高效的C程序与C代码优化
本文地址:http://www.cnblogs.com/archimedes/p/writing-efficient-c-and-code-optimization.html,转载请注明源地址. 说明 ...
- bash 统计文件行数
#假设文件名是:fortest.gtf declare -i fileLinesfileLines=`sed -n '$=' fortest.gtf`echo $fileLines #-------- ...
- UEFI GPT
其实关于UEFI的几篇文章很早就写下了,只是自己读了一遍感觉很不满意,就决定重写.目的是想用最简单直白的语言把内容写出来,让每个人都能轻松读懂.当然,如果你已经对这些内容有了很深的理解的话,这篇文章除 ...
- LeetCode Product of Array Except Self (除自身外序列之积)
题意:给一个序列nums,要求返回一个序列ans,两序列元素个数相同,ans第i个元素就是除了nums[i]之外所有的数相乘之积. 思路:时间O(n),额外空间O(0). 第一次扫一遍,处理nums[ ...