1, Socket粘包解包过程,传输数据的压缩是如何做的?
解决数据分包和粘包的基本策略如下
消息定长: 比如一个100,那么读取端每次读取数据就截取100个长度的数据,然后交给业务成去做解析
在消息尾部加一些特殊字符,那么在读取数据的时候,只要读取到这个特殊字符,就认为已经可以截取一个完整的数据包了.这种情况在一定的业务情况下实用.
读取缓存的数据时不定长的,所以我们把读取到的数据添加到我们自己的一个byte[]数组中,然后根据我们的业务逻辑来找到指定的特殊协议头部,协议长度,协议尾部,然后从我们byte[]中获取一个完整的数据包,然后在对数据包进行业务解析就可以得到正确结果.
Socket发送的内容是什么
发送内容可以是数字,字符串,或者是对象,但是他们在传输的过程中都将被转化为字节流
Socket的心跳实现是如何实现的
"心跳包"就是服务器端和客户端约定好的一种数据
所谓"心跳包"机制,其实就是服务器端按照固定的频率给客户端发送心跳包,客户端接受到心跳包之后做回应.如果服务器发送了一个心跳包,客户端没有回应,服务器认为客户端已经不再了.就回断开长连接
说明:服务器只是在客户端长时间没有给服务器发送数据的情况下,才会发送心跳包
客户端每隔一个时间间隔发送一个探测包给服务器
客户端发包时启动一个超时定时器
服务器端接收到检测包,应该回应一个包
如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器
如果客户端的超时定时器超时,依然没有收到应打包,则说明服务器挂了
如何实现断线重连
粗略的做法是,当客户端调用send或recv失败,然后WSAGetLastError()判断错误编号,然后关闭socket,在创建一个socket,然后进行connect操作.
正常操作:
客户端维护一个线程安全的待发送信息队列
开启死循环
判断Socket=null
调用Socket的sendUrgentData(OxFF)发送1个字节的心跳包
捕捉到连接异常后就关闭IO和Socket连接
读取队列内容,如果队列为空就休眠3秒,然后continue
遍历待发送消息队列,一次发送里面的内容
全部发送成功后清空队列
如果socket为null说明断开连接;重建socket连接,并开启IO
重建连接时如果连接不上,出现异常,那就休眠10秒,之后进入新一轮循环
TCP/IP,UDP实现有什么区别?HTTP有什么优势
TCP连接在客户端和服务端数据通信前,会进行三次确认才会正式建立连接,也即是三次握手.特点是面向连接,适合进行大数据量,持续连接的网络通讯,
UDP连接无连接,不需要确认连接,即可进行数据通信,特点是无连接,适合小数据量,高突发性,高频率的网络通信
AssetBundle 加载资源的过程是:
点了运行之后,将我在StreamAssets下生成的AB包Copy到C盘中的某个路径
开启更新模式 会从服务器下载一份file.txt和本地进行MD5的比对
若不一样会从服务器下载对应的MD5值文件 放到C盘 完成更新
然后启动框架,会调用Game的OninitOK方法
资源加载的方式都有哪些
1.Resource.load(string path)
优点: 同步 ,使用方便
缺点:只能加载Resource目录下的资源
2.WWW
优点:灵活,可以加载Application.streamingAssetsPath,Application.persistentDataPath目录下的资源,以及从网络上下载资源
缺点:异步,如果业务需要按需加载资源,容易打散逻辑
3.AssetBunlde.CreateFromFile(string path)
优点:同步,可以加载Application.persistentDataPath目录下的AssetBundle
缺点:AssetBundle不能压缩,在Android下不能加载Application.streamingAssetsPath下的AssetBundle
4, AssetBundle.CreateFromMemorylmmediate(byte[]bunary)
优点:同步,可以加载Application.persistentDataPath目录下压缩过的AssetBundle
缺点:在Andriid下不能加载Application.streamingAssetsPath下的AssetBundle
4,图集打包注意图集的大小和分辨率
5, NGUI和UGUI的区别?他们的适配都是如何去做的
UGUI的Canvas有世界坐标和屏幕坐标
UGUI的Image可以使用material
UGUI通过Mask来裁剪,而NGUI通过Panel的Clip
NGUI的渲染前后顺序是通过Widget的Depth,而UGUI的渲染顺序根据Hierarchy的顺序,越下面渲染在顶层
UGUI不需要绑定Colliders,UI可以自动拦截事件
UGUI的Anchor是相对父对象,没有提供高级选项,个人感觉UGUI的Anchor操作起来比NGUI更方便
UGUI没有Atlas一说,使用Sprite Packer
UGUI的Navigation在Scene中能可视化
UGUI的事件需要实现事件系统的接口,但写起来也算简单
Lua和C#是如何调用的,
Lua调用C#:
1.判断其实否注册 2. 生成(点击Lua->Clear wrap files->确定)
如果一个c#方法要被Lua调用,则首先需要将其注册到Lua虚拟机中(LuaState.RegisterFunction),之后再Lua中就可以通过注册的名称来调用这个C#方法
2. 如果C#要调用Lua中的函数,则:
首先要在Lua虚拟机中加载该函数(LuaState.Dofile)
拿到目标函数(LuaState.GetFunction)
执行目标函数(LuaFunction.Call)
C#调用lua
C#通过Pinvoke方式调用了lua的dll(一个c库),然后这个dll执行了lua脚本
Lua的优化有哪些
使用局部变量
预设物的优点有哪些
在游戏运行时实例化,Prefab相当于一个模板,对你已有的素材,脚本,参数,做一个默认配置,以便于以后修改,同时prefab打包的内容简化了导出的操作,便于团体的交流
当你场景中有大量相似的物体.如游戏中的小怪时就可以用frefab来对这些物体进行统一管理,这样当你需要修改物体属性时,只要修改一个物体,然后apply给prefab其他的物体也就一起改好了.还有当你需要用代码动态创建物体是也是用prefab的
ArrayList和List有何区别
在声明List集合时,我们需要为其声明List集合内数据的对象类型
而ArrayList会把所有插入的数据都当做object来处理
ArrayList存在不安全类型
装箱拆箱操作
请描述Interface与抽象类之间的区别
接口不是类,不能实例化,抽象类可以间接实例化
接口是完全抽象,抽象类为部分抽象
接口可以多继承 抽象类是单继承
线程和协程之间有何区别
多线程程序同时运行多个线程,而在任一指定时刻只有一个协程在运行,并且这个正在运行的协同程序只在必要时才被挂起.除主线程之外的线程无法访问Unity的对象,组件,方法.
unity没有多线程的概念,不过unity也给我们提供了StartCoroutine(协同程序)和LoadLevelAsync(异步加载关卡)后台加载场景的方法.
所谓协同:就是当你在StartCoroutine的函数体里处理一段代码时,利用yield语句等待执行结果,这期间不影响主程序的继续执行,可以协同工作.而LoadLevelAsync则允许你再后台加载新资源和场景,所以在利用协同,你就可以前台用loading条或动画提示玩家游戏未卡死,同时后台协同处理加载的事宜.
值类型和引用类型的区别
区别:值类型存储在内存栈中,引用类型数据存储在内存堆中,而内存单元中存放的是堆中存放的地址.
值类型存取快,引用类型存取慢
值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针和引用.
栈的内存是自动释放,堆内存是.NET中会由GC来自动释放
值类型继承自System.ValueType,引用类型继承自System.Object.
委托和事件有何区别
委托允许直接通过委托去访问相应的处理函数,而事件只能通过公布的回调函数去调用
事件只能通过"+=""-="方式注册和取消注册处理函数,而委托除此之外还可以使用"="直接赋值处理函数.事件只能在当前定义的类结构中调用,不能再外部调用.
如何去掉敏感字
string s = "坏蛋"
s.Replace("坏蛋","**")