Ayuda sobre Sockets. Enviar mensajes en hexadecimal java

Muy buenas tardes, necesito ayuda sobre sockets.
Actualmente tengo una aplicación socket cliente que se comunica con un socket servidor. hay intercambio de datos sin problema.

la pregunta es que
A principio de cada mensaje debe de contener la longitud del mensaje en hexadecimal:
mas o menos así:

7MENSAJE,

PERO EL NUMERO 7 DEBE SER EN HEXADECIMAL CONCATENANDO CON EL MENSAJE EN STRING

private void enviarDatos() {
try {
String mensaje="MENSAJE";
short tamanyo=7;/*ESTE DEBE SER EN HEXADECIMAL*/
String mensje2=tamanyo+mensaje;
salida.write(mensaje.getBytes());
salida.flush();
} catch (IOException ioe) {
ioe.getMessage();
}
}

AYUDENME PORFA

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de checotaku

Conversion entre bases

Si quieres obtener la representacion Hexadecimal como una cadena de un entero puedes usar el metodo toHexString(int x) de la clase Integer

 

Si la conversion entre bases es parte del problema que estas resolviendo , entonces talves necesites programar un metodo que realice la conversion de base 10 a cualquier otra base.

AYUDENM POR FA

QUIERO HACER UN PROGRAMA EN JAVA Q SEA SOBRE LOS CODIGOS DE MORSEN Y ME TIENEN Q HACER UN SONIDO DE CADA COMPU ALGIEN ME PUEDE AYUDAR O DAR UNA IDEA POR DOND COMENSAR GRACIAS SE LO AGRADESCO

Imagen de ezamudio

cuántos bytes?

Un ejemplo de encabezado de longitud en binario, a 2 bytes

Asi es, ya lo he visto, pero

Asi es, ya lo he visto, pero la conversión te lo hace en String y lo que yo necesito es
en bytes. Algo asi:
variable=0xb7;
Es decir poner como prefijo al mensaje.
Y si hago como lo dices sería asi:
String mensaje="MENSAJE";
String mensje2=Integer.toHexString(7);
String enviar=mensje2+mensaje;
PERO entonces, ya no se enviaría como hexadecimal(2 bytes), sino un string normal.

public static final char STX = '\u0002';
public static final char ETX = '\u0003';
ya lo he hecho con otros caracteres como el del inicio y el término de una cadena:
String mensaje="MENSAJE";
String mensjefinal=STX+mensaje+ETX;
Sólo que en lugar de STX, hay que representar la longitud en hexadecimal de 2 bytes y no hexadecimal en String.

Sucede que al final en es el mismo número

Pero tu problema es que lo estás queriendo meter en otra parte del protocolo:

Mira:
 
Son exactamente el mismo numero:
 

Al parecer tu problema esta en que no sabes como enviar este número por el socket y piensas que concatenandoselo al mensaje funcionará. Nope!, así no va a jalar.

Si se lo concatenas al mensaje, entonces tu mensaje será "7MENSAJE" y aún te hará falta mandar el encabezado ( y de hecho la longitud sería: 8 por el caracter 7 extra que le metiste )

Usar "0x7MENSAJE" no arregla en nada el asunto por que como ya te diste cuenta, le estás concatenando "caracteres" al mensaje y no mandando la longitud.

Lo único que tienes que hacer ( si entendí bien tu protocolo ) es mandarle primero la longitud y luego el mensaje:

 

De esta forma el otro lado del socket lo primerititito que va a leer va a ser un entero ( o un byte con muchos ceros y tres 1's al final )

Y luego va a leer un bonche de bytes de los cuales los primero 7 serán el mensaje.

edit

La explicación de por que concatenar STX y ETX te funciona es la siguiente

Al flujo de bytes que viaja por la red esto le importa un cacahuate, el solo ve un montón de bytes que van por ahí viajando.

Cuando haces:

 

Y lo envías, estás en realidad enviando un byte que representa el 2 ( \u0002 ) y luego los bytes del mensaje, pero esta mal.

Si quieres hacer lo mismo tendrías que hacer lo siguiente:
 

Y te va a funcionar ( por que estas poniendo en el 7 como como el character unicode '\u0007' y al concatenarlo con el String le pone esos bytes ) ; pero no puedes seguir haciendo eso por que al hacerse más complicado el protocolo se te va a caer en pedazos horriblemente.

El mayor problema que se te puede presentar con esto, es que la cantidad de bits que lleva cada byte depende del "encoding" que lleva. Al parecer estas corriendo con suerte y cada caracter Java te lo está escribiendo como 8 bits, pero si la plataforma usa otro encoding te lo podria mandar de 16 bits, entonces te pondría 8 ceros extra y adios protocolo.

ejem. letra 'a' en UTF-8 = 01000001 en binario

Pero la letra 'a' en UTF-16 es: 0000000001000001

Es por eso que en Java 1.6 se añadio el método: String.getBytes( charset: Charset):byte[]

Para que tu como desarrollador tengas control de la forma en la que se van a representar esos bytes.

En conclusión tienes que llamarlo así:

 

Espero que esto te sea útil.

En efecto asi es

la longitud del mensaje no se envía como encabezado, sino que parte del mensaje.
Lo que pasa es que estoy desarrollando una aplicación y no viene explicado especificamente.
y en el apartado solo dice así:

AL PRINCIPIO DE CADA MENSAJE DEBE CONTENER LOS CARACTERES EN HEXADECIMAL (2 BYTES) INDICANDO EL TAMAÑO DEL MENSAJE.

por lo que yo entiendo que no es el encabezado.

eso es lo que pide la documentación.

Saludos....

Si dice 2 bytes tienes que usar short entonces

 

Casualmente un   tambien tiene dos bytes, lo cual concuerda con aquello de  

Lo mejor que puedes hacer, es ir probando.

Muchas gracias

De hecho lo manejé como short, pero como te comento, en la documentación decia que en hexadecimal.

Me causa confusión, si es así lo dejo como está, es decir como short.
Y lo que haré es tener 2 versiones, una donde maneje el short y la otra ocupando un arreglo de bytes
Gracias por todo...

Je eje es lo mismo.

Lo que pasa es que hexadecimal es una representación "humana" de un mismo número, al flujo de bytes le da lo mismo
 

Todos representan el mismo número. Pero bueno ya te irá cayendo el 20 poco a poco :) :) Lo bueno es que ya te está funcionando.

Para leerlo es igual, pero al revés :)

jejej te dije que se te iba a empezar a hacer pedazos el protocolo si lo querías hacer todo con un solo string.

Lee y relee lo que escribí hasta que lo entiendas.

Cuando lo hayas entendido, aplica lo mismo pero en vez de   usa  

El mensaje en realidad no te está llegando truncado ( es decir no es que primero te llegue uno y luego otro ) quizá sea tu interpretación por que lo estás queriendo ver en algún editor o algo así.

Si el mensaje llega truncado, no está cumpliendo con el protocolo y no debes de hacer nada por solucionarlo.

> Hablando de sockets, manejamos los mensajes como sigue:
> public static final char STX = '\u0002';
> public static final char ETX = '\u0003';
> String "MENSAJE"
>
> String mensajeEnviar=STX+MENSAJE+ETX;
>
> while (entrada.read()) {
> }
> Pues la lectura de lo que llega, se lee bien y todo.
> Mi duda es como le hago para leer el mensaje, cuando me llegan varios a la vez: algo asi:
> STX+MENSAJE+ETX+STX+MENSAJE+ETX+STX+MENSAJE+ETX
> porque si sucede en cuestionde milisegundos.
> como separar los mensajes indicando por STX y ETX, o cuando lleguen tramas como este:
> primera trama:
> STX+MENSAJE+ETX+STX+MEN
> segunda trama:
> SAJE+ETX+STX+MENSAJE+ETX
>
> armar la primera trama y luego la segunda. porque llegan cortadas
>
>

Ejemplo:

Aquí te va un ejemplo de como leer un protocolo muy sencillo que consiste en   repetido n veces:

 

Corrida de ejemplo:

 

Si te fijas en el segundo ejemplo el tamaño del mensaje es 0x13 Pero eso es solo el formato con el que se imprime  

Cuando se escribio se fue derechito como un numero nomás: 

Este protocolo dice: "dime de que tamaño es el mensaje y yo lo voy a leer" Es por eso que cuando se procesa solamente dice:

 

Es decir; lo primero que lee es un "short" con el numero a crear y luego lee esa cantidad de veces y ya, no hace más intento por descifrar el mensaje.

Claro está, un protocolo que valga la pena es mucho más complicado que esto, pero estas son las bases.

Espero que te sirva.

Acá hay otro ejemplo de un protocolo ligeramente más complicado: