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

C++服务端与C#客户端Socket传图接收端字节不一致问题

Socket跨语言传输图片字节丢失(大量问号)问题修复方案
  • 核心错误位于C#客户端的编码转换逻辑:二进制图片不属于文本格式,你将Socket接收的原始二进制数据先按Unicode规则解码为字符串、再重新编码为字节的操作,会把所有不符合Unicode编码规范的字节替换为U+FFFD替换字符,表现出来就是大量问号,直接破坏原始图片数据。
  • 次要错误1:代码变量名不匹配,最终写文件时使用的byts变量与前文存储转换结果的bits变量不一致,也会导致输出文件内容错误。
  • 次要错误2:未处理TCP流的粘包/半包问题,C++的send接口不保证一次性传输完所有字节,C#接收逻辑如果未按约定长度收全数据,会导致文件截断。

C++服务端优化(兼容长度校验逻辑)

原有读二进制文件的逻辑正确,仅需补充长度预发送和循环发送逻辑即可:

std::ifstream fin("1.bmp", std::ios::binary);
std::string data;
data.reserve(1000000);
std::copy(std::istreambuf_iterator<char>(fin),
    std::istreambuf_iterator<char>(),
    std::back_inserter(data));
fin.close();

// 先发送4字节无符号整数标识文件总长度
uint32_t fileSize = data.size();
send(clientSocket, (char*)&fileSize, sizeof(fileSize), 0);
// 循环发送确保所有字节传输完成
size_t sentBytes = 0;
while (sentBytes < fileSize) {
    int curSent = send(clientSocket, data.c_str() + sentBytes, fileSize - sentBytes, 0);
    if (curSent <= 0) break;
    sentBytes += curSent;
}

C#客户端修复(核心修改点)

删除所有文本编码转换逻辑,直接接收原始二进制字节写入文件:

s = new SocketHandler(ip, Int32.Parse(port));
// 先接收4字节文件长度
byte[] lengthBuffer = new byte[4];
s.Receive(lengthBuffer, 0, 4, SocketFlags.None);
int totalLength = BitConverter.ToInt32(lengthBuffer, 0);
// 按总长度接收完整二进制数据
byte[] fileBuffer = new byte[totalLength];
int receivedBytes = 0;
while (receivedBytes < totalLength) {
    int curReceived = s.Receive(fileBuffer, receivedBytes, totalLength - receivedBytes, SocketFlags.None);
    if (curReceived <= 0) break;
    receivedBytes += curReceived;
}
// 直接写入原始字节到文件,无需任何转码
File.WriteAllBytes("newff.bmp", fileBuffer);

内容的提问来源于stack exchange,提问作者Maxim Kirusin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:06:07