2013-02-28 2 views
1

서버 및 클라이언트 응용 프로그램이 있으며 NetworkStream을 통해 통신하고 있습니다. 서버에서 바이너리를 직렬화하여 NetworkStream을 통해 전송하면 클라이언트에서 읽고 비 직렬화합니다. 그러나 그것은 던지고 오류 : 이진 스트림 '0'유효한 BinaryHeader가 포함되어 있지 않습니다. 직렬화와 비 직렬화간에 유효하지 않은 스트림 또는 오브젝트 버전이 변경 될 수 있습니다. 먼저 NetworkStream의 길이를 확인했으며 직렬화 된 객체를 보낸 후 서버와 클라이언트에서 동일합니다. 그런 다음 서버 참조를 클라이언트에 추가하고 Server.SaveData를 사용하여 직렬화를 해제 할 때 정확히 동일한 클래스가 있는지 확인합니다.이진 스트림 '0'에 유효한 BinaryHeader가 없습니다.

그런 다음 서버 및 코드에서 동일한 개체를 직렬화하고 비 직렬화 한 다음 완벽하게 작동 시키려고 시도했습니다.

Stream stream = new MemoryStream(); 
IFormatter formatter = new BinaryFormatter(); 

current_state.saveData(map, red, blu); 
formatter.Serialize(stream, current_state); 

int total = (int)stream.Length; 
byte[] buffer = new byte[total]; 

writer.WriteLine(total.ToString()); 
writer.Flush(); 

stream.Read(buffer, 0, total); 
network_stream.Write(buffer, 0, total); 

stream.Close(); 

그리고 클라이언트 측 :

stream.Read(buffer, 0, total); 
network_stream.Write(buffer, 0, total); 

network_stream.Read(buffer, 0, total); 
stream.Position = 0; 
stream.Write(buffer, 0, total); 

SaveData savedata = (SaveData)formatter.Deserialize(stream); 

다음은 서버에서 전체 코드를입니다

Stream stream = new MemoryStream(); 
IFormatter formatter = new BinaryFormatter(); 

while (reader.Peek() == '\0') { reader.Read(); } //solved the problem, idkw 
int total = Convert.ToInt32(reader.ReadLine().ToString()); 
byte[] buffer = new byte[total]; 

network_stream.Read(buffer, 0, total); 
stream.Position = 0; 
stream.Write(buffer, 0, total); 
stream.Position = 0; 

Console.Write(stream.Length.ToString()); 

Server.SaveData current_state = (Server.SaveData)formatter.Deserialize(stream); //here is the problem 

stream.Close(); 
+0

당신이 있습니까 다른 응용 프로그램에 의해 직렬화 된 'BinaryFormatter'로 데이터를 직렬화 해제 할 수 없습니까? 아니면 직렬화 된 이진 스트림 또는 무엇을 전달할 문제가 있습니까? – Sinatr

+0

동일한 버전의 .net을 사용하는 클라이언트와 서버? – Andy

+0

또한 UDP 또는 TCP 기반 스트림입니까? 데이터의 전체 집합이 수신 측에 있는지 확 인해 야합니까? – Andy

답변

0

왜 직렬화/직접 NetworkStream (MemoryStream 중간 제외)에 데이터를 역 직렬화?

약간의 예.

서버와 클라이언트가 교환 할 데이터 구조가 있다고 가정합니다 (귀하의 경우 데이터 구조는 current_state입니다).

[Serializable] 
public class UserData : ISerializable 
{ 
    public string Text { get; private set; } 
    public int Number { get; private set; } 

    public UserData(string text, int number) 
    { 
     Text = text; 
     Number = number; 
    } 

    protected UserData(SerializationInfo info, StreamingContext context) 
    { 
     Text = info.GetString("Text"); 
     Number = info.GetInt32("Number"); 
    } 

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("Text", Text); 
     info.AddValue("Number", Number); 
    } 
} 

(예를 들어, 클라이언트 측에서) 데이터 구조를 보내려면

using (var networkStream = tcpClient.GetStream()) 
{ 
    var userData = new UserData("Hello.", 9); 

    var binaryFormatter = new BinaryFormatter(); 
    binaryFormatter.Serialize(networkStream, userData); 
} 

(예를 들어, 서버 측) 데이터 구조를 받으려면 :

var binaryFormatter = new BinaryFormatter(); 
using (var networkStream = tcpClient.GetStream()) 
{ 
    while (networkStream.DataAvailable) 
    { 
     var receivedData = (UserData)binaryFormatter.Deserialize(networkStream); 
    } 
}