将一个短值放入 2 个字节的字符串中

发布于 2024-12-12 03:05:09 字数 713 浏览 0 评论 0原文

因此,我正在为在线游戏制定自己的网络协议,为了节省空间,每个消息(通过 TCP 发送)都会被赋予一个短的 2 字节 ID,从服务器发送到客户端的所有消息(反之亦然)都是字符串,如何将 java 中的短整型转换为仅 2 个字节(字符)的字符串?

更新:我可能不清楚我想要什么...... 我希望能够将一个短整型转换为 2 个字符,这样我就可以通过网络以字符串格式发送短整型,只需 2 个字节,然后在另一端将其解码回短整型(在 ActionScript 3 中)。

一个字符可以容纳 256 个可能的值,对吧?所以 256*256=65,536 这是一个无符号短整型的大小!

这是我到目前为止所得到的:

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 转换为可以通过网络发送的单个字符,现在我只需要让它使用 2 个字符,并且最多可以做一个短字符。

So I'm making my own networking protocol for a online game, to save space each message (sent over TCP) is given a ID which is a short, 2 bytes, all messages sent from the server to the client and vice versa are strings, how can I convert a short to a string in java in just 2 bytes (characters)?

Update: I'm probably not being clear as to what I want...
I want to be able to convert a short int into 2 characters, so that I can send the short over the network in a string format in just 2 bytes and decode it back into a short on the other side (in actionscript 3).

A character can hold 256 possible values right? So 256*256=65,536 which is the size of a unsigned short int!

Here's what I've got so far:

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
}

This can turn a int into a single character which can be sent over the network, now I just need to have it use 2 characters and it can do up to a short.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我三岁 2024-12-19 03:05:09

对于“可能”的某些值来说,这是可能的。

String s = "" + (char)myShort;

但是,结果字符串可能无效,因为并非所有 16 位整数都表示有效(UTF-16 编码)代码点!也就是说,生成的字符串可能是无效 UTF-16 序列。各种字符串函数和/或编码/解码可能会导致“奇怪的行为”,因为违反了基本规则(我认为对于可能发生的情况有点松懈,但...)。您已被警告 - 请参阅底部示例,仅显示一种可能的表现形式。

TL,博士。 不要使用字符串进行此类网络传输*。相反,使用字节数组(或 ByteBuffer)并将短值作为两个八位位组(高位和低位)发送。 (哦,我有没有提到ByteBuffers?看一下这些方法...)如果需要发送字符串,可以对其进行编码(UTF-8),并且也可以在数据包中作为“字节”发送。

当然,使用 标准序列化 可能会更简单协议缓冲区来处理数据包...肯定胜过自定义编码。 (此外,协议缓冲区做了一些巧妙的技巧,例如之字形整数编码...)

快乐编码:)


*虽然,Quake 3 使用字符串来表示许多网络消息...但是,它将值“编码为纯文本” -- 例如“xyz=1234” -- 并使用了一堆猴子手工序列化代码。


查看输出中的最后一个值,了解为什么这种“字符串填充”可能是坏东西;-)

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);
    }
}

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!!!!!

This is possible to do for some value of "possible".

String s = "" + (char)myShort;

However, the resulting string may be invalid as not all 16-bit integers represent valid (UTF-16 encoded) code-points! That is, the resulting string may be an invalid UTF-16 sequence. Various string functions and/or encoding/decode may result in "strange behavior" as the fundamental rules have been violated (I think it is somewhat lax as to what may occur, but...). You have been warned -- see the bottom example showing just one possible manifestation.

tl,dr. Don't use strings for this sort of network transmission*. Rather, use byte arrays (or ByteBuffers) and send the short as two octets, high and low. (Oh, and did I mention ByteBuffers? Take a look at the methods...) If strings need to be sent they can be encoded (UTF-8) and also sent as "bytes" in the data packets.

Of course, it is quite likely be simpler just to use standard Serialization or Protocol buffers to deal with the packets... sure beats custom encoding. (Also, protocol buffers does some neat tricks like zig-zag integer encoding...)

Happy coding :)


*Although, Quake 3 use strings for a number of network messages ... however, it encoded the values "as plain text" -- e.g. "xyz=1234" -- and used a bunch of monkey hand-serialization code.


See the last value in the output as to why this "string stuffing" can be bad stuff ;-)

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);
    }
}

The results in 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!!!!!
暮年 2024-12-19 03:05:09

DataOutputStream.writeShort/DataInputStream.readShort?

DataOutputStream.writeShort/DataInputStream.readShort?

凉城凉梦凉人心 2024-12-19 03:05:09

我不使用java,但我认为你只想使用强制转换运算符。如果您的 Short 称为 mynumber,请使用 (char) mynumber。也就是说,如果您打算在这些位从另一侧出来时将其视为短路。祝跨平台好运,但如果您使用“short”作为字段的定义而不是“16位有符号整数”,那么那里有一些深奥的平台。

I don't use java, but I think you just want to use a cast operator. If your short is called mynumber, use (char) mynumber. That is, if you then intend to treat those bits as a short when they come out the other side. Good luck with cross-platformness though if you're using "short" as the definition of your field rather than "16-bit signed int", there are some esoteric platforms out there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文