Unity3D网络游戏0.4
创始人
2025-05-31 13:47:39
0

状态检测 Poll

 不使用异步多线程技术,同步程序如何改善C/S架构呢?
 答案是在同步程序中添加判断,判断想要进行的操作是否可以完成。

Socket.Poll 方法

 Poll方法的原型如下:

public bool Poll(int microSeconds,SelectMode mode
)
参数说明
microSeconds等待回应的时间(ms)
modeRead /Write /Error

 Poll方法会检擦Socket的状态.
 如果指定mode参数为SelectMode.SelectRead则可确定Socket是否可读,指定参数为SelectMode.SelectWrite确定参数是否可写,指定参数为SelectMode.SelectError可以检测错误条件。
 Poll将在指定的时间段内阻止执行,若在某一时刻检测的状态为true则返回,否则将一直检测完整个时间段。如果要一直检测可将microSeconds设置为-1,如果希望不阻塞可将microSeconds设置为0。

同步客户端

 使用Poll方法开发同步聊天客户端,代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using UnityEngine;
using UnityEngine.UI;public class Echo : MonoBehaviour
{private Socket socket;public InputField inputField;public Text text;private byte[] readBuff = new byte[1024];private string recvStr = "";public void Connection(){socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//其实没有连接上Socket也无法聊天,所以此处写同步方法socket.Connect("127.0.0.1", 8888);}public void Send(){string sendStr = inputField.text;byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr);//当可用发消息时才发消息if (socket.Poll(0, SelectMode.SelectWrite))socket.Send(sendBytes);}public void Update(){if (socket == null)return;//当有消息可读时才读消息if (socket.Poll(0, SelectMode.SelectRead)){byte[] readBuff = new byte[1024];int count = socket.Receive(readBuff);string readStr = System.Text.Encoding.Default.GetString(this.readBuff, 0, count);text.text = readStr;}}
}

同步服务端

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
public class ClientState
{public Socket socket;public byte[] readBuff = new byte[1024];
}class MainClass
{//监听Socket listenfdprivate static Socket listenfd;//连接服务端的客户端列表(使用字典是为了方便查找)private static Dictionary clients =new Dictionary();public static void Main(string[] args){Console.WriteLine("Hello World!");//创建监听Socketlistenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//注册BindIPAddress ipAdr = IPAddress.Parse("127.0.0.1");IPEndPoint ipEp = new IPEndPoint(ipAdr, 8888);listenfd.Bind(ipEp);//设置并开始监听listenfd.Listen(0);Console.WriteLine("[服务器]启动成功");while (true){if (listenfd.Poll(0, SelectMode.SelectRead)){ReadListenfd(listenfd);}foreach (ClientState cs in clients.Values){Socket clientfd = cs.socket;if (clientfd.Poll(0, SelectMode.SelectRead)){if (!ReadClientfd(clientfd)){break;}}}}System.Threading.Thread.Sleep(1);}public static void ReadListenfd(Socket listenfd){Console.WriteLine("Accept");Socket clientfd = listenfd.Accept();ClientState state = new ClientState();state.socket = clientfd;clients.Add(clientfd,state);}public static bool ReadClientfd(Socket clientfd){ClientState state = clients[clientfd];int count = 0;try{count = clientfd.Receive(state.readBuff);}catch (SocketException e){clientfd.Close();clients.Remove(clientfd);Console.WriteLine("Receive SocketExeception:"+e.ToString());return false;}if (count == 0){clientfd.Close();clients.Remove(clientfd);return false;}string recvStr = System.Text.Encoding.Default.GetString(state.readBuff, 0, count);Console.WriteLine("Receive"+recvStr);string sendStr = clientfd.RemoteEndPoint.ToString() + ":" + recvStr;byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr);foreach (ClientState cs in clients.Values){cs.socket.Send(sendBytes);}return true;}
}

 尽管逻辑清晰,但Poll 服务端的弊端也很明显,若没有收到客户端数据,服务端也一直在循环,浪费了CPU。Poll客户端也是同理,没有数据的时候还一直在Update中检测数据,同样是一种浪费。从性能角度考虑,还有不小的改进空间。

相关内容

热门资讯

【MySQL】锁 锁 文章目录锁全局锁表级锁表锁元数据锁(MDL)意向锁AUTO-INC锁...
【内网安全】 隧道搭建穿透上线... 文章目录内网穿透-Ngrok-入门-上线1、服务端配置:2、客户端连接服务端ÿ...
GCN的几种模型复现笔记 引言 本篇笔记紧接上文,主要是上一篇看写了快2w字,再去接入代码感觉有点...
数据分页展示逻辑 import java.util.Arrays;import java.util.List;impo...
Redis为什么选择单线程?R... 目录专栏导读一、Redis版本迭代二、Redis4.0之前为什么一直采用单线程?三、R...
【已解决】ERROR: Cou... 正确指令: pip install pyyaml
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
Lock 接口解读 前置知识点Synchronized synchronized 是 Java 中的关键字,...
Win7 专业版安装中文包、汉... 参考资料:http://www.metsky.com/archives/350.htm...
3 ROS1通讯编程提高(1) 3 ROS1通讯编程提高3.1 使用VS Code编译ROS13.1.1 VS Code的安装和配置...
大模型未来趋势 大模型是人工智能领域的重要发展趋势之一,未来有着广阔的应用前景和发展空间。以下是大模型未来的趋势和展...
python实战应用讲解-【n... 目录 如何在Python中计算残余的平方和 方法1:使用其Base公式 方法2:使用statsmod...
学习u-boot 需要了解的m... 一、常用函数 1. origin 函数 origin 函数的返回值就是变量来源。使用格式如下...
常用python爬虫库介绍与简... 通用 urllib -网络库(stdlib)。 requests -网络库。 grab – 网络库&...
药品批准文号查询|药融云-中国... 药品批文是国家食品药品监督管理局(NMPA)对药品的审评和批准的证明文件...
【2023-03-22】SRS... 【2023-03-22】SRS推流搭配FFmpeg实现目标检测 说明: 外侧测试使用SRS播放器测...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
初级算法-哈希表 主要记录算法和数据结构学习笔记,新的一年更上一层楼! 初级算法-哈希表...
进程间通信【Linux】 1. 进程间通信 1.1 什么是进程间通信 在 Linux 系统中,进程间通信...
【Docker】P3 Dock... Docker数据卷、宿主机与挂载数据卷的概念及作用挂载宿主机配置数据卷挂载操作示例一个容器挂载多个目...