2010-05-21 9 views
7

Estoy escribiendo una aplicación .NET que hará una llamada RPC a una aplicación Java (a través de una cola de mensajes). Los datos enviados en ambas direcciones serán grandes conjuntos de números de coma flotante. ¿Cuál es la mejor manera de serializarlos para enviarlos a través del cable? Me gustaría algo más compacto que el texto, pero independiente de la arquitectura ya que el servidor puede no ser una máquina x86. La aplicación Java se puede cambiar según sea necesario.La mejor manera de enviar números de coma flotante de .NET a Java y volver

+0

¿Qué cola de mensajes? – cletus

+0

RabbitMQ, pero probablemente tampoco quiero depender de eso. Le enviaré una serie de bytes y me ocuparé de la serialización. – EMP

Respuesta

6

Las primitivas numéricas de Java en realidad se almacenan (en la JVM) y se escriben (a través de jnava.io.DataOutputStream y java.nio.ByteBuffer) en orden de red y los valores de coma flotante son estándar IEEE. Son directamente intercambiables con C# /. NET. Bueno, si .NET proporcionó el orden de bytes de red para leer dobles (ver abajo el código).

Por lo tanto, puede enviar y recibir cualquier primitiva utilizando las dos clases mencionadas aquí (y las contrapartes de entrada) siempre que el lado .NET esté leyendo/escribiendo en orden de bytes de red como siempre debería usar.

lado de Java, por ejemplo:

// Assume the following somewhere in your class 
Socket socket; 
DataOutputStream out = new DataOutputStream(socket.getOutputStream()); 

// Send a double 
out.writeDouble(doubleValue); 

C# lateral para recuperar el valor:

Stream stream = new NetworkStream(socket, FileAccess.ReadWrite, true); 
BinaryReader reader = new BinaryReader(stream, Encoding.UTF8); 

// Read double from the stream 
long v = IPAddress.NetworkToHostOrder(reader.ReadInt64()); 
double doubleValue = BitConverter.Int64BitsToDouble(v); 

Para escribir haces lo contrario, C# tiene que escribir en orden de bytes de red.

Stream stream = new NetworkStream(socket, FileAccess.ReadWrite, true); 
BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8); 

// Write double to the stream 
long v = BitConverter.DoubleToInt64Bits(doubleValue); 
writer.Write(IPAddress.HostToNetworkOrder(v)); 

Y a continuación, en el lado de Java para leer estas de vuelta en:

// Some where in your class 
Socket socket; 
DataInputStream in = new DataInputStream(socket.getInputStream()); 

// To read the double 
double doubleValue = in.readDouble(); 

El C# IPAddress clase proporciona orden de bytes de red métodos de lectura/escritura para todas las primitivas excepto doble y flotador, pero como en mi Por ejemplo, puede pasar a través de una int de 32 bits o de 64 bits respectivamente.

+0

Ya sabes, podría seguir con este enfoque simple. .NET también tiene 'System.IO.BinaryWriter' y' System.IO.BinaryReader' que manejan la serialización. (No utilizaré clases de socket directamente.) – EMP

+0

C# es .NET; las clases 'BinaryReader' y' BinaryWriter' en mis ejemplos son .NET; estos no existen en Java. –

+0

Si desea poner los valores en matrices de bytes y operar en ellos por separado, es posible que desee utilizar 'java.nio.ByteBuffer' de Java. Ver mi respuesta aquí: http://stackoverflow.com/questions/2868885/representing-a-number-in-a-byte-array-java-programming/2870823#2870823 –

1

JSON viene a la mente. O es una contraparte binaria, BSON. Ambos tienen implementaciones en Java y .NET

+0

BSON parecía prometedor, pero parece que no hay mucho apoyo del cliente. El enlace "Cliente de Java" simplemente va a un único archivo fuente en algún controlador de base de datos. WTF? – EMP

0

El texto es realmente la única plataforma independiente que representa los números de punto flotante, y sin duda es la más fácil de hacer. Si le preocupa el tamaño del mensaje, siempre puede almacenar sus mensajes.

1

Actualmente estoy leyendo sobre Protocol Buffers y se ven prometedores. Hay una implementación oficial de Google para Java y una C# port of it nada menos que por Jon Skeet.

Cuestiones relacionadas