C# client 与java netty 服务端的简单通信,客户端采用Unity。
2017-05-19 10:09
477 查看
http://blog.csdn.net/wilsonke/article/details/24721057
近日根据官方提供的通信例子自己写了一个关于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的原因没有找准需要取出或者存入数据的准确位置而读取数据失败。
详细代码如下:
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个字节的数据长度+实际数据的字节数组。
当然数据的加密加压可以在吧实际数据存入字节数组后就进行,那么发送的长度就是加密加压后的数据长度了。
实现方法:
异步通信的线程安全一直是一个难点,它不像ActionScript那样,建立通信连接后注册事件用来侦听即可。但是在C#中就必须让线程等待当前的异步操作完成后才可以继续向下执行。C#异步通信中可以使用ManualResetEvent类来处理这类问题。当需要暂停执行后续代码以完成异步操作时。使用ManualResetEvent的WaitOne();方法来阻塞这个线程(类似与java的ReentrantLock类),但是必须在异步操作完成后使线程恢复,否则就会出现线程被锁死的情况。使用ManualResetEvent的Set()方法即可。
实现方法:
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的原因没有找准需要取出或者存入数据的准确位置而读取数据失败。
详细代码如下:
相关文章推荐
- C# client 与java netty 服务端的简单通信,客户端采用Unity。
- Java中利用socket实现简单的服务端与客户端的通信(中级)——实现任意双向通信
- Java简单实现TCP服务端和客户端通信
- socket ( java ) 简单客户端、服务端通信
- socket ( java ) 简单多个客户端、服务端通信(多线程)
- (C#:Socket)简单的服务端与客户端通信。
- C# SOCKET编写的简单聊天通信程序(客户端+服务端)
- Unity使用C#实现简单Scoket连接及服务端与客户端通讯
- C#网络编程.2.套接字.TcpListener.TcpClient.服务端客户端通信
- Java中利用socket实现简单的服务端与客户端的通信(入门级)
- Java简单实现UDP服务端和客户端的通信
- JAVA 服务端和客户端Socket通信的简单例子
- JAVA与C#的TCP通信——JAVA客户端,C#线程池服务端
- Java review--NIO实例:实现服务端和客户端的简单通信
- socket ( java ) 简单多个客户端、服务端通信(多线程)
- 通过XMLRPC简单构建 python服务端和C#客户端通信框架
- java网络编程之服务端客户端socket简单通信案例
- Java中利用socket实现简单的服务端与客户端的通信(基础级)
- 使用socket实现简单的客户端和服务端通信(C#语言)
- C#网络编程.2.套接字.TcpListener.TcpClient.服务端客户端通信