Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将数据从C#客户端发送到Java服务器-数据不一致。_Java_C# - Fatal编程技术网

将数据从C#客户端发送到Java服务器-数据不一致。

将数据从C#客户端发送到Java服务器-数据不一致。,java,c#,Java,C#,我不确定这里的问题是什么,但我发送到Java的所有数据似乎都被破坏了。它在Java客户机上运行完全正常,我已经验证了两种语言之间每个原语的字节大小 我将从客户机的C#方面开始,因为我已经非常简单: 这是PacketBuilder类 /// <summary> /// Used to build a instance of the <see cref="UnityNetworking.Packet"/> class. /// </summary>

我不确定这里的问题是什么,但我发送到Java的所有数据似乎都被破坏了。它在Java客户机上运行完全正常,我已经验证了两种语言之间每个原语的字节大小

我将从客户机的C#方面开始,因为我已经非常简单:

这是PacketBuilder类

/// <summary>
    /// Used to build a instance of the <see cref="UnityNetworking.Packet"/> class.
    /// </summary>
    public class PacketBuilder {

        /// <summary>
        /// The opcode of the packet being built.
        /// </summary>
        private int Opcode;

        /// <summary>
        /// The stream to write data to the packet's buffer.
        /// </summary>
        private MemoryStream stream;

        /// <summary>
        /// The binary writer to convert data into binary format.
        /// </summary>
        private BinaryWriter writer;

        /// <summary>
        /// The String encoder.
        /// </summary>
        private Encoding encoder;

        /// <summary>
        /// Create a new PacketBuilder instance with the specified opcode and a default capacity.
        /// </summary>
        /// <param name="opcode">The opcode.</param>
        public static PacketBuilder Create(int opcode) {
            return new PacketBuilder (opcode, 512);
        }

        /// <summary>
        /// Create a new PacketBuilder instance with the specified opcode and capacity.
        /// </summary>
        /// <param name="opcode">The opcode.</param>
        /// <param name="capacity">The buffer capacity.</param>
        public static PacketBuilder Create(int opcode, int capacity) {
            return new PacketBuilder (opcode, capacity);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="UnityNetworking.PacketBuilder"/> class.
        /// </summary>
        /// <remarks>Private scope to prevent outside library instantiation.</remarks>
        private PacketBuilder (int opcode, int capactiy) {
            Opcode = opcode;
            stream = new MemoryStream (capactiy);
            writer = new BinaryWriter (stream);
            encoder = new UTF8Encoding (true, true);
        }

        /// <summary>
        /// Adds the specified data to the builders buffer.
        /// </summary>
        /// <param name="data">The data.</param>
        public PacketBuilder Add(object data) {
            if (data is Int16) {
                writer.Write ((short)data);
            } else if (data is Int32) {
                writer.Write ((int)data);
            } else if (data is Int64) {
                writer.Write ((long)data);
            } else if (data is Single) {
                writer.Write ((float)data);
            } else if (data is Double) {
                writer.Write ((double)data);
            } else if (data is Byte) {
                writer.Write ((byte)data);
            } else if (data is Boolean) {
                writer.Write ((bool)data);
            } else if (data is String) {
                string str = (string)data;
                byte[] bytes = encoder.GetBytes (str);
                writer.Write ((short)bytes.Length);
                writer.Write (bytes, 0, bytes.Length);
            } else {
                throw new Exception ("Unsupported Object Type: " + data);
            }
            Debug.Log ("Data Type: " + data.GetType() + " || Value: " + data);
            return this;
        }

        public Packet ToPacket() {
            return new Packet(Opcode, stream.ToArray());
        }
    }
这是通过客户端类中的
Write(Packet)
方法发送的,可在此处找到:

public NetworkClient Write(Packet packet) {
    networkStream.Write (packet.Buffer, 0, packet.Size);
    return this;
}
非常基本:现在在Java端,所有内容都被放入一个
ByteBuffer
中,该数据是使用
getX
方法获取的

我获取这些数据的方法如下:

public boolean handle(long userId, Session session, Packet packet) {
    ByteBuffer buffer = packet.getBuffer();
    byte opcode = buffer.get();
    userId = buffer.getLong();
    System.out.println("Opcode: " + opcode + " || User ID: " + userId);
}
这将输出以下行:

Opcode: 1 || User ID: 4108690235045445632
我一点也不明白到底发生了什么,尤其是1337怎么会变成只有上帝知道的数字。从客户端进行调试时,将显示以下信息:

Data Type: System.Byte || Value: 1
Data Type: System.Int64 || Value: 1337

所以,如果有人能告诉我发生了什么,那就太好了

您的64位整数有不同的字节顺序

您得到的值是1337L,即0x0539。如果反转此字节值,则得到0x3905000000000000。将其转换为十进制,得到4108690235045445632


通常,当通过网络发送原始数据(如数据包)时,您将使用lton(值)发送,以及ntol(值)发送您接收的值。我不确定C#和Java的等价物是什么,但它们是“长到网络”和“网络到长”函数。类似地,您可以对short和其他类型(8位值除外)执行此操作。

BinaryWriter使用小端编码,而Java使用大端编码。这意味着
Int64
的最低有效字节首先用C#编写,Java解释具有最高有效字节的字节


在这里查看强制C端使用Big-Endian的方法:

这可能是一个问题,具体取决于机器。我知道Java是big-endian,我认为Intel机器是little-endian。因此,如果您的C#程序运行在基于Intel的机器上,这可能是您的问题。Java在规范中使用big-endian,并
DataOutputStream
使用它。在Java中使用little endian需要额外的工作。C#不定义尾数,但
BinaryWriter
使用很少的尾数。因此,在C#中使用big-endian需要额外的工作。@Icemandind-您可能打算对Op进行评论。是的,显然是Endianness问题。@Les-感谢您对反转字节值的说明,我已经解决了这个问题,现在我所有的网络都可以从客户端->服务器完美地工作。现在,我只需要从服务器->客户端反转这个过程。再次感谢。
Data Type: System.Byte || Value: 1
Data Type: System.Int64 || Value: 1337