您的位置:首页 > 移动开发 > Unity3D

C# client 与java netty 服务端的简单通信,客户端采用Unity。

2017-05-19 10:09 477 查看
http://blog.csdn.net/wilsonke/article/details/24721057


C# client 与java netty 服务端的简单通信,客户端采用Unity。

近日根据官方提供的通信例子自己写了一个关于Unity(C#)和后台通信的类,拿出来和大家分享一下。

具体请参考:

1.Java服务端用的apach.mina框架搭建。java服务端请参考:http://blog.9tech.cn/?c=site&m=article&id=548

2.C#环境:.NET framework 2.0

3.C#帮组文档,及Socket注解:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket(v=vs.85).aspx

4.官方例子:http://msdn.microsoft.com/zh-cn/library/bew39x2a(v=VS.85).aspx#CommunityContent

 

个人觉得,最难的地方在与以下几个地方:

1.封装数据,和后台的编解码格式保持一致

   封装数据,其实就是一个前后台约定好一个通信格式。比如:获得所以数据后并写入字节数组后,在吧这个字节数组的长度读出来(4个字节的整形数据),再封装进一个字节数组中。

    所以最终的数据字节数组内容是:4个字节的数据长度+实际数据的字节数组。

当然数据的加密加压可以在吧实际数据存入字节数组后就进行,那么发送的长度就是加密加压后的数据长度了。

实现方法:

2.异步通信的线程管理

    异步通信的线程安全一直是一个难点,它不像ActionScript那样,建立通信连接后注册事件用来侦听即可。但是在C#中就必须让线程等待当前的异步操作完成后才可以继续向下执行。C#异步通信中可以使用ManualResetEvent类来处理这类问题。当需要暂停执行后续代码以完成异步操作时。使用ManualResetEvent的WaitOne();方法来阻塞这个线程(类似与java的ReentrantLock类),但是必须在异步操作完成后使线程恢复,否则就会出现线程被锁死的情况。使用ManualResetEvent的Set()方法即可。

实现方法:
ManualResetEvent类的帮组文档及例子:http://msdn.microsoft.com/zh-cn/library/system.threading.manualresetevent_members(v=vs.85).aspx

3.关于数据的压缩,和解压.

    对于数据的压缩和解压可以采用ICSharpCode.SharpZipLib这个动态链接库。下载地址:http://www.icsharpcode.net/opensource/sharpziplib/

下载后再MonoDevelop里倒入引用就可以了,位置:Project->Edit References..  

using ICSharpCode.SharpZipLib.Zip;

然后在代码里就可以倒入类了

参考:http://blog.sina.com.cn/s/blog_62fda93c0101d51j.html

4.接收和读取数据的操作

    在接受服务端发送的数据时,也根据同样的格式进行解读;先读取4个字节的数据长度,再跟进这个长度得到实际的数据,最后在解密和解压就可以得到最终的数据了。

    但是在这个操作过程中,会出现一些意想不到的麻烦。

    大致流程是:

    采取分段读取的方式,第一次只读取4个字节的长度信息。

    取得长度后,根据设置的每次分段读取数据长度来读取,知道所得的数据和总长度相同;

    每次分段读取的数据的长度不一定都是设置的长度,所以将每次读取的数据写入内存流MemoryStream类中。特别重要的每次操作MemoryStream类时注意设置它的Position位置,不然会出现你本来已经成功的存入了数据,但是由于Position的原因没有找准需要取出或者存入数据的准确位置而读取数据失败。

详细代码如下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: