Representação binária do tamanho da String

Olá pessoal.

Pois bem, estou enfrentando um problema na minha aplicação.

eis que tenho uma String ex: ‘988768767326423462308648324615286721542574317346235127362493475’

preciso enviar ela com Stream e dizer o tamanho dela em 2 bytes, ou seja os dois primeiros.

no exemplo abaixo ele me retornou 00C2BB ao invés de 00BB, pois a string tinha o tamanho de 187.

                        
StringBuffer sb = new StringBuffer(String);

int axLen = sb.length();

int h = (axLen / 256);
int l = axLen - (h * 256); 

sb.insert(0, (char)l);
sb.insert(0, (char)h);
                        
saida = new PrintStream(socket.getOutputStream());
saida.print(sb);
saida.flush();

uma análise aprimorada:

HdrLen=32, Win=65393(241510916), Cksum=C861, Flags=18
Options= 0101080A 00003899 D2C6AD6B
DATA +0000 00C2BB30 32313541 30313830 30303038 .B.0215A01800008
+0010 41303030 30303630 30303030 30303031 A000006000000001
+0020 30303030 30303238 39303032 33313332 0000002890023132
+0030 34303430 35323530 34383139 31303030 4040525048191000
+0040 31303030 33393039 33303030 33303030 1000390930003000
+0050 30303030 30303030 30303030 30303030 0000000000000000
+0060 30303030 30303030 30303030 30363130 0000000000000610
+0070 30313230 39313134 38393030 35353232 0120911489005522
+0080 30202020 20202020 20202020 20202020 0 *
+0090 20202020 20202020 20202020 20202020 * *
+00A0 20202020 20202020 20202020 30343031 * 0401

+00B0 30343030 39303030 30303530 3937 *04009000005097 *

OSA_EXPR 00010207 05/25 13:24:06.028871 OUTPUT

gostaria da ajuda de todos vocês.

desde já obrigado.

Eu faria assim:

int l = (sb.length() & 0xFF); int h = ((sb.length() >> 8 ) & 0xFF);

O que você está usando para imprimir esse output? Por acaso é o wireshark?
http://www.wireshark.org/

[quote=ViniGodoy]Eu faria assim:

int l = (sb.length() & 0xFF);
int h = ((sb.length() >> 8 ) & 0xFF);

O que você está usando para imprimir esse output? Por acaso é o wireshark?
http://www.wireshark.org/

[/quote]

não na verdade é da IBM eu acho, SDSF.

vou testar seu exemplo.

Outra coisa. Jamais use o printStream para escrever dados binários.

O PrintStream é usado para texto. Portanto, ele vai inserir o \n ao final.

Use o DataInputStream e o DataOutputStream. Logo vê-se que você não leu os links que te indiquei no outro tópico.

[quote=ViniGodoy]Outra coisa. Jamais use o printStream para escrever dados binários.

O PrintStream é usado para texto. Portanto, ele vai inserir o \n ao final.

Use o DataInputStream e o DataOutputStream. Logo vê-se que você não leu os links que te indiquei no outro tópico.[/quote]

eu li e baixei os exemplos, porém como já tinha programado essa parte não me preocupei em mudar.

vendo agora vi que estava usando o DataOutput e comentei por alguma razão.

tudo funciona perfeitamente, somente a questão do envio do hexadecimal nos primeiros bytes que ainda não compreendi.

eu só preciso colocar nos bytes iniciais a representação em hexadecimal.

ex:

mensagem com 187 caracteres

00 BB 48 5D 48 53 65 48
0 2 0 5 A 0

e ler esses dois bytes quando recebo as mensagens também.

E o meu código funcionou?

não.

não.[/quote]

modifiquei para


int parteAlta = ((axLen >> 4) & 0xf) << 4;
int parteBaixa = axLen & 0xf;
if (parteAlta == 0) sb.insert(0, (char)'0');
sb.insert(0,(char)(parteAlta | parteBaixa));

e também me retornou 00 C2 BB para uma string com tamanho 187

o mesmo retorna com o seu exemplo

int l = (sb.length() & 0xFF);
int h = ((sb.length() >> 8 ) & 0xFF);

e o meu inicial também da o mesmo resultado.

int h = (axLen / 256); 
int l = axLen - (h * 256);

O que deu?
Com certeza esse código funciona.

Quem está gerando esse C2 não é esses códigos.

[quote=ViniGodoy]O que deu?
Com certeza esse código funciona.[/quote]

ele me retorna no output

00 C2 BB que é igual a 49851

ao invés de

00 BB que é igual a 187 que por sinal é o tamanho correto da string.

vou colocar aqui o fragmento que gera o código.


StringBuffer sb = new StringBuffer(iConteudo); // Pega o texto passado como parametro

int axLen = sb.length(); // Determina o tamanho do parametro


//Exemplo 1 para pegar o tamanho em hex da string

int parteAlta = ((axLen >> 4) & 0xf) << 4;
int parteBaixa = axLen & 0xf;
if (parteAlta == 0) sb.insert(0, (char)'0');
sb.insert(0,(char)(parteAlta | parteBaixa));

//Exemplo 2
int l = (sb.length() & 0xFF);
int h = ((sb.length() >> 8 ) & 0xFF);

//Exemplo 3
int h = (axLen / 256);
int l = axLen - (h * 256);

// Concatena para os exemplos 2 e 3
sb.insert(0, (char)l);
sb.insert(0, (char)h);/**/

saida = new PrintStream(socket.getOutputStream());
saida.print(sb);
saida.flush();

no DataOutputStream como enviarStringBuffer?

pode ser no PrintStream também o erro.

Pois é, esse C2 está sendo inserido, provavelmente pelo PrintStream. Tente usar o DataOutputStream.

Já usou o depurator para imprimir o valor das variáveis l e h? Garanto que nenhuma delas vale 194.

[quote=ViniGodoy]Pois é, esse C2 está sendo inserido, provavelmente pelo PrintStream. Tente usar o DataOutputStream.

Já usou o depurator para imprimir o valor das variáveis l e h? Garanto que nenhuma delas vale 194.[/quote]

sim elas, valem realmente o que deveriam valer.

deve ser o PrintStream mesmo, mais no caso do DataOutputStream como enviar StringBuffer?

Use o método getBytes() da classe String.

obrigado.

não foi dessa vez, o C2 intruso continua aparecendo na mensagem.

interessante que o C2 só aparece se a mensagem tiver mais de 100 caracteres, até 99 ele não aparece.

Problema resolvido.

o Caminho foi pelo DataOutpuStream.

usei o writeutf() que diz o tamanho e o DataInputStream.readUTF automaticamente lê o tamanho e os bytes necessários para criar a String.

DataOutputStream saida = new DataOutputStream(socket.getOutputStream());
saida.writeUTF(iConteudo);
saida.flush();

obrigado a todos pela ajuda.

Eu não sabia que vc podia enviar os dados em UTF. Eu já havia pensado nele.

Mas a regra é: Quando for transferir dados, nunca usa PrintWriter, ou converta dados para String antes de envia-los.
Tem sempre que lembrar que Strings tem diversos formatos (ISO, UTF, ASCII) e o Java pode resolver converte-los. Aí, o que você escreve em binário nem sempre vai ser o que circula pela rede…

[quote=ViniGodoy]Eu não sabia que vc podia enviar os dados em UTF. Eu já havia pensado nele.

Mas a regra é: Quando for transferir dados, nunca usa PrintWriter, ou converta dados para String antes de envia-los.
Tem sempre que lembrar que Strings tem diversos formatos (ISO, UTF, ASCII) e o Java pode resolver converte-los. Aí, o que você escreve em binário nem sempre vai ser o que circula pela rede…[/quote]

entendi a lição.

agora vamos ao outro problema. rsrssr

mais é mais simples.

eu recebo a mensagem pelo BufferedReader.

Como descobrir então o tamanho da mensagem que eu recebo, ela vem nos dois bytes iniciais também.

entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));