Unity的Socket通讯_2_数据传输
来源:互联网 发布:品茗软件客服电话 编辑:程序博客网 时间:2024/04/26 08:10
好了,已经连上服务器了,可是怎么通信,,,byte[]是个什么鬼?
好吧,来了解下数据转换吧,还记得刚学编程时,字符串转Int的Convert吗?
public void Convert() { string str = "hello world"; byte[] strbyte = Encoding.UTF8.GetBytes(str); Debug.Log(Encoding.UTF8.GetString(strbyte,0,strbyte.Length)); int n = 13; byte[] nbyte = BitConverter.GetBytes(n); Debug.Log(BitConverter.ToInt32(nbyte,0)); }
上面的就是两个常用的方法,第一个Encoding是编码类,里面有好多种编码,Utf8是万国码,你要想支持中文就得选这个。Ascii码学过汇编的都懂,就255个字符,中文指定不够用。
下面的BitConverter是值类型的转换,我是这么理解的,也没去查,说错就说错吧。
都知道string类型其实是个引用类型,说白了就是个对象,所以在转换的时候有三个参数,第一个是string,第二个是起始位置(内存的起始位置),第三个是长度(占用内存的长度)。
而BitConverter呢,只需要知道起始位置就行了,因为值类型的长度是固定的。
关于Encoding和BitConverter的内容可以上msdn查阅,我也不或者点这里了。
那上一篇的代码,我们只需要在Receive中间加入一句代码
private void Receive(IAsyncResult ar) { int size = client.EndReceive(ar); //Debug.Log("收到数据" + size); if (size < 1) { Debug.Log("服务器关闭"); closeConnect(); return; } Debug.Log(Encoding.UTF8.GetString(receiveData,0,size));//输出接受到的字符串 client.BeginReceive(receiveData, 0, receiveData.Length, SocketFlags.None, new AsyncCallback(Receive), null); }
这样我们就能把服务器发送过来的字符串编译到本地了,然后继续等待.....
然后你会发现然而并没有什么卵用,,,
是的,我们不可能只传字符串,这连聊天室的功能都满足不了,我们要传的是数据,里面有各种各样的类型,变量等!!
public static byte[] StructToBytes(object structObj)//结构体转byte[] { int size = Marshal.SizeOf(structObj);//获得结构体大小 byte[] bytes=new byte[size]; IntPtr structPtr = Marshal.AllocHGlobal(size);//从非托管内存中划片空间 Marshal.StructureToPtr(structObj,structPtr,false);//把结构体放到非托管内存中就变成byte[]了 Marshal.Copy(structPtr,bytes,0,size);//把bytes[]从内存中复制出来 Marshal.FreeHGlobal(structPtr);//清理内存 return bytes;//输出 } public static object BytesToStruct(byte[] bytes,Type type)//byte[]转结构体 { int size = Marshal.SizeOf(type);//获得结构体类型大小 if (size > bytes.Length)//类型大小比byte[]大,就跳出 return null; IntPtr structPtr = Marshal.AllocHGlobal(size);//开辟空间 Marshal.Copy(bytes,0,structPtr,size);//复制到内存中 object obj = Marshal.PtrToStructure(structPtr, type);//从非托管内存中转换成对应类型的obj托管对象 Marshal.FreeHGlobal(structPtr);//清理内存 return obj; } [Serializable]//可被序列化 [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]//整理内存布局 struct Person { public string name; public int age; } public void Test() { Person P1 = new Person(); P1.name = "叶良辰"; P1.age = 250; byte[] data = StructToBytes(P1); Person P2 = (Person)BytesToStruct(data,typeof(Person)); Debug.Log("姓名:"+P2.name+"\n年龄:"+P2.age); }
上面这个代码有些和网上的很象,没错,我就是抄的,啊,原文请点这里
序列化嘛,肯定的,设置内存布局,应该就是让这个结构体在内存中排列的规整点,我是这么猜的,说错就错了吧。
通过这段代码,我们可以把结构体转换成byte[],然后接受后再转换为对应的结构体(也可以转class),本地测试貌似没问题。
但实际上我在应用中遇到了很多问题,大部分问题出在这个托管与非托管上面,
托管就是有中间语言的,说白了.net执行的代码,非托管,就没中间语言了,系统直接执行的。
具体报什么错我忘了,毕竟好早以前的事了。
而且再看写法,发现很繁琐。
有没有不整什么托管非托管,内存不内存的1,2行代码就搞定的。
还真有,还记得struct上面的[Serializable]吗,Serializable特性,对,直接序列化就行了,好傻啊,简直是饶了一大弯。
public static byte[] ObjectToByte(object obj)//序列化 { using (MemoryStream ms = new MemoryStream())//申请流内存,结束自动收回 { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj);//序列化 return ms.GetBuffer();//取出byte[] } } public static object ByteToObject(byte[] data)//反序列化 { using (MemoryStream ms = new MemoryStream(data)) { BinaryFormatter bf = new BinaryFormatter(); return bf.Deserialize(ms);//反序列化 } } [Serializable]//可被序列化 struct Person { public string name; public int age; } public void Test() { Person P1 = new Person(); P1.name = "叶良辰"; P1.age = 250; byte[] data = ObjectToByte(P1); Person P2 = (Person)ByteToObject(data); Debug.Log("姓名:" + P2.name + "\n年龄:" + P2.age); }现在看这两个转换方法,是不是很简洁,两行代码搞定,而且反序列化也不需要知道什么类型,
最最重要的根本不用考虑什么托管与非托管,想干啥就干啥。
这样我们就可以随心所欲的在服务器和客户端之间传递任何数据了,当然,服务端必须是C#写的。
服务端是其他语言写的,目前还没研究过,等接触了再补篇吧。
关于序列化的详细内容请自行百度。
- Unity的Socket通讯_2_数据传输
- Unity的Socket通讯_1_客户端
- Unity的Socket通讯_3_粘包丢包
- winform与unity之间的Socket通讯
- udp的socket数据传输
- 【Unity】Unity3D教程:实现基于Socket通讯的公共聊天室
- 有关socket数据传输的函数
- 硬件通讯协议的数据传输方式
- delphi的socket通讯
- delphi的socket通讯
- 简单的Socket通讯
- 简单的socket通讯
- 简单的socket通讯
- Socket的TCP通讯
- BCB的SOCKET通讯
- socket数据传输
- socket数据传输
- Socket数据传输
- requirejs多重依赖的实现
- Trump成功笔记4
- 图片浏览器
- Debian 用户名密码输入成功后重复登录
- [笔记] Fake Host:网站卡在墙里半天不加载
- Unity的Socket通讯_2_数据传输
- json字符串转换为JSONObject和JSONArray
- 网页收藏
- stringstream的复制
- 四则表达式计算模板第二版
- C++流格式控制(2006-9-25 15:25:00…
- 今天学习了安装AMP服务器
- 转的编译安装Lamp
- 谈谈Qt的中文编码 又是转的