我正在编写一个多人游戏,我很难用udp数据包的大小。我想通过udp数据包发送多个敌人的统计数据(hp,position,id)。以下是重要的代码部分:
Byte[] datagramPacketData = ("11" + String.valueOf(entityAmount) + "," + gamename + "," + username + entitiesToBeSent).getBytes();
如您所见,我将所有数据合并为一个String,然后在发送之前将其转换为byte []。但是字符消耗的字节数比小的字节数(对于id和位置)和long(hp)要多得多。 例如:一个暴徒有2.000.000马力。该数字将消耗7个字符(= 7个字节),但它只需要4个字节。如何在不使用对象流的情况下使用更少的字节来发送所有这些数据?
我会对一些建议感到高兴! 非常感谢你提前。
答案 0 :(得分:0)
首先,如果您的数据足够小以适应单个数据包,则UDP消息长度不太可能产生太大差异。除非你有具体证据证明数据包大小是一个关键问题,否则我建议你不要在这个问题上出汗。即硬基准测试结果表明您无法维持游戏所需的最小传输速率超过特定数据包大小。 (针对实际不存在的问题进行优化是浪费精力。)
如果您担心消息长度,那么您应该使用字符串编码(如上所述)和二进制编码进行比较;例如就像你使用DataInputStream
和DataOutputStream
一样。
byte
编码为单个八位字节short
或char
将被编码为两个八位字节有关详细信息,请参阅DataOutputStream
javadocs。
不要使用对象流。它们使用与DataOutputStream
相同的二进制编码,但是编码类型信息和对象标识会产生大量额外开销。
答案 1 :(得分:0)
我现在已经尝试了,它适用于String,但不是或很长。我无法弄清楚自己的错误,你可以找到错误吗? 这是它:
发件人方:
byte[] data = new byte[1024];
int i = 0;
String packetNumber = "25";
ByteBuffer buffer0 = ByteBuffer.allocate(2);
buffer0.put(packetNumber.getBytes());
byte[] numberInByte = buffer0.array();
int x = 0;
for (int k = i; k < numberInByte.length; k++) {
data[k] = numberInByte[x];
x++;
i++;
}
long life = 2000000;
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(life);
byte[] lifeInByte = buffer.array();
x = 0;
for (int k = i; k < lifeInByte.length; k++) {
data[k] = lifeInByte[x];
x++;
i++;
}
接收方:
ByteBuffer byteBuffer = ByteBuffer.wrap(data);
byte[] packetNumber = new byte[2];
byteBuffer.get(packetNumber);
System.out.println(new String(packetNumber));
long life = byteBuffer.getLong();
System.out.println(life);
输出是: 25(这是对的) 1966080(这不是2000000,但为什么?)