Java 将一个短字符放入2字节的字符串中
因此,我正在为一个在线游戏制定自己的网络协议,为了节省空间,每个消息(通过TCP发送)都有一个短的ID,2个字节,所有从服务器发送到客户端的消息,反之亦然,都是字符串,我如何在java中用2个字节(字符)将短消息转换为字符串 更新:我可能不清楚我想要什么。。。 我希望能够将一个短整型转换为2个字符,这样我就可以在网络上以字符串格式发送短整型,只需2个字节,然后在另一端将其解码为短整型(在actionscript 3中) 一个字符可以容纳256个可能的值,对吗?所以256*256=65536,这是一个无符号短整数的大小 以下是到目前为止我得到的信息:Java 将一个短字符放入2字节的字符串中,java,string,actionscript-3,byte,short,Java,String,Actionscript 3,Byte,Short,因此,我正在为一个在线游戏制定自己的网络协议,为了节省空间,每个消息(通过TCP发送)都有一个短的ID,2个字节,所有从服务器发送到客户端的消息,反之亦然,都是字符串,我如何在java中用2个字节(字符)将短消息转换为字符串 更新:我可能不清楚我想要什么。。。 我希望能够将一个短整型转换为2个字符,这样我就可以在网络上以字符串格式发送短整型,只需2个字节,然后在另一端将其解码为短整型(在actionscript 3中) 一个字符可以容纳256个可能的值,对吗?所以256*256=65536,这是
public static String toCode(int c){
if(c <= 255 ){
return Character.toString((char)c);
}else{
return null;
}
}
public static int fromCode(String c){
return ((int)c.charAt(0));//Return the character code of the send string, 1 char only
}
公共静态字符串到代码(int c){
如果(c我不使用java,但我认为您只想使用cast运算符。如果您的short名为mynumber,请使用(char)mynumber。也就是说,如果您打算在另一端出现这些位时将其视为short。如果您使用“short”作为字段的定义,而不是“16位有符号整数”,这里有一些深奥的平台。对于“可能”的某些值,这是可能的
但是,结果字符串可能无效,因为并非所有16位整数都表示有效(UTF-16编码)代码点!也就是说,结果字符串可能是无效的UTF-16序列。各种字符串函数和/或编码/解码可能会导致“奇怪行为”,因为违反了基本规则(我认为它对可能发生的情况有点松懈,但是…)您已经被警告过了——请参见下面的示例,其中仅显示了一种可能的表现形式
tl,dr.不要在这种网络传输中使用字符串*。相反,使用字节数组(或ByteBuffers)并将短字符发送为两个八位字节,高和低。(哦,我提到过吗?看看方法…)如果需要发送字符串,可以对其进行编码(UTF-8),也可以在数据包中作为“字节”发送
当然,仅仅使用或处理数据包可能更简单……当然比自定义编码更简单。(此外,协议缓冲区也有一些巧妙的技巧,如锯齿形整数编码…)
快乐编码:)
*虽然Quake 3对许多网络消息使用字符串…但是,它将值编码为“纯文本”--例如“xyz=1234”--并使用了一组猴子手序列化代码
查看输出中的最后一个值,了解为什么这种“字符串填充”可能是坏东西;-)
结果在JDK 7和Windows 64中显示
orig int: 55297
orig short: -10239
length of string: 1
value in string: -10239
restored value: 55297
encoded size: 1
decode:?
decode length:1
value in string:63 WHAT IS THIS?!?!?! NOOOOO!!!!!
DataOutputStream.writeShort/DataInputStream.readShort?你不能-这就是为什么会有short
放在第一位…如果你想节省空间,我认为你不应该使用字符串:)Javachar
是16位的,而不是8位…看看这个问题。Java中只有2个字节的字符串是不可能的。哦,拜托e请解释-1。我不能使用标准序列化,因为客户端将在flash中,服务器将在java中,所以我需要一些自定义序列化。@Bubby4j在任何情况下,将序列化和传输的数据视为八位字节序列,而不是字符串(至少来自java)。我不知道Flash对字节流的支持是什么,也不知道它如何处理字符串/字符串解码。只使用基于“fat”文本的消息格式(甚至可以说是JSON)可能是有益的,它将是“字符串安全的”,除非证明需要将其编码为非常紧凑的格式。其他选项包括二进制数据的基本编码(base64是常见的,但自定义base96/128仍然是UTF-8友好的;它不必是“可读”编码,只要是“有效”编码)。@Bubby4j“UTF-8友好”字符串是指所有(或几乎所有)字符串字符可以编码为单个八位字节;所有常规ASCII字符都编码为单个八位字节。+1非常好的一点——序列化流有相对简单的方法。
public class test1 {
public static void main (String[] args) throws Exception {
int s1 = 0xd801;
short s = (short)s1;
String x = "" + (char)s;
System.out.println("orig int: " + s1);
System.out.println("orig short: " + s);
System.out.println("length of string: " + x.length());
System.out.println("value in string: " + (short)x.codePointAt(0));
int s2 = ((short)x.codePointAt(0)) & 0xffff;
System.out.println("restored value: " + s2);
byte[] xb = x.getBytes("UTF8");
System.out.println("encoded size: " + xb.length);
String x2 = new String(xb, "UTF8");
System.out.println("decode:" + x2);
System.out.println("decode length:" + x2.length());
int s3 = ((short)x2.codePointAt(0)) & 0xffff;
System.out.println("value in string:" + s3);
}
}
orig int: 55297
orig short: -10239
length of string: 1
value in string: -10239
restored value: 55297
encoded size: 1
decode:?
decode length:1
value in string:63 WHAT IS THIS?!?!?! NOOOOO!!!!!