我必須在Java和C#之間進行通信,我需要通過套接字服務器發送對象。這裏服務器部分用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#客戶端中反序列化字節[]時出現異常。 異常消息是:「輸入流不是有效的二進制格式。起始內容(以字節爲單位)爲:AC-ED-00-05-73-72-00-17-74-65-73-74- 73-6F-63-6B-65 ...「
現在我的問題是,我如何解決這個問題,以反序列化在C#代碼並獲得從Java服務器發送的對象?
使用像JSON或XML這樣的對象的共享中間協議表示形式。您不能直接將對象序列化爲Java中的二進制文件,並希望C#能夠反序列化它。 – Fildor
Java&C#都有不同的默認序列化/反序列化模式,因此您需要使用第三方組件(JSON,XML或其他文本格式)來標準化數據傳輸。使用一種語言序列化並在另一種語言中反序列化往往不能提供預期的結果。 –
爲什麼不發送字節而不是編碼到Ascii?您不是將ascii解碼回字節。發送方法和接收方法必須是對稱的。您收到的所有信息都必須以相反的順序發送。 – jdweng