添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

游戏项目基本很难避免不与服务器端通信交互传输数据,除非你只做单机版的游戏。一般的网络游戏在游戏刚启动的时候,需要做资源热更检查处理。这里一般使用http协议,如UnityWebRequest/WWW以及HttpWebRequest等已经封装好的接口来实现。而针对在网络游戏实时同步的战斗部分,则必须实现长链接,保证数据实时传输发送与接收。一般使用TCP传输协议或者“改善”的UDP协议来实现。这边使用TCP协议。详细的网络通信原理,该系列文章不做介绍,站在项目实用的角度,讲解如何一步一步地实现。

本篇文章主要介绍字节与基本类型数据转换的工具类ByteTool如何实现。主要对BitConverter 和 MemoryStream 封装。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using System.Text;
* Author:W
* 字节读写工具
* 1.基本数据类型与字节数组的相互转换
* 2.以及从内存流中读写这些基本数据类型
namespace W.NetWork
	public class ByteTool
		/// <summary>
		/// 将字节数组写入到内存流
		/// </summary>
		/// <param name="memoryStream">内存流</param>
		/// <param name="value">目标字节数组</param>
		/// <param name="isLittleEndian">是否是小端编码</param>
		public static void WriteBytes(MemoryStream memoryStream,byte[] value, bool isLittleEndian = false)
			//如果不是小端编码,则字节数组需要翻转
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(value);
			memoryStream.Write(value,0,value.Length);
		/// <summary>
		/// 将short数据转换为Byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteShort(MemoryStream memoryStream,short value, bool isLittleEndian = false)
			byte[] bytes = BitConverter.GetBytes(value);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			memoryStream.Write(bytes,0,2);
		/// <summary>
		/// 将ushort数据转换为byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteUShort(MemoryStream memoryStream, ushort value, bool isLittleEndian = false)
			byte[] bytes = BitConverter.GetBytes(value);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			memoryStream.Write(bytes, 0, 2);
		/// <summary>
		/// 将Int型数据转换为Byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteInt(MemoryStream memoryStream, int value, bool isLittleEndian = false)
			byte[] bytes = BitConverter.GetBytes(value);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			memoryStream.Write(bytes, 0, 4);
	    /// <summary>
		/// 将uint型数据转化为byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteUInt(MemoryStream memoryStream, uint value, bool isLittleEndian = false)
			byte[] bytes = BitConverter.GetBytes(value);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			memoryStream.Write(bytes, 0, 4);
		/// <summary>
		/// 将Long型数据转换为Byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteLong(MemoryStream memoryStream, long value, bool isLittleEndian = false)
			byte[] bytes = BitConverter.GetBytes(value);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			memoryStream.Write(bytes, 0, 8);
		/// <summary>
		/// 将ulong型数据转换为Byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteULong(MemoryStream memoryStream, ulong value, bool isLittleEndian = false)
			byte[] bytes = BitConverter.GetBytes(value);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			memoryStream.Write(bytes, 0, 8);
		/// <summary>
		/// 将Float型数据转换Byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteFloat(MemoryStream memoryStream, float value, bool isLittleEndian = false)
			byte[] bytes = BitConverter.GetBytes(value);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			memoryStream.Write(bytes, 0, 4);
		/// <summary>
		/// 将Double型数据转换为Byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteDouble(MemoryStream memoryStream, double value, bool isLittleEndian = false)
			byte[] bytes = BitConverter.GetBytes(value);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			memoryStream.Write(bytes, 0, 8);
		/// <summary>
		/// 将string字符串数据转换为byte数组,并写入内存流
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="value"></param>
		/// <param name="encodingName"></param>
		/// <param name="isLittleEndian"></param>
		public static void WriteString(MemoryStream memoryStream, string value,string encodingName="utf-8", bool isLittleEndian = false)
			Encoding encoding = Encoding.GetEncoding(encodingName);
			byte[] strBytes = encoding.GetBytes(value);
			WriteUShort(memoryStream,(ushort)strBytes.Length,isLittleEndian);
			memoryStream.Write(strBytes,0,strBytes.Length);
		/// <summary>
		/// 从内存流中读取short型数据
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static short ReadShort(MemoryStream memoryStream, bool isLittleEndian = false)
			CheckReadError(memoryStream,2);
			byte[] bytes = new byte[2];
			memoryStream.Read(bytes,0,2);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			return BitConverter.ToInt16(bytes,0);
		/// <summary>
		/// 从内存流中读取ushort型数据
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static ushort ReadUShort(MemoryStream memoryStream, bool isLittleEndian = false)
			CheckReadError(memoryStream, 2);
			byte[] bytes = new byte[2];
			memoryStream.Read(bytes, 0, 2);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			return BitConverter.ToUInt16(bytes, 0);
		/// <summary>
		/// 从内存流中读取int型数据
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static int ReadInt(MemoryStream memoryStream, bool isLittleEndian = false)
			CheckReadError(memoryStream, 4);
			byte[] bytes = new byte[4];
			memoryStream.Read(bytes, 0, 4);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			return BitConverter.ToInt32(bytes, 0);
		/// <summary>
		/// 从内存流中读取uint型数据
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static uint ReadUInt(MemoryStream memoryStream, bool isLittleEndian = false)
			CheckReadError(memoryStream, 4);
			byte[] bytes = new byte[4];
			memoryStream.Read(bytes, 0, 4);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			return BitConverter.ToUInt32(bytes, 0);
		/// <summary>
		/// 从内存流中读取Long型数据
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static long ReadLong(MemoryStream memoryStream, bool isLittleEndian = false)
			CheckReadError(memoryStream, 8);
			byte[] bytes = new byte[8];
			memoryStream.Read(bytes, 0, 8);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			return BitConverter.ToInt64(bytes, 0);
		/// <summary>
		/// 从内存流中读取ulong型数据
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static ulong ReadULong(MemoryStream memoryStream, bool isLittleEndian = false)
			CheckReadError(memoryStream, 8);
			byte[] bytes = new byte[8];
			memoryStream.Read(bytes, 0, 8);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			return BitConverter.ToUInt64(bytes, 0);
		/// <summary>
		/// 从内存中读取Float型数据
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static float ReadFloat(MemoryStream memoryStream, bool isLittleEndian = false)
			CheckReadError(memoryStream, 4);
			byte[] bytes = new byte[4];
			memoryStream.Read(bytes, 0, 4);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			return BitConverter.ToSingle(bytes, 0);
		/// <summary>
		/// 从内存流中读取double型数据
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static double ReadDouble(MemoryStream memoryStream, bool isLittleEndian = false)
			CheckReadError(memoryStream, 8);
			byte[] bytes = new byte[8];
			memoryStream.Read(bytes, 0, 8);
			if (BitConverter.IsLittleEndian != isLittleEndian)
				Array.Reverse(bytes);
			return BitConverter.ToDouble(bytes, 0);
		/// <summary>
		/// 从内存流中读取特定编码的字符串
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="encodingName"></param>
		/// <param name="isLittleEndian"></param>
		/// <returns></returns>
		public static string ReadString(MemoryStream memoryStream, string encodingName = "utf-8", bool isLittleEndian = false)
			ushort length = ReadUShort(memoryStream,isLittleEndian);
			return ReadString(memoryStream,length,encodingName);
		/// <summary>
		/// 从内存流中读取特定长度特定编码的字符串
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="length"></param>
		/// <param name="encodingName"></param>
		/// <returns></returns>
		public static string ReadString(MemoryStream memoryStream, ushort length, string encodingName = "utf-8")
			CheckReadError(memoryStream, length);
			Encoding encoding = Encoding.GetEncoding(encodingName);
			byte[] strBytes = new byte[length];
			memoryStream.Read(strBytes, 0, length);
			string str = encoding.GetString(strBytes);
			return str;
		/// <summary>
		/// 读取数据检查
		/// </summary>
		/// <param name="memoryStream"></param>
		/// <param name="readSize"></param>
		public static void CheckReadError(MemoryStream memoryStream,int readSize)
			if (memoryStream.Position + readSize > memoryStream.Length)
				Debug.LogError("读取的内存流的大小超出了流本身的大小");
                    游戏项目基本很难避免不与服务器端通信交互传输数据,除非你只做单机版的游戏。一般的网络游戏在游戏刚启动的时候,需要做资源热更检查处理。这里一般使用http协议,如UnityWebRequest/WWW以及HttpWebRequest等已经封装好的接口来实现。而针对在网络游戏战斗部分,则必须实现长链接,保证数据实时传输发送与接收。一般使用TCP传输协议或者“改善”的UDP协议来实现。这边使用TCP协议。详细的网络通信原理,该系列文章不做介绍,站在项目实用的角度,讲解如何一步一步地实现。本篇文章主要介绍字节与
				
本文来自于csdn,主要讲解socket的基本概念,TCP协议通讯流程以及sockaddr数据结构等相关内容,希望对您的学习有所帮助。1、socket即为套接字,在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一的标识网络通讯中的一个进程,“IP地址+TCP或UDP端口号”就为socket。2、在TCP协议中,建立连接的两个进程(客户端和服务器)各自有一个socket来标识,则这两个socket组成的socketpair就唯一标识一个连接。3、socket本身就有“插座”的意思,因此用来形容网络连接的一对一关系,为TCP/IP协议设计的应用层编程接口称为socketAPI。内存中的多
获取名字:请求服务端给出其机器的名称。 活动连接列表:请求服务端给出当前连接的所有客户端信息(编号、IP 地址、端口等) 发消息:请求服务端把消息转发给对应编号的客户端,该客户端收到后显示在屏幕上 g) 退出:断开连接并退出客户端程序服务端接收到客户端请求后,根据客户端传过来的指令 详细介绍参考:https://biyezuopin.blog.csdn.net/article/details/125540827   游戏通信协议包含两种不同的部分:客户端和服务器(C-S)之间的交互协议游戏内部服务器(S-S)之间的交互协议。前者为了降低延迟,应该尽可能减少报文长度。同时,为了防止外挂,必须作加密处理。相反,后者在服务器之间,通信协议就可以比较灵活。  客户端和服务器的通信经过服务器的网关,经过中转分发到其他类型的服务器上或者分发给客户端。    2、客户端和服务器通信
这是我自己做的一个多人联机游戏网络部分的总结。全部为自己全新做的,没用开源软件(有一个网络游戏开源软件Raknet)。目的是写一个属于自己的可靠网络模块,修改、扩展后在很多地方都能用得着。也想自己从上至下完全写一遍,对网络编程有更深的理解。代码已经实现完并投入实际使用,由于公司网络限制是不能上传和外发的,所以不能公布了。这里把设计和遇到的问题跟大家分享。 1       设计、实现
建议使用网络通信来进行数据传输和通讯。常见的网络协议有 TCP 和 UDP,可以根据游戏的特点和需求来选择合适的协议。另外,对于游戏网络通信,还可以使用第三方库和框架,如 Unity 的 UNET 或 Unreal Engine 的 Unreal Networking,来简化网络通信实现
使用Java利用socket通信可以实现Modbus-RTU通信协议实现空调对接。Modbus-RTU是一种常用的串行通信协议,可以实现设备之间的数据传输。 首先,需要在Java中使用socket实现网络通信。通过创建服务器端socket和客户端socket,可以建立通信连接。服务器端socket监听指定端口,等待客户端的连接请求,客户端socket则主动发起连接请求。 然后,根据Modbus-RTU通信协议,需要实现相应的功能码来进行数据的读取和写入。常用的功能码包括读功能码(0x03)和写功能码(0x06)。通过Java的输入输出流,可以向设备发送相应的Modbus-RTU命令,然后读取或写入数据。 在空调对接的过程中,需要调用空调设备的相关API来实现具体的操作。首先需要对空调进行初始化配置,如设置波特率、数据位、停止位等参数。然后可以通过发送读功能码来获取空调的状态信息,如温度、湿度等。通过发送写功能码,可以实现对空调进行控制,如调节温度、开关机等。 需要注意的是,Modbus-RTU通信协议是基于串行通信的,而Java的socket通信是基于网络通信的,两者之间存在差异。因此,在进行空调对接时,需要将串行通信转换为网络通信,将串行口转换为网络socket,并进行相应的协议转换和数据处理。 综上所述,利用Java的socket通信可以实现Modbus-RTU通信协议实现空调对接。通过实现相应的功能码和调用空调设备的API,可以实现空调的读取和控制操作。
你好,作者,我用的是Unity2019,当我导入你的工具后,Excel路径也设置了,但却报空指针: NullReferenceException: Object reference not set to an instance of an object W.GameFrameWork.ExcelTool.ExcelConvertEditor.ConvertToJson (System.String fileName, System.String fileFromPath, System.String fileOutPath) (at Assets/ExcelTool/Editor/ExcelConvertEditor.cs:174) Unity发布抖音小游戏:构建与发布 细水长流丶: 博主,unity的CCD申请你是绑定的腾讯云吗,我现在去弄CCD试用,发现只能绑定银行卡,是不是我没找对地方哦