pdoxtader
Если вы собираетесь использовать двоичную сериализацию, то большая проблема, с которой вы столкнетесь при отправке сериализованных объектов в другое приложение, заключается в том, что объекты, сериализованные с помощью двоичного средства форматирования, записывают не только имя класса, но и пространство имен и имя сборки. Таким образом, даже если вы успешно сериализуете и затем передаете объект через tcp, при попытке десериализовать его в удаленном приложении он потерпит неудачу.
Способ справиться с этим заключается в использовании Объект serializationbinder.Биндтотип.
Используя BindToType, вы можете заглянуть в объект перед его десериализацией и дать команду BinaryFormatter получить целевой тип объекта из текущей сборки.
У меня есть библиотека TCP здесь, на codeproject, которая позволяет отправлять сериализованные объекты между клиентом и сервером, а также между клиентами, подключенными к вашему серверу. Код доступен в разделе загрузки для статьи:
https://www.codeproject.com/Articles/1192106/Abstracting-TCP-Communications-and-adding-what-sho
Я бы скачал библиотеку и посмотрел - она должна делать то, что вам нужно. Если вы все еще заинтересованы в том, чтобы сделать это самостоятельно, вот посмотрите, как я настроил BindToType (в c#):
public class TypeConvertor : System.Runtime.Serialization.SerializationBinder
{
private Assembly targetAssembly;
public TypeConvertor(Assembly targetAssembly)
{
this.targetAssembly = targetAssembly;
}
public override Type BindToType(string assemblyName, string typeName)
{
Type returntype = null;
assemblyName = targetAssembly.FullName;
Assembly.Load(assemblyName);
returntype = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName), false, true);
// In VB.NET, the typeName may contain the default namespace also. So our if our remote application
// is a VB.NET application, we need to remove that:
if (returntype == null && typeName.Contains("."))
{
// Remove the default namespace here:
String vbAssemName = Regex.Split(typeName, @"\.")[0] + ".";
typeName = typeName.Replace(vbAssemName, "");
// And attempt to get the returntype (our targetAssembly may be a C# application)
returntype = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName), false, true);
// If targetAssembly is a VB.NET application, we need to get the current default namespace:
if (returntype == null)
{
try
{
// All the types in our target assembly should be the same. We only need one:
Type[] types = targetAssembly.GetTypes();
if (types.Length > 0)
{
// And include it in our typename:
returntype = Type.GetType(String.Format("{0}, {1}", Regex.Split(types[0].FullName, @"\.")[0] + "." + typeName, assemblyName), false, true);
}
}
catch (Exception) { }
}
}
return returntype;
}
}
Код, на который вы хотите посмотреть, чтобы увидеть пример сериализации и десериализации объектов в этом проекте, можно найти в файле Core.cs между строками 399 и 465.
- Пит