You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# TCP服务端-客户端开发:反序列化时出现程序集未找到异常

解决C# TCP Socket中BinaryFormatter反序列化SerializationException问题

看起来你碰到了BinaryFormatter跨Socket序列化/反序列化的经典坑啊!那个提示程序集信息不匹配的System.Runtime.Serialization.SerializationException,我之前做TCP通信时也踩过,给你梳理几个最可能的原因和对应的解决思路:

1. 两端对象的程序集/类定义不匹配

BinaryFormatter序列化时会把对象所属的程序集完整信息(版本、公钥令牌、命名空间等)都打包进去,反序列化时要求两端的程序集完全一致才可以。比如服务端的对象在Multi Server, Version=1.0.0.0这个程序集里,但客户端的同名对象可能来自不同程序集、版本有差异,甚至类的字段/属性、序列化特性有细微差别,都会触发这个异常。

解决办法:

  • 把需要序列化的对象抽成独立的类库项目,服务端和客户端都引用这个类库的同一个版本,从根源上保证两端的类定义、程序集信息完全同步。
  • 如果没法用共享类库,就手动保证两端的类丝毫不差:包括命名空间、类名、字段/属性的名称和类型,甚至[Serializable]、[NonSerialized]这类序列化特性都要完全一致,连大小写都不能错。

2. Socket接收的字节数组不完整

TCP是流式协议,存在粘包/拆包问题,客户端可能只收到了部分序列化后的字节数据,这种情况下反序列化失败,异常信息有时候会误导性地指向程序集,但根源是数据不全。

解决办法:
发送序列化数据前先传递数据长度,客户端先接收长度,再根据长度接收完整的字节数组:

// 服务端发送逻辑
byte[] serializedData = GetSerializedObject(); // 你的序列化逻辑
// 先发送数据长度(4字节int)
byte[] lengthBytes = BitConverter.GetBytes(serializedData.Length);
socket.Send(lengthBytes);
// 再发送序列化数据
socket.Send(serializedData);
// 客户端接收逻辑
// 先接收长度
byte[] lengthBytes = new byte[4];
socket.Receive(lengthBytes);
int dataLength = BitConverter.ToInt32(lengthBytes, 0);
// 循环接收完整数据
byte[] serializedData = new byte[dataLength];
int totalReceived = 0;
while (totalReceived < dataLength)
{
    int received = socket.Receive(serializedData, totalReceived, dataLength - totalReceived, SocketFlags.None);
    totalReceived += received;
}
// 此时再反序列化
using (MemoryStream ms = new MemoryStream(serializedData))
{
    BinaryFormatter formatter = new BinaryFormatter();
    try
    {
        var targetObj = formatter.Deserialize(ms);
        // 处理对象
    }
    catch (SerializationException ex)
    {
        // 此时再排查其他问题
    }
}

3. .NET环境的BinaryFormatter配置问题

从.NET Core 3.0开始,BinaryFormatter默认被禁用了,因为存在安全漏洞;另外如果类的序列化特性配置有误(比如没加[Serializable]),也会导致反序列化失败。

解决办法:

  • 确保要序列化的类加上[Serializable]特性,所有需要序列化的成员都符合要求(如果用自定义序列化,两端的ISerializable实现要完全一致)。
  • 如果是.NET Core/.NET 5+环境,需要在项目文件中手动启用BinaryFormatter:
<PropertyGroup>
    <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
</PropertyGroup>

4. 程序集强名称签名不匹配

如果服务端的程序集是强名称签名的(有PublicToken),而客户端的程序集没有签名,或者用了不同的密钥对签名,反序列化时会因为程序集标识不匹配报错。

解决办法:
两端的共享类库要么都不使用强名称签名,要么用同一个强名称密钥对进行签名,确保公钥令牌完全一致。

额外建议:考虑替换BinaryFormatter

BinaryFormatter已经被官方标记为过时(Obsolete),存在严重的安全风险(比如恶意构造的序列化数据可能触发代码执行)。如果可以的话,建议换成更安全、兼容性更好的序列化方案:

  • JSON序列化:System.Text.Json或Newtonsoft.Json,跨平台跨程序集兼容性强,调试也方便。
  • 二进制序列化:Protobuf-net,性能接近BinaryFormatter,安全且跨语言兼容性好。

内容的提问来源于stack exchange,提问作者Emirhan Özsoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:38:38