将对象从java传输到C#

时间:2017-09-11 07:17:22

标签: java c# sockets serialization serversocket

我必须在Java和C#之间进行通信,我需要通过套接字服务器发送一个对象。这里服务器部分用Java编写,客户端部分用C#编写。我想从服务器(Java)发送一个对象,并在客户端(C#)接收它。但我不能这样做。

LocalJobInfo.java

package testsocket;

import java.io.Serializable;

public class LocalJobInfo implements Serializable{
    private String id;
    private String message;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

服务器(在Java中):

List<LocalJobInfo> jobInfoList = new ArrayList<LocalJobInfo>();
LocalJobInfo jobInfo = new LocalJobInfo();

jobInfo.setId("1");
jobInfo.setMessage("Success");

jobInfoList.add(jobInfo);

ServerSocket serverSocket = new ServerSocket(4343, 10);
Socket socket = serverSocket.accept();
InputStream is = null;
OutputStream os = null;
String received = null;
try {
       is = socket.getInputStream();
       os = socket.getOutputStream();
       byte[] lenBytes = new byte[4];
       is.read(lenBytes, 0, 4);
       int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16)
       | ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
       byte[] receivedBytes = new byte[len];
       is.read(receivedBytes, 0, len);
       received = new String(receivedBytes, 0, len);


       System.out.println("Server received: " + received);

       // Sending

       byte[] toSendBytes = null;
       ByteArrayOutputStream bos = new ByteArrayOutputStream();
       ObjectOutput out = null;
       try {
               out = new ObjectOutputStream(bos);
               out.writeObject(jobInfoList);
               out.flush();
               toSendBytes = bos.toByteArray();
       } finally {
                    try {
                        bos.close();
                    } catch (IOException ex) {
                        // ignore close exception
                    }
       }

       int toSendLen = toSendBytes.length;
       byte[] toSendLenBytes = new byte[4];
       toSendLenBytes[0] = (byte) (toSendLen & 0xff);
       toSendLenBytes[1] = (byte) ((toSendLen >> 8) & 0xff);
       toSendLenBytes[2] = (byte) ((toSendLen >> 16) & 0xff);
       toSendLenBytes[3] = (byte) ((toSendLen >> 24) & 0xff);
       os.write(toSendLenBytes);
       os.write(toSendBytes);

       try {
                Thread.sleep(10000);
       } catch (Exception ex) {
       }
   } catch (Exception ex) {
   }
   socket.close();
   serverSocket.close();

客户(在C#中):

string toSend = "Hello!";

IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4343);

Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(serverAddress);

// Sending
int toSendLen = System.Text.Encoding.ASCII.GetByteCount(toSend);
byte[] toSendBytes = System.Text.Encoding.ASCII.GetBytes(toSend);
byte[] toSendLenBytes = System.BitConverter.GetBytes(toSendLen);
clientSocket.Send(toSendLenBytes);
clientSocket.Send(toSendBytes);

// Receiving
byte[] rcvLenBytes = new byte[4];
clientSocket.Receive(rcvLenBytes);
int rcvLen = System.BitConverter.ToInt32(rcvLenBytes, 0);
byte[] rcvBytes = new byte[rcvLen];
clientSocket.Receive(rcvBytes);

MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(rcvBytes, 0, rcvBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);

在C#客户端反序列化byte []期间出现异常。 异常消息是:“输入流不是有效的二进制格式。起始内容(以字节为单位)为:AC-ED-00-05-73-72-00-17-74-65-73-74-73 -6F-63-6B-65 ......“

现在我的问题是,如何解决问题以便在C#代码中反序列化并从Java中获取从服务器发送的对象?

1 个答案:

答案 0 :(得分:0)

您需要一个与语言无关的序列化框架。示例包括Google Protocol Buffers,ASN.1,XSD。

基本上,您需要将模式文件(如GPB .proto,或ASN.1 .asn或.xsd)转换为POJO和POCO类(分别用于Java和C#)。这就是GPB编译器或ASN.1编译器可以为您做的事情。因此,您最终会使用两种语言的类,并且这些类与公共有线格式串行/反序列化。

XSD稍微复杂一点;有来自Microsoft的xsd.exe将.XSD文件转换为C#。我不知道Java是否有类似内容。

我认为最好的起点是使用Google Protocol Buffers - 它是免费的,并且会让你前进。它支持JAVA和C#。

我不会触及JSON模式;代码生成工具似乎远远落后。有很多验证器可以告诉您,您收到或即将发送的消息是否符合JSON模式,但这并不能帮助您首先制定消息。