从套接字读取消息时如何获取字节序?

huangapple go评论89阅读模式
英文:

How to get the endianness when reading a message from socket?

问题

我正在使用go协议缓冲go程序将编码的协议缓冲消息发送给连接到套接字的客户端。由于协议缓冲没有分隔符,客户端不知道从套接字中读取多少数据。

我计划在消息前面加上消息长度,一个32位整数。这样客户端可以读取4个字节,获取长度并读取完整的消息。

我可以使用binary包将整数值放入字节数组中,类似于:

binary.Write(buf, binary.LittleEndian, value)

现在的问题是,write需要一个字节顺序,接收端如何知道字节顺序是什么?有没有一种方法可以在不指定显式字节顺序的情况下处理这个问题?

英文:

I am using go and protocol buffers. go program sends encoded protocol buffer messages to clients connected to the socket. Now since protocol-buffers is not delimited, clients don't know how much data to read from the socket.

I am planning to prefix the message with the message length, a 32bit integer. So clients can read 4 bytes, get the length and read the full message.

I can put an integer value into the bytes array using binary package. Something like,

binary.Write(buf, binary.LittleEndian, value)

Now the question is, write needs a byte order and how will the receiving end know what is the byte order? Is there a way to deal with this without specifying explicit byte order?

答案1

得分: 6

约定是网络字节顺序为大端序,但是你的客户端和服务器在任何情况下都必须达成一致。请明确指定字节顺序。

编辑:根据Protobuf文档的阅读,为了保持一致性,最好使用proto.EncodeVarintproto.DecodeVarint在消息之前写入长度。

英文:

The convention is that network byte order is big endian, but your client and server must agree in any case. Specify the byte order explicitly.

Edit: Reading the Protobuf docs, it might be better to use proto.EncodeVarint and proto.DecodeVarint to write the length before the message, for the sake of consistency.

答案2

得分: 2

你应该始终明确定义和记录字节顺序(和布局)。在一般通信中,大端直接布局似乎是常态(所以47将是4个字节,十六进制值为00 00 00 2F)。然而,你可能需要考虑具体的上下文。例如,如果你已经在讨论protobuf,你也可以使用“varint”编码格式,这种情况下47是一个字节:2F - 许多protobuf实现将提供预定义的方法来消费或生成varint(否则,可以在这里找到文档 - 但可以概括为7位有效负载和连续位,最低有效的7位组先出现)。

英文:

You should always explicitly define and document the byte order (and layout) on such things. In general communications, big-endian direct layout seems to be the norm (so 47 would be 4 bytes with hex values 00 00 00 2F). However, you might want to take specific context into consideration. For example, if you are already talking protobuf, you could also use the "varint" encoding format, in which case 47 is a single byte: 2F - many protobuf implementations will provide pre-rolled methods to consume or produce a varint (otherwise, it is documented here - but can be summarised as 7-bit payload with continuation bit, with the least-significant 7-bit group first)

huangapple
  • 本文由 发表于 2014年2月13日 19:45:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/21753306.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定