【问题标题】:Send XML file over socket C++通过套接字 C++ 发送 XML 文件
【发布时间】:2025-12-29 19:45:11
【问题描述】:

我正在尝试通过

发送.ui 文件的内容
std::ifstream f;
f.open(filePath, std::ios::binary | std::ios::ate);
int fileSize = f.tellg();
char *bytes = new char[fileSize];

f.read((char *) bytes, fileSize);

send(clientSocket, std::to_string(fileSize).c_str(), 16, 0);
send(clientSocket, bytes, fileSize, 0);
f.close();
delete [] bytes;

尽管已打开且文件大小计算正确,但在调试时,我看到了

f.read((char *) bytes, fileSize); f: std::ifstream fileSize:2328 bytes: 0x6824b0 "\r\360\255\272 ...

顺序

\r\360\255\272

进一步重复并最终以

结束

\r\360\255\272\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\356\376\356\ 376\356\376",

如何通过WinSock2_32正确传递和接收任何xml内容?

【问题讨论】:

  • 假设您在打开文件并获取大小时绝对没有出错,那么您进一步假设文件大小作为字符串的长度正好是 16 个字符长的合理性是什么?尤其是当您清楚地显示一个仅占 4 个字符的值时?只是好奇。无论如何,你的阅读是盲目的失败,因为你已经在文件的末尾。这就是std::ios::ate 所做的(实际上你依靠它来获得大小)。你永远不会倒回文件,因此你的读取实际上什么也没读,你永远不会检查任何错误,然后继续前进。
  • 在远端接收到数据之前,您无法关闭串行流。建议您在关闭之前从另一端发送响应以验证数据是否已收到。

标签: c++ xml winsock2


【解决方案1】:

在读取字节之前,您没有将文件流返回到位置 0,因此f.read() 将失败。事先添加对f.seekg(0)的呼叫。

此外,您应该以二进制格式发送fileSize,而不是作为字符串,尤其是因为字符串的长度不是 16 个字节。

试试这个:

std::ifstream f(filePath, std::ios::binary | std::ios::ate);
if (!f.is_open()) ...

int fileSize = f.tellg();
if (fileSize < 0) ...

char *bytes = new char[fileSize];
f.seekg(0);
f.read(bytes, fileSize);

int32_t tmp = htonl(fileSize);
send(clientSocket, &tmp, sizeof(tmp), 0);
send(clientSocket, bytes, fileSize, 0);

delete [] bytes;
f.close();

如果您绝对需要将 fileSize 作为 16 个字符的字符串发送,请为此使用格式化的 char[] 缓冲区,例如:

std::ifstream f(filePath, std::ios::binary | std::ios::ate);
if (!f.is_open()) ...

int fileSize = f.tellg();
if (fileSize < 0) ...

char *bytes = new char[fileSize];
f.seekg(0);
f.read(bytes, fileSize);

char s_fileSize[17] = {};
sprintf(s_fileSize, "%0.16d", fileSize);

send(clientSocket, s_fileSize, 16, 0);
send(clientSocket, bytes, fileSize, 0);

delete [] bytes;
f.close();

【讨论】: