首先 需要编写 服务器端 简单的需求 需要判断是否处理信息 我做的是答题联网游戏 所以需要题目的编号 题库对应的数据 还有获得的分数 当然 还需要外置服务器的IP跟port 在读取配置 服务器一般都写成控制台程序 先上代码
class Program
{
/// 客户端列表
public static List<Controller> clientList = new List<Controller>();
/// 是否接收到处理
public static bool IsClick = true;
///题目编号
public static int numberquestion = 0;
///题库编号数组
public static List<string> QuestionList = new List<string>();
/// 获得分数
public static int[] GradeEnd = new int[4] { 0, 0, 0, 0 };
/// 服务器ip
public static string ip;
/// 服务器port
public static int port;
///读取文件
private static void Read()
{
var lines = File.ReadAllLines(Directory.GetCurrentDirectory() + "/config.txt");
var dict = new StringDictionary();
string[] arr;
foreach (var line in lines)
{
if (line.Contains("@"))
{
arr = line.Split('@');
dict.Add(arr[0], arr[1]);
}
}
ip = dict["ip"];
port =int.Parse(dict["port"]);
}
static void Main(string[] args)
{
Read();
//定义socket
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipendPoint = new IPEndPoint(IPAddress.Parse(ip), port);
Console.WriteLine("开始绑定port号....");
//将ip地址和端口号绑定
serverSocket.Bind(ipendPoint);
Console.WriteLine("绑开启服务器....");
//开启服务器
serverSocket.Listen(100);
Console.WriteLine("启动成功!");
while (true)
{
//Console.WriteLine("等待链接.....");
Socket clinetSocket = serverSocket.Accept();
ClientController controller = new ClientController(clinetSocket);
//添加到列表中
clientControllerList.Add(controller);
Console.WriteLine("当前有" + clientControllerList.Count + "个用户链接....");
}
}
}
}
当然Controller 对应的是多台连接 所以写成list数组 网络上连接一台 就需要新建一个Controller 首先 控制的脚本中是需要ClientController开启线程的脚本的 开启接收的方法 方法对应的接收的数据需要定义下 定义自己需要的协议类型 需要登录 开始游戏 判断当前抢答的机器 是否中途可以加入 分数统计 中途加入 这边为了简单 就直接规避掉
namespace server
{
/// <summary>
/// 简单的协议类型
/// </summary>
public enum MessageType
{
Isplay = 0,//答题过程通信
Play = 4,//开始游戏
Login = 1,//登陆ip
Grade = 3,//排行榜
IsClick = 5,//其他机器是否可以答题
EndGrade = 6,//分数
IsJoinGame = 7,//是否可以加入游戏
Responder = 8,//抢答功能
ResponderIsclick = 9,//抢答功能
}
/// <summary>
/// 消息体
/// </summary>
public class MessageData
{
/// <summary>
/// 消息类型
/// </summary>
public MessageType msgType;
/// <summary>
/// 消息内容
/// </summary>
public string msg;
/// <summary>
/// 题目编号
/// </summary>
//题目总数量
int QuesMax = 10;
//随机题目
public void RandomQues(int max, List<string> QuesNumberList)
{
QuesNumberList.Clear();
while (QuesNumberList.Count <= QuesMax)
{
Random random = new Random();
int num = random.Next(max);
if (!QuesNumberList.Contains(num.ToString()))
{
QuesNumberList.Add(num.ToString());
}
else
{
continue;
}
}
}
}
}
当然 每个用户对应的控制脚本中的重要代码
private Socket clientSocket;
/// <summary>
/// 昵称 桌号 玩家编号
/// </summary>
public string nickName;
//接收的线程
Thread receiveThread;
public ClientController(Socket socket)
{
clientSocket = socket;
//启动接收的方法
receiveThread = new Thread(ReceiveFromClient);
receiveThread.Start();
}
/// <summary>
/// 接收
/// </summary>
void ReceiveFromClient()
{
while (true)
{
byte[] buffer = new byte[512];
int lenght = clientSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
//Console.WriteLine("接收长度=" + lenght);
string json = System.Text.Encoding.UTF8.GetString(buffer, 0, lenght);
json.TrimEnd();
if (json.Length > 0)
{
//Console.WriteLine("json=" + json);
MessageData data = JsonConvert.DeserializeObject<MessageData>(json);
switch (data.msgType)
{
//data.msg 客户端发送的数据信息
case MessageType.Login://如果是登陆消息
data.RandomQues(30, Program.QuestionList);//随机题库
//登陆成功
MessageData backData = new MessageData();
backData.msgType = MessageType.Login;
backData.msg = "";
SendMessageDataToAllClient(backData);
MessageData joinData = new MessageData();
joinData.msgType = MessageType.IsJoinGame;
joinData.msg = nickName + "|" + "true";
SendMessageDataToAllClient(joinData);
break;
......
break;
}
}
}
}
还需要发送给客户端的方法
/// 广播信息,告诉所有用户有什么信息过来了!
/// </summary>
/// <param name="data"></param>
void SendMessageDataToAllClient(MessageData data)
{
for (int i = 0; i < Program.clientControllerList.Count; i++)
{
try
{
Program.clientControllerList[i].SendToClient(data);
}
catch (Exception e)
{
i--;
}
}
//Console.WriteLine("广播所有信息");
}
运行的结果 截图
现在来写客户端 当然 通信的协议类是直接可以在客户端使用的,交互通信的方法 UIController 还需要ClientSocket客户端的数据通信脚本
public void ConnectToServer()//开始连接网络
{
if (clientSocket == null)
{
//创建socket对象
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipendPoint = new IPEndPoint(IPAddress.Parse(Clientip), port);
///IPEndPoint iep_local = new IPEndPoint(IPAddress.Parse(Localip), 11111);
//clientSocket.Bind(iep_local);
//Debug.Log("开始链接服务器!!!");
//请求链接
clientSocket.BeginConnect(ipendPoint, ConnectCallback, "");
}
}
......
public void SendBytesMessageToServer(byte[] sendMsgContent, int offset, int size)
{
//Debug.Log("开始发送!!准备发送长度=" + size);
clientSocket.BeginSend(sendMsgContent, offset, size, SocketFlags.None, SendMessageCallback, "");
}
当然客户端连接上去之后就是需要发送信息开始通信了 通信的方式跟服务器端类似 对应的协议加需要通信的内容 //发送 MessageData data = new MessageData(); data.msgType = MessageType.Chat; data.msg = grade; clientSocket.PutMessageToQueue(data); //抢答功能开启 MessageData responder = new MessageData(); responder.msgType = MessageType.ResponderIsclick; responder.msg = "true"; clientSocket.PutMessageToQueue(responder);
客户端也需要写接收的方法 监听其他的客户端通过服务器发送的信息交互 处理
public void ReceiveMsgData(byte[] byteArray, int offset, int length)
{
string msg = System.Text.Encoding.UTF8.GetString(byteArray, offset, length);
//Debug.Log(“收到信息:” + msg);//xml
//receiveMsg += “服务器发来信息:” + msg + “\n”;
//对信息进行处理
MessageData data = LitJson.JsonMapper.ToObject(msg);
switch (data.msgType)
{
case MessageType.Login://联网登陆
//进入场景
break;
case MessageType.IsJoinGame:
//是否可以加入游戏。。。。。。
整体的运行结果如图
当然 服务器跟客户端中间的简单通信 规避掉休眠状态是参考网上大神 壹叶成名https://blog.csdn.net/qq_42461824/article/details/85646260 的联网聊天室 但是项目的需求比这个复杂 我也是简单的关于通信方面 写了个大体答题的逻辑