【发布时间】:2011-05-14 18:12:07
【问题描述】:
当通过套接字从 java 应用程序向 C# 应用程序发送信息时,字节顺序是否不同?或者我可以将一个整数从 C# 发送到 Java 应用程序并将其读取为整数吗?
(操作系统是否重要,或者对于 java/.net 是否相同,无论实际操作系统如何处理它?)
【问题讨论】:
当通过套接字从 java 应用程序向 C# 应用程序发送信息时,字节顺序是否不同?或者我可以将一个整数从 C# 发送到 Java 应用程序并将其读取为整数吗?
(操作系统是否重要,或者对于 java/.net 是否相同,无论实际操作系统如何处理它?)
【问题讨论】:
这一切都取决于您如何对数据进行编码。如果您仅将其视为原始字节序列,则没有冲突;顺序是一样的。当问题是字节序时解释数据块作为(例如)整数。
任何序列化程序考虑到可移植性都会定义字节序 - 例如,在协议缓冲区(Java 和 C# 都可用)中总是使用小字节序 无论您的本地硬件如何。
如果您要手动写入流,使用诸如基于移位的编码(而不是直接内存复制)之类的方法将为您提供定义的字节序。
如果您使用预装的平台序列化程序,您将受到实现的摆布。它可能是字节序安全的,也可能不是(即它可能取决于两端的平台)。例如,.NET BitConverter 类是不安全的——通常(错误地)假设它是小端的,但在某些平台上(尤其是在某些硬件上的 Mono 中)它可能是大端;因此.IsLittleEndian 属性。
我的建议是使用一个序列化程序来为你处理这一切;p
【讨论】:
在 Java 中,您可以使用 DataInputStream 或 DataOutputStream 先读取和写入高字节,如文档所述:
http://download.oracle.com/javase/6/docs/api/java/io/DataOutputStream.html#writeInt%28int%29
您应该查看相应的 C# 文档以了解它的作用(或者这里有人可以告诉您)。
在 Java 中,您还可以选择使用 ByteByffer:
http://download.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html
...它具有“order”方法,允许您为读取多字节原始类型的操作指定字节顺序。
【讨论】:
Java 将 Big Endian 用于一些库,例如 DataInput/OutputStream。 IP 协议都使用 Big Endian,这会导致人们将 Big Endian 用作网络协议的默认设置。
但是 NIO,ByteBuffer 允许您指定 BigEndian、LittleEndian 或 NativeEndian(系统默认使用什么)
x86 系统倾向于使用小端,因此许多 Microsoft/Linux 应用程序默认使用小端,但可以支持大端。
【讨论】:
是的,字节顺序可能不同。 C# assumes little-endian 可能使用平台的字节顺序,Java 倾向于使用 big-endian。这已经在 SO 上讨论过。参见例如C# little endian or big endian?
【讨论】:
BitConverter 等),但它们使用平台字节序,在某些平台上可能会有所不同