版权声明:本文为原创文章,转载请声明
上一篇主要说的是protobuf字节流的序列化和解析,将protobuf对象序列化为字节流后虽然可以直接传递,但是实际在项目中却不可能真的只是传递protobuf字节流,因为socket的tcp通讯中会出现几个很常见的问题,就是粘包和少包。所谓粘包,简单点说就是socket会将多个较小的包合并到一起发送。因为tcp是面向连接的,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。少包则是指缓存区满后,soket将不完整的包发送到接收端(按我的理解,粘包和少包其实是一个问题)。这样接收端一次接收到的数据就有可能是多个包,为了解决这个问题,在发送数据之前,需要将包的长度也发送出去。于是,包的结构就应该是 消息长度+消息内容。
这一篇,就来说说数据的拼接,干货来了
首先的拼接数据包
1 |
|
代码中使用的ByteBuffer工具java中有提供,但是c#中是没有的,源码摘至,不过作者并未在工具中添加获取所有字节码的方法,所以自己添加了一个GetBytes()方法
1 |
|
当然,c#中虽然没有ByteBuffer,但也有拼接字节数组的方法,比如
1 2 |
|
字节数组拼接好后,就可以使用socket的send方法发送了,不过这一篇先继续讲完接收数据的处理
接收数据的顺序是先接收消息长度,然后根据消息长度接收指定长度的消息
1 |
|
GetBytesRecive方法用于接收消息,并解决粘包、少包的问题,代码如下
1 |
|
到这里,消息的简单发送和接收就基本搞定了,但是,实际项目中,我们的消息数量肯定不会只有一条,如果是长链接的项目,更是需要一直接收和发送消息,该怎么办?
众所周知,unity的UI上的显示只能在主线程中执行,可是如果我们在主线程一直接收和发送消息,那体验将会极差,所以我们必须另外开启线程来负责消息的接收和发送,下一篇就是使用多线程来完成socket通讯
Atas ialah kandungan terperinci socket传输protobuf字节流的实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!