Entwickler-Ecke

Netzwerk - Serialisierte Klasse über Socket übertragen


waldigunde - Mo 22.03.10 22:54
Titel: Serialisierte Klasse über Socket übertragen
hallo zusammen

klasse Protokoll=name


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Server
{
    [Serializable()]
    public class Protokoll
    {

        public string Message="";

    }
}


client-code (der client sendet)


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
Protokoll protokoll = new Protokoll(); //protokoll ist eine
protokoll.Message = "protokoll msg";

BinaryFormatter binaryWrite = new BinaryFormatter();
binaryWrite.Serialize(swSender.BaseStream, protokoll);

swSender.Flush();




server-code (der server empfängt)


C#-Quelltext
1:
2:
3:
4:
BinaryFormatter binaryRead = new BinaryFormatter();
                    
Stream sss = srReceiver.BaseStream;
object resp = binaryRead.Deserialize(sss);


leider kriege ich eine Serialization exception
The input stream is not a valid binary format. The starting contents (in bytes) are: 00-0C-02-00-00-00-3D-43-6C-69-65-6E-74-2C-20-56-65 ...

was mach ich falsch?

danke für eure hilfe.

Moderiert von user profile iconChristian S.: C#-Tags hinzugefügt


danielf - Mo 22.03.10 23:04

Hallo und :welcome:,

bei deinem server-code machst du in zeile 3 ein srReceiver.Read();

Damit ließt er ein byte von dem Stream aus und dieses fehlt nachher dem Serializer beim Deserializen. Probier es mal ohne diese Zeile.

Gruß


waldigunde - Mo 22.03.10 23:10

danke für die hilfe, jetzt kriege ich eine andere exception, eine SerializationException


System.Runtime.Serialization.SerializationException wurde nicht behandelt.
Message="Unable to find assembly 'Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'."
Source="mscorlib"
StackTrace:
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap.Create(String name, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
at Server.Connection.AcceptClient() in C:\Users\mike\Desktop\moa\OK\ChatServer\Server.cs:line 304
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:


danielf - Mo 22.03.10 23:19

Das hört sich so an, als ob dein Server das Objekt (Protokoll) nicht kennt. Du musst sicherstellen, dass er dieses Kennt.

Am besten du machst sowas:

C#-Quelltext
1:
Protokoll resp = (Protokoll) binaryRead.Deserialize(sss);                    

Dann merkst du es schon zur Laufzeit.

Ich wunder mich auch immer warum es keinen Generischen Deserializer gibt ...

C#-Quelltext
1:
Protokoll resp = binaryRead.Deserialize<Protokoll>(sss);                    


find ich schöner ;)


waldigunde - Mo 22.03.10 23:27

danke

aha, an dem kann es wirklich liegen, ich habe die beiden server und client in 2 verschiedenen projekten. die protokollklasse habe ich redundant. geht es so nicht, denn der code ist genau der selbe, aber warscheinlich wird es nicht als das selbe betrachtet?

wie share ich am besten die klasse, wenn meine art nicht geht?


danielf - Mo 22.03.10 23:35

Jepp, die selbe Klasse ist nicht die gleiche :) .NET vergibt einen eindeutige GUID für jede Klasse. Diese wird beim Serialisieren mit angegeben.

Wenn du die zwei Projekte in der gleichen Solution hast, kannst du einfach bei einem Projekt per Rechts Klick einen Verweis hinzufügen. Dort gehst du zum Reiter Projekt und wählst das "andere" Projekt aus. Dann ist das gleich Protokoll auch in dem Projekt verfügbar.

Alternativ (wenn du die Projekt nicht in der gleichen Solution hast) musst du das Assembly, welches generiert wird, auch per Rechts kLick auf das Projekt hinzufügen. Dieses mal über den Reiter Durchsuchen.

Viel Erfolg ;)


waldigunde - Mo 22.03.10 23:55

Super, das werde ich gleich morgen testen. Und werde es im Thread kundtun.

Herzlichen Dank für die Hilfe, heute habe ich was gelernt.


waldigunde - Mi 24.03.10 13:36

hat alles tip top geklappt, herzlichen Dank für die Hilfe :)