/ / Colocando um short em 2 bytes de string - java, string, actionscript-3, byte, short

Colocando um short em 2 bytes de string - java, string, actionscript-3, byte, short

Então, eu estou criando meu próprio protocolo de rede para umjogo online, para economizar espaço a cada mensagem (enviada por TCP) recebe um ID de 2 bytes, todas as mensagens enviadas do servidor para o cliente e vice-versa são seqüências de caracteres, como posso converter um curto em uma string em java em apenas 2 bytes (caracteres)?

Atualizar: Provavelmente não estou sendo claro quanto ao que quero ... Quero poder converter um int curto em 2 caracteres, para que eu possa enviar o curto pela rede em um formato de string em apenas 2 bytes e decodificá-lo novamente em um curto do outro lado (no actionscript 3).

Um personagem pode conter 256 valores possíveis, certo? Então 256 * 256 = 65.536, que é o tamanho de um short int não assinado!

Aqui está o que eu tenho até agora:

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
}

Isso pode transformar um int em um único caractere que pode ser enviado pela rede, agora só preciso que ele use 2 caracteres e pode fazer até um curto.

Respostas:

5 para resposta № 1

Isso é possível com algum valor de "possível".

String s = "" + (char)myShort;

Contudo, a sequência resultante pode ser inválida, pois nem todos os números inteiros de 16 bits representam pontos de código válidos (codificados em UTF-16)! Ou seja, a sequência resultante pode ser um inválido Sequência UTF-16. Várias funções de string e / ou codificação / decodificação podem resultar em "comportamento estranho" como as regras fundamentais foram violadas (acho que é um tanto negligente quanto o que pode ocorrer, mas ...). Você foi avisado - veja o exemplo inferior mostrando apenas uma manifestação possível.

tl, dr. Não use cadeias para esse tipo de transmissão em rede *. Em vez, usar matrizes de bytes (ou ByteBuffers) e envie o short como dois octetos, alto e baixo. (Ah, e eu mencionei ByteBuffers? Dê uma olhada nos métodos ...) Se as strings precisarem ser enviadas, elas podem ser codificadas (utf-8) e também enviadas como "bytes" nos pacotes de dados.

Claro, é bem provável que seja mais simples usar serialização padrão ou Buffers de protocolo para lidar com os pacotes ... certamente supera a codificação personalizada. (Além disso, os buffers de protocolo fazem alguns truques legais, como a codificação inteira em zig-zag ...)

Codificação feliz :)


* Embora o Quake 3 use sequências para várias mensagens de rede ... no entanto, ele codificou os valores "como texto sem formatação" - por exemplo "xyz = 1234" - e usou um monte de código de serialização manual de macacos.


Veja o último valor na saída para saber por que esse "preenchimento de string" pode ser coisas ruins ;-)

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

Os resultados no 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 para resposta № 2

DataOutputStream.writeShort / DataInputStream.readShort?


-1 para resposta № 3

Eu não uso java, mas acho que você só queruse um operador de conversão. Se o seu short for chamado mynumber, use (char) mynumber. Ou seja, se você pretende tratar esses bits como curtos quando eles saem do outro lado. Boa sorte com a plataforma cruzada, embora se você estiver usando "short" como a definição do seu campo em vez de "16-bit assinado int", existem algumas plataformas esotéricas por aí.