C++ 如何在 Winsock 中正确接收文件?

标签 c++ windows networking winsock winsock2

我正在使用 C++ 开发一个 CHAT 程序。并陷入发送/接收文件的问题。我的服务器端是 Python,它在 Flask App 的后台运行,接受 TCP 连接并将传入/传出数据转发到聊天客户端。它没有问题并且效果很好。我的问题是客户端接收。我添加了发送和接收文件的功能。虽然发送正常,没有错误(经过测试并且有效)。在客户端接收让我很头疼。

我正在使用以下方法接收文件,无论它是二进制文件还是文本文件。

// filebuf is defined as
// char filebuf[BUFFER];
// BUFFER is 1024.
void CHAT::recvFile()
{
 int fsize;
 std::ofstream recvfile(filename, std::ios::app, std::ios::binary);
 while ((fsize = recv(sockfd, filebuf, sizeof(filebuf), 0)) > 0)
 {
     recvfile.write(filebuf, sizeof(filebuf));
 }
 recvfile.close();
 respond("Received file.\n");
}

这有效,但数据没有完全写入文件。例如;如果我发送一个 144 kb 的文件,它将在另一端保存为 142 kb。程序就停在那里。

最后一个问题;我如何在 C++ 中接收大/小文件?

编辑:在@Algirdas Preidžius 回复后,我重新测试了它。以下是文件发送前后的一些屏幕截图。

这是在发送之前。

https://www.upload.ee/image/10164543/ook.PNG

这是发送后的样子。 https://www.upload.ee/image/10164544/wsa.PNG

最佳答案

有 3 种方法可以处理这种情况。

  • 消息定界符/行终止符
  • 在消息前插入消息的大小
  • 将非阻塞 IO 与 select 结合使用

这是一个简单的示例,用于解析传入消息以查找行终止符。 例如:

int fsize;
std::string filebuf( '0', 1024 );

while ( ( fsize = recv( sockfd, filebuf.data( ), filebuf.size( ), 0 ) ) > 0 )
{
     if( std::size_t index{ filebuf.find( "#end", 0 ) }; 
          index != std::string::npos )
     {
         // The line terminator was found so don't call the
         // the receive function again as there should be nothing
         // remaining in the stream to read.
     }
     /*Write the data to your file.*/
     filebuf.clear( );
}
respond("Received file.\n");

请注意,这是一个未经测试的快速示例,向您展示了如何解析传入消息。

关于C++ 如何在 Winsock 中正确接收文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56854717/

相关文章:

sql-server - MSOLEDBSQL 或 MSOLEDBSQL19 连接到 Azure 数据库时出现超时错误 - 工作正常 "from my machine"

c++ - Flatbuffers 验证器行为

c++ - 如何比较相似的代码库?

c++ - 将构造函数参数变成模板参数

windows - Windows 上的 Makefile 干净

Apache:如何从网络外部的计算机访问我的网页?

c++ - 基于范围的多维数组自动循环作为函数参数

python - 调用设置环境变量的批处理文件的脚本

windows - 如何从bat脚本变量中找到的父文件夹中删除子文件夹和文件?

windows - 如何列出远程机器文件夹的内容