TCP P2P传输DLL后调用Assembly.LoadFile触发BadImageFormatException问题
嘿,我之前做文件传输工具的时候也踩过类似的坑,结合你的描述,咱们一步步拆解可能的问题:
先确认流处理是否用了二进制模式
这是最常见的坑:很多人传输二进制文件(比如DLL、EXE)时,不小心用了文本模式的流(比如StreamReader/StreamWriter),这类流会基于编码对字节做转义处理(比如把某些控制字符替换掉),哪怕最后文件大小和原文件一致,实际字节内容已经被篡改了。
你要确保传输和写入全流程都用纯二进制流操作:直接用NetworkStream的Read/Write方法,写入文件时用FileStream(别用StreamWriter),全程不要经过任何文本编码转换。校验文件哈希值,确认内容完全一致
文件大小相同不代表字节完全一致,比如某个字节被替换成了另一个值,但总长度没变。你可以用MD5或SHA256分别计算本地原DLL和传输后DLL的哈希值,对比是否完全相同:using System.Security.Cryptography; using System.IO; static byte[] GetFileHash(string path) { using var sha256 = SHA256.Create(); using var fs = File.OpenRead(path); return sha256.ComputeHash(fs); } // 对比哈希 bool isSame = GetFileHash("original.dll").SequenceEqual(GetFileHash("transferred.dll"));如果哈希不一样,说明传输过程中确实存在数据篡改,得回头查传输逻辑。
排查架构匹配问题
BadImageFormatException另一个常见原因是进程架构和DLL不匹配:比如你原DLL是x64编译的,但加载它的进程是x86的;或者反过来。不过你说本地生成的能正常加载,这个可能性相对小,但也可以快速排查:右键传输后的DLL→属性→详细信息,查看“处理器架构”,再对比你加载它的进程的架构(比如在任务管理器里看进程的“平台”列)。确认文件写入是否完整
有时候传输完成后,文件流没正确刷新或关闭,导致最后一部分字节没写入磁盘。一定要用using块包裹流,确保自动完成刷新和释放:// 接收端写入文件的正确示例 using (var networkStream = client.GetStream()) using (var fileStream = new FileStream("received.dll", FileMode.Create, FileAccess.Write)) { byte[] buffer = new byte[4096]; int bytesRead; // 循环读取直到流结束 while ((bytesRead = networkStream.Read(buffer, 0, buffer.Length)) > 0) { fileStream.Write(buffer, 0, bytesRead); } }这里
using块会自动调用Flush和Close,避免数据残留到内存里没写入磁盘。检查分块传输的逻辑(如果有)
如果你的P2P应用是分块传输文件的,要确保分块的拼接顺序完全正确,没有出现块错位、重复或遗漏。虽然TCP是可靠的字节流,但如果应用层的分块标记或拼接逻辑出错,也会导致文件内容混乱。比如要按分块的序号依次写入,而不是按接收顺序拼接(虽然TCP不会乱序,但如果你的分块处理有逻辑漏洞,还是可能出问题)。
先从哈希校验和流处理这两点入手,大概率能找到问题所在。
内容的提问来源于stack exchange,提问作者naknik

