/ / Umieszczanie skrótu w 2 bajtach ciągu - java, string, Actionscript-3, bajt, krótki

Umieszczanie skrótu w 2 bajtach ciągu - java, string, Actionscript-3, byte, short

Dlatego tworzę własny protokół sieciowy dlagra online, aby zaoszczędzić miejsce każda wiadomość (wysłana przez TCP) otrzymuje identyfikator, który jest krótki, 2 bajty, wszystkie wiadomości wysyłane z serwera do klienta i odwrotnie są ciągami, jak mogę przekonwertować krótki na ciąg w java w zaledwie 2 bajty (znaki)?

Aktualizacja: Prawdopodobnie nie jestem pewien, czego chcę ... Chcę być w stanie przekonwertować krótki int na 2 znaki, dzięki czemu mogę wysłać skrót przez sieć w formacie łańcuchowym w zaledwie 2 bajtach i zdekodować go z powrotem na krótki po drugiej stronie (w ActionScript 3).

Postać może przechowywać 256 możliwych wartości, prawda? Więc 256 * 256 = 65 536, co jest rozmiarem krótkiej int bez znaku!

Oto, co do tej pory osiągnąłem:

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
}

Może to zamienić int w pojedynczy znak, który można wysłać przez sieć, teraz muszę tylko użyć 2 znaków i może to zrobić nawet krótko.

Odpowiedzi:

5 dla odpowiedzi № 1

Można to zrobić dla pewnej wartości „możliwej”.

String s = "" + (char)myShort;

jednak, wynikowy ciąg może być nieprawidłowy, ponieważ nie wszystkie 16-bitowe liczby całkowite reprezentują prawidłowe (kodowane w UTF-16) punkty kodowe! Oznacza to, że wynikowy ciąg może być nieważny Sekwencja UTF-16. Może to skutkować różnymi funkcjami łańcucha i / lub kodowaniem / dekodowaniem "dziwne zachowanie" ponieważ podstawowe zasady zostały naruszone (myślę, że jest to nieco luźne co może wystąpić, ale ...). Zostałeś ostrzeżony - patrz dolny przykład pokazujący tylko jedną możliwą manifestację.

tl, dr. Nie używaj ciągów dla tego rodzaju transmisji sieciowej *. Raczej, użyj tablic bajtowych (lub ByteBuffers) i wysyłaj krótkie jako dwa oktety, wysoki i niski. (Och, a wspomniałem Bufory Bajtowe? Spójrz na metody ...) Jeśli ciągi muszą zostać wysłane, można je zakodować (utf-8), a także wysłać jako „bajty” w pakietach danych.

Oczywiście korzystanie z niego jest prawdopodobnie prostsze standardowa serializacja lub Bufory protokołów radzić sobie z pakietami ... na pewno pokonuje niestandardowe kodowanie. (Również bufory protokołów wykonują pewne sztuczki, takie jak kodowanie liczb całkowitych zygzakowatych ...)

Szczęśliwe kodowanie :)


* Chociaż Quake 3 używa ciągów znaków do wielu komunikatów sieciowych ... jednak zakodował wartości „jako zwykły tekst” - np. „xyz = 1234” - i użył garść małpiego kodu serializacji ręcznej.


Zobacz ostatnią wartość na wyjściu, dlaczego może to być „upychanie łańcucha” złe rzeczy ;-)

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

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

1 dla odpowiedzi nr 2

DataOutputStream.writeShort / DataInputStream.readShort?


-1 dla odpowiedzi nr 3

Nie używam java, ale myślę, że po prostu chceszużyj operatora rzutowania. Jeśli skrót ma nazwę mynumber, użyj (char) mynumber. To znaczy, jeśli zamierzasz traktować te bity jako krótkie, gdy wyjdą po drugiej stronie. Powodzenia z platformami wieloplatformowymi. Jeśli jednak używasz „krótkiej” jako definicji swojego pola zamiast „16-bitowej int”, istnieją pewne ezoteryczne platformy.