110,535
社区成员
发帖
与我相关
我的任务
分享
class Client
{
TcpClient m_tcp;
public Client(TcpClient t)
{
m_tcp = t;
}
public void communicate()
{
NetworkStream ns = m_tcp.GetStream();
IFormatter formatter = new BinaryFormatter();
while (true)
{
MyClass myClass;
try
{
if ((myClass = (MyClass)formatter.Deserialize(ns)) == null)
{
Console.WriteLine("disconnected");
break;
}
}
catch (Exception exc)
{
Console.WriteLine("missing " + exc.ToString());
break;
}
Console.WriteLine(myClass.name);
myClass.name = myClass.name.ToUpper();
myClass.gender = myClass.gender.ToUpper();
try
{
formatter.Serialize(ns, myClass);
}
catch
{
Console.WriteLine("missing");
break;
}
}
ns.Close();
}
}
[Serializable]
class MyClass
{
public string name;
public string gender;
}
class Program
{
static void Main(string[] args)
{
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Parse("127.0.0.1"), 13000);
NetworkStream ns = tcpClient.GetStream();
IFormatter formatter = new BinaryFormatter();
while (true)
{
MyClass myClass = new MyClass();
myClass.name = "zhaohad";
myClass.gender = "male";
try
{
formatter.Serialize(ns, myClass);
}
catch (Exception exc)
{
Console.WriteLine("missing " + exc.ToString());
break;
}
try
{
myClass = (MyClass)formatter.Deserialize(ns);
}
catch (Exception exc)
{
Console.WriteLine("missing " + exc.ToString());
break;
}
}
ns.Close();
}
}
/// <summary>
/// 反序列化TcpMessage对象
/// </summary>
/// <param name="Msg"></param>
/// <returns></returns>
// 采用二进制序列化取代了XML序列化,二进制体积小,速度快,但是有一定的限定条件
public static TcpMsg GetMessage_(byte[] Msg)
{
try
{
using (MemoryStream memStream = new MemoryStream(Msg))
{
BinaryFormatter brFormatter = new BinaryFormatter();
// 就是下面的接口。。。
brFormatter.Binder = new ConvertAssemblyBinder();
TcpMsg tm = (TcpMsg)brFormatter.Deserialize(memStream);
//XmlSerializer xs = new XmlSerializer(typeof(TcpMsg));
//TcpMsg tm = xs.Deserialize(memStream) as TcpMsg;
return tm;
}
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// 控制将序列化对象绑定到类型的过程(通过此接口自己修改序列化后的程序集和命名空间即可)
/// </summary>
public sealed class ConvertAssemblyBinder : SerializationBinder
{
/// <summary>
/// 控制二进制序列化类型转换
/// </summary>
/// <param name="assemblyName"></param>
/// <param name="typeName"></param>
/// <returns></returns>
// 在序列化过程中,格式化程序传输创建正确类型和版本的对象的实例所需的信息。
// 此信息通常包括对象的完整类型名称和程序集名称。
// 程序集名称包含程序集的名称、版本和强名称(请参见具有强名称的程序集)散列。
// 默认情况下,反序列化将使用此信息创建等同对象的实例(安全策略所限制的任何程序集加载属于例外)。
// 因为类已经在程序集之间移动或者因为在服务器和客户端上要求类的不同版本,有些用户需要控制要加载哪些类。
// 这是一个抽象基类。所有联编程序都扩展此类。
// 给继承者的说明 从 SerializationBinder 继承时,必须重写以下成员:BindToType。
// 由于服务器和客户端共同使用同一个类型,进行数据传递,但是服务器和客户端的同一类型处于不同的
// 程序集,需要在反序列化的时候,提供强制类型转换
public override Type BindToType(string assemblyName, string typeName)
{
// 取得当前的程序集名称,取得传递过来,类型名称不修改,都是"TestPro.CSFTcpMsg"
string strCurAssembly = Assembly.GetExecutingAssembly().FullName;
// 返回当前对应的类型
Type CurType = Type.GetType(String.Format("{0}, {1}", typeName, strCurAssembly));
return CurType;
}
}