[英]Send binary file from Java Server to C# Unity3d Client with Protocol Buffer
我问了这个问题https://stackoverflow.com/questions/32735189/sending-files-from-java-server-to-unity3d-c-sharp-client但我发现这不是发送文件的最佳解决方案通过内置操作在Java和C#之间切换,因为我还需要其他消息,不仅是文件内容。
因此,我尝试使用Protobuf,因为它速度快并且可以独立于平台对对象进行序列化/反序列化。 我的.proto文件如下:
message File{
optional int32 fileSize = 1;
optional string fileName = 2;
optional bytes fileContent = 3;
}
因此,我在生成的.java文件中为每个变量设置值:
file.setFileSize(fileSize);
file.setFileName(fileName);
file.setFileContent(ByteString.copyFrom(fileContent, 0, fileContent.length);
我看到了许多有关如何将对象写入文件和从文件读取的教程。 但是,我找不到任何有关如何从服务器套接字向客户端套接字发送文件的示例。
我的意图是在Java服务器上序列化对象(文件大小,文件名和文件内容),并将这些信息发送到C#客户端。 因此,可以反序列化文件并将其存储在客户端。
在上面的示例代码中,服务器读取文件(图像文件)的字节并将其写入输出流,以便客户端可以通过输入流将字节读取和写入磁盘。 我想通过对生成的.proto文件进行序列化来实现相同的目的。
谁能给我一个例子或给我一个提示,怎么做?
如文档中所述,protobuf不会处理消息的开始和停止位置,因此在使用像TCP这样的流套接字时,您必须自己做。
从文档中:
[...]如果要将多个消息写入单个文件或流,则由您决定一条消息的结束位置和下一条消息的开始位置。 协议缓冲区连线格式不是自定界的,因此协议缓冲区解析器无法确定消息在何处结束。 解决此问题的最简单方法是在编写消息本身之前先编写每个消息的大小。 当您读回消息时,您将读取大小,然后将字节读取到单独的缓冲区中,然后从该缓冲区进行解析。 [...]
长度前缀是一个不错的选择。 根据您正在编写的语言,有些库可以为例如TCP使用长度前缀,也可以自己定义。
线路上缓冲区的示例表示形式可能是(格式从左边开始):
[buf_length|serialized_buffer2]
因此,您在发送之前将代码打包以包装缓冲区可能看起来像(这在带有node.js的javascript中):
function pack(message) {
var packet = new Buffer(message.length + 2);
packet.writeIntBE(message.length, 0, 2);
message.copy(packet, 2);
return packet;
}
要阅读,您必须做相反的事情:
client.on('data', function (data) {
dataBuffer = Buffer.concat([dataBuffer, data]);
var dataLen = dataBuffer.readIntBE(0, 2);
while(dataBuffer.length >= dataLen) {
// Message length excluding length prefix of 2 bytes
var msgLen = dataBuffer.readIntBE(0, 2);
var thisMsg = new Buffer(dataBuffer.slice(2, msgLen + 2));
//do something with the msg here
// Remove processed message from buffer
dataBuffer = dataBuffer.slice(msgLen + 2);
}
});
您还应该知道,在TCP套接字上发送多个协议缓冲区时,它们可能会被缓冲以进行网络优化(连接)并一起发送。 意味着无论如何都需要某种分隔符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.