gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 11:03:06 24 4
gpt4 key购买 nike

我不确定这里的问题是什么,但似乎我发送到 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());
}
}

如您所见,此类使用 MemoryStreamBinaryWriter 作为我要发送的示例 我将使用 long 值或在 C# 中通常称为 Int64

    PacketBuilder builder = PacketBuilder.Create(1);
builder.Add((byte)1);
builder.Add(1337L);
client.Write(builder.ToPacket());

这是通过 Client 类中的 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(value) 之类的东西来发送,并使用 ntol(value) 来处理您收到的值。我不确定 C# 和 Java 的等价物是什么,但这些是“long to network”和“network to long”函数。同样,您可以对 short 和其他类型(8 位值除外)执行此操作。

关于java - 从 C# 客户端向 Java 服务器发送数据 - 数据不一致。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30539887/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com