Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Putting a short into 2 bytes of string

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.

like image 742
James T Avatar asked Nov 27 '25 13:11

James T


2 Answers

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

DataOutputStream.writeShort/DataInputStream.readShort?

like image 27
Joop Eggen Avatar answered Nov 29 '25 01:11

Joop Eggen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!